{"version":3,"file":"ui.min.js","sources":["../../../../../../UILib/ui-lib/lib/functions.js","../../../../../../UILib/ui-lib/lib/ui/icon.js","../../../../../../UILib/ui-lib/lib/ui/checkbox.js","../../../../../../UILib/ui-lib/lib/ui/tooltip.js","../../../../../../UILib/ui-lib/lib/ui/tab.js","../../../../../../UILib/ui-lib/lib/utility/request.js","../../../../../../UILib/ui-lib/lib/utility/strings.js","../../../../../../UILib/ui-lib/lib/utility/lgres.js","../../../../../../UILib/ui-lib/lib/utility.js","../../../../../../UILib/ui-lib/lib/ui/dropdown.js","../../../../../../UILib/ui-lib/lib/ui/popup.js","../../../../../../UILib/ui-lib/lib/ui/extension.js","../../../../../../UILib/ui-lib/lib/ui/date.js","../../../../../../UILib/ui-lib/lib/ui/grid/column.js","../../../../../../UILib/ui-lib/lib/ui/grid/grid.js","../../../../../../UILib/ui-lib/lib/ui/media.js"],"sourcesContent":["export function createElement(tagName, init, ...children) {\r\n const element = document.createElement(tagName);\r\n if (typeof init === 'function') {\r\n init(element);\r\n } else if (init != null) {\r\n element.className = init;\r\n }\r\n if (children.length > 0) {\r\n element.append(...children);\r\n }\r\n return element;\r\n}\r\n","const svgns = 'http://www.w3.org/2000/svg';\r\nconst dict = {\r\n \"\\uf000\": \"glass-martini\",\r\n \"\\uf001\": \"music\",\r\n \"\\uf002\": \"search\",\r\n \"\\uf004\": \"heart\",\r\n \"\\uf005\": \"star\",\r\n \"\\uf007\": \"user\",\r\n \"\\uf008\": \"film\",\r\n \"\\uf009\": \"th-large\",\r\n \"\\uf00a\": \"th\",\r\n \"\\uf00b\": \"th-list\",\r\n \"\\uf00c\": \"check\",\r\n \"\\uf00d\": \"times\",\r\n \"\\uf00e\": \"search-plus\",\r\n \"\\uf010\": \"search-minus\",\r\n \"\\uf011\": \"power-off\",\r\n \"\\uf012\": \"signal\",\r\n \"\\uf013\": \"cog\",\r\n \"\\uf015\": \"home\",\r\n \"\\uf017\": \"clock\",\r\n \"\\uf018\": \"road\",\r\n \"\\uf019\": \"download\",\r\n \"\\uf01c\": \"inbox\",\r\n \"\\uf01e\": \"redo\",\r\n \"\\uf021\": \"sync\",\r\n \"\\uf022\": \"list-alt\",\r\n \"\\uf023\": \"lock\",\r\n \"\\uf024\": \"flag\",\r\n \"\\uf025\": \"headphones\",\r\n \"\\uf026\": \"volume-off\",\r\n \"\\uf027\": \"volume-down\",\r\n \"\\uf028\": \"volume-up\",\r\n \"\\uf029\": \"qrcode\",\r\n \"\\uf02a\": \"barcode\",\r\n \"\\uf02b\": \"tag\",\r\n \"\\uf02c\": \"tags\",\r\n \"\\uf02d\": \"book\",\r\n \"\\uf02e\": \"bookmark\",\r\n \"\\uf02f\": \"print\",\r\n \"\\uf030\": \"camera\",\r\n \"\\uf031\": \"font\",\r\n \"\\uf032\": \"bold\",\r\n \"\\uf033\": \"italic\",\r\n \"\\uf034\": \"text-height\",\r\n \"\\uf035\": \"text-width\",\r\n \"\\uf036\": \"align-left\",\r\n \"\\uf037\": \"align-center\",\r\n \"\\uf038\": \"align-right\",\r\n \"\\uf039\": \"align-justify\",\r\n \"\\uf03a\": \"list\",\r\n \"\\uf03b\": \"outdent\",\r\n \"\\uf03c\": \"indent\",\r\n \"\\uf03d\": \"video\",\r\n \"\\uf03e\": \"image\",\r\n \"\\uf040\": \"pencil\",\r\n \"\\uf041\": \"map-marker\",\r\n \"\\uf042\": \"adjust\",\r\n \"\\uf043\": \"tint\",\r\n \"\\uf044\": \"edit\",\r\n \"\\uf047\": \"arrows\",\r\n \"\\uf048\": \"step-backward\",\r\n \"\\uf049\": \"fast-backward\",\r\n \"\\uf04a\": \"backward\",\r\n \"\\uf04b\": \"play\",\r\n \"\\uf04c\": \"pause\",\r\n \"\\uf04d\": \"stop\",\r\n \"\\uf04e\": \"forward\",\r\n \"\\uf050\": \"fast-forward\",\r\n \"\\uf051\": \"step-forward\",\r\n \"\\uf052\": \"eject\",\r\n \"\\uf053\": \"chevron-left\",\r\n \"\\uf054\": \"chevron-right\",\r\n \"\\uf055\": \"plus-circle\",\r\n \"\\uf056\": \"minus-circle\",\r\n \"\\uf057\": \"times-circle\",\r\n \"\\uf058\": \"check-circle\",\r\n \"\\uf059\": \"question-circle\",\r\n \"\\uf05a\": \"info-circle\",\r\n \"\\uf05b\": \"crosshairs\",\r\n \"\\uf05e\": \"ban\",\r\n \"\\uf060\": \"arrow-left\",\r\n \"\\uf061\": \"arrow-right\",\r\n \"\\uf062\": \"arrow-up\",\r\n \"\\uf063\": \"arrow-down\",\r\n \"\\uf064\": \"share\",\r\n \"\\uf065\": \"expand\",\r\n \"\\uf066\": \"compress\",\r\n \"\\uf067\": \"plus\",\r\n \"\\uf068\": \"minus\",\r\n \"\\uf069\": \"asterisk\",\r\n \"\\uf06a\": \"exclamation-circle\",\r\n \"\\uf06b\": \"gift\",\r\n \"\\uf06c\": \"leaf\",\r\n \"\\uf06d\": \"fire\",\r\n \"\\uf06e\": \"eye\",\r\n \"\\uf070\": \"eye-slash\",\r\n \"\\uf071\": \"exclamation-triangle\",\r\n \"\\uf072\": \"plane\",\r\n \"\\uf073\": \"calendar-alt\",\r\n \"\\uf074\": \"random\",\r\n \"\\uf075\": \"comment\",\r\n \"\\uf076\": \"magnet\",\r\n \"\\uf077\": \"chevron-up\",\r\n \"\\uf078\": \"chevron-down\",\r\n \"\\uf079\": \"retweet\",\r\n \"\\uf07a\": \"shopping-cart\",\r\n \"\\uf07b\": \"folder\",\r\n \"\\uf07c\": \"folder-open\",\r\n \"\\uf07d\": \"arrows-v\",\r\n \"\\uf07e\": \"arrows-h\",\r\n \"\\uf080\": \"chart-bar\",\r\n \"\\uf083\": \"camera-retro\",\r\n \"\\uf084\": \"key\",\r\n \"\\uf085\": \"cogs\",\r\n \"\\uf086\": \"comments\",\r\n \"\\uf089\": \"star-half\",\r\n \"\\uf08b\": \"sign-out\",\r\n \"\\uf08d\": \"thumbtack\",\r\n \"\\uf08e\": \"external-link\",\r\n \"\\uf090\": \"sign-in\",\r\n \"\\uf091\": \"trophy\",\r\n \"\\uf093\": \"upload\",\r\n \"\\uf094\": \"lemon\",\r\n \"\\uf095\": \"phone\",\r\n \"\\uf098\": \"phone-square\",\r\n \"\\uf09c\": \"unlock\",\r\n \"\\uf09d\": \"credit-card\",\r\n \"\\uf09e\": \"rss\",\r\n \"\\uf0a0\": \"hdd\",\r\n \"\\uf0a1\": \"bullhorn\",\r\n \"\\uf0a3\": \"certificate\",\r\n \"\\uf0a4\": \"hand-point-right\",\r\n \"\\uf0a5\": \"hand-point-left\",\r\n \"\\uf0a6\": \"hand-point-up\",\r\n \"\\uf0a7\": \"hand-point-down\",\r\n \"\\uf0a8\": \"arrow-circle-left\",\r\n \"\\uf0a9\": \"arrow-circle-right\",\r\n \"\\uf0aa\": \"arrow-circle-up\",\r\n \"\\uf0ab\": \"arrow-circle-down\",\r\n \"\\uf0ac\": \"globe\",\r\n \"\\uf0ad\": \"wrench\",\r\n \"\\uf0ae\": \"tasks\",\r\n \"\\uf0b0\": \"filter\",\r\n \"\\uf0b1\": \"briefcase\",\r\n \"\\uf0b2\": \"arrows-alt\",\r\n \"\\uf0c0\": \"users\",\r\n \"\\uf0c1\": \"link\",\r\n \"\\uf0c2\": \"cloud\",\r\n \"\\uf0c3\": \"flask\",\r\n \"\\uf0c4\": \"cut\",\r\n \"\\uf0c5\": \"copy\",\r\n \"\\uf0c6\": \"paperclip\",\r\n \"\\uf0c7\": \"save\",\r\n \"\\uf0c8\": \"square\",\r\n \"\\uf0c9\": \"bars\",\r\n \"\\uf0ca\": \"list-ul\",\r\n \"\\uf0cb\": \"list-ol\",\r\n \"\\uf0cc\": \"strikethrough\",\r\n \"\\uf0cd\": \"underline\",\r\n \"\\uf0ce\": \"table\",\r\n \"\\uf0d0\": \"magic\",\r\n \"\\uf0d1\": \"truck\",\r\n \"\\uf0d6\": \"money-bill\",\r\n \"\\uf0d7\": \"caret-down\",\r\n \"\\uf0d8\": \"caret-up\",\r\n \"\\uf0d9\": \"caret-left\",\r\n \"\\uf0da\": \"caret-right\",\r\n \"\\uf0db\": \"columns\",\r\n \"\\uf0dc\": \"sort\",\r\n \"\\uf0dd\": \"sort-down\",\r\n \"\\uf0de\": \"sort-up\",\r\n \"\\uf0e0\": \"envelope\",\r\n \"\\uf0e2\": \"undo\",\r\n \"\\uf0e3\": \"gavel\",\r\n \"\\uf0e4\": \"tachometer\",\r\n \"\\uf0e7\": \"bolt\",\r\n \"\\uf0e8\": \"sitemap\",\r\n \"\\uf0e9\": \"umbrella\",\r\n \"\\uf0ea\": \"paste\",\r\n \"\\uf0eb\": \"lightbulb\",\r\n \"\\uf0ec\": \"exchange\",\r\n \"\\uf0ed\": \"cloud-download\",\r\n \"\\uf0ee\": \"cloud-upload\",\r\n \"\\uf0f0\": \"user-md\",\r\n \"\\uf0f1\": \"stethoscope\",\r\n \"\\uf0f2\": \"suitcase\",\r\n \"\\uf0f3\": \"bell\",\r\n \"\\uf0f4\": \"coffee\",\r\n \"\\uf0f8\": \"hospital\",\r\n \"\\uf0f9\": \"ambulance\",\r\n \"\\uf0fa\": \"medkit\",\r\n \"\\uf0fb\": \"fighter-jet\",\r\n \"\\uf0fc\": \"beer\",\r\n \"\\uf0fd\": \"h-square\",\r\n \"\\uf0fe\": \"plus-square\",\r\n \"\\uf100\": \"angle-double-left\",\r\n \"\\uf101\": \"angle-double-right\",\r\n \"\\uf102\": \"angle-double-up\",\r\n \"\\uf103\": \"angle-double-down\",\r\n \"\\uf104\": \"angle-left\",\r\n \"\\uf105\": \"angle-right\",\r\n \"\\uf106\": \"angle-up\",\r\n \"\\uf107\": \"angle-down\",\r\n \"\\uf108\": \"desktop\",\r\n \"\\uf109\": \"laptop\",\r\n \"\\uf10a\": \"tablet\",\r\n \"\\uf10b\": \"mobile\",\r\n \"\\uf10d\": \"quote-left\",\r\n \"\\uf10e\": \"quote-right\",\r\n \"\\uf110\": \"spinner\",\r\n \"\\uf111\": \"circle\",\r\n \"\\uf118\": \"smile\",\r\n \"\\uf119\": \"frown\",\r\n \"\\uf11a\": \"meh\",\r\n \"\\uf11b\": \"gamepad\",\r\n \"\\uf11c\": \"keyboard\",\r\n \"\\uf11e\": \"flag-checkered\",\r\n \"\\uf120\": \"terminal\",\r\n \"\\uf121\": \"code\",\r\n \"\\uf122\": \"reply-all\",\r\n \"\\uf124\": \"location-arrow\",\r\n \"\\uf125\": \"crop\",\r\n \"\\uf126\": \"code-branch\",\r\n \"\\uf127\": \"unlink\",\r\n \"\\uf128\": \"question\",\r\n \"\\uf129\": \"info\",\r\n \"\\uf12a\": \"exclamation\",\r\n \"\\uf12b\": \"superscript\",\r\n \"\\uf12c\": \"subscript\",\r\n \"\\uf12d\": \"eraser\",\r\n \"\\uf12e\": \"puzzle-piece\",\r\n \"\\uf130\": \"microphone\",\r\n \"\\uf131\": \"microphone-slash\",\r\n \"\\uf132\": \"shield\",\r\n \"\\uf133\": \"calendar\",\r\n \"\\uf134\": \"fire-extinguisher\",\r\n \"\\uf135\": \"rocket\",\r\n \"\\uf137\": \"chevron-circle-left\",\r\n \"\\uf138\": \"chevron-circle-right\",\r\n \"\\uf139\": \"chevron-circle-up\",\r\n \"\\uf13a\": \"chevron-circle-down\",\r\n \"\\uf13d\": \"anchor\",\r\n \"\\uf13e\": \"unlock-alt\",\r\n \"\\uf140\": \"bullseye\",\r\n \"\\uf141\": \"ellipsis-h\",\r\n \"\\uf142\": \"ellipsis-v\",\r\n \"\\uf143\": \"rss-square\",\r\n \"\\uf144\": \"play-circle\",\r\n \"\\uf145\": \"ticket\",\r\n \"\\uf146\": \"minus-square\",\r\n \"\\uf148\": \"level-up\",\r\n \"\\uf149\": \"level-down\",\r\n \"\\uf14a\": \"check-square\",\r\n \"\\uf14b\": \"pen-square\",\r\n \"\\uf14c\": \"external-link-square\",\r\n \"\\uf14d\": \"share-square\",\r\n \"\\uf14e\": \"compass\",\r\n \"\\uf150\": \"caret-square-down\",\r\n \"\\uf151\": \"caret-square-up\",\r\n \"\\uf152\": \"caret-square-right\",\r\n \"\\uf153\": \"euro-sign\",\r\n \"\\uf154\": \"pound-sign\",\r\n \"\\uf155\": \"dollar-sign\",\r\n \"\\uf156\": \"rupee-sign\",\r\n \"\\uf157\": \"yen-sign\",\r\n \"\\uf158\": \"ruble-sign\",\r\n \"\\uf159\": \"won-sign\",\r\n \"\\uf15b\": \"file\",\r\n \"\\uf15c\": \"file-alt\",\r\n \"\\uf15d\": \"sort-alpha-down\",\r\n \"\\uf15e\": \"sort-alpha-up\",\r\n \"\\uf160\": \"sort-amount-down\",\r\n \"\\uf161\": \"sort-amount-up\",\r\n \"\\uf162\": \"sort-numeric-down\",\r\n \"\\uf163\": \"sort-numeric-up\",\r\n \"\\uf164\": \"thumbs-up\",\r\n \"\\uf165\": \"thumbs-down\",\r\n \"\\uf175\": \"long-arrow-down\",\r\n \"\\uf176\": \"long-arrow-up\",\r\n \"\\uf177\": \"long-arrow-left\",\r\n \"\\uf178\": \"long-arrow-right\",\r\n \"\\uf182\": \"female\",\r\n \"\\uf183\": \"male\",\r\n \"\\uf185\": \"sun\",\r\n \"\\uf186\": \"moon\",\r\n \"\\uf187\": \"archive\",\r\n \"\\uf188\": \"bug\",\r\n \"\\uf191\": \"caret-square-left\",\r\n \"\\uf192\": \"dot-circle\",\r\n \"\\uf193\": \"wheelchair\",\r\n \"\\uf195\": \"lira-sign\",\r\n \"\\uf197\": \"space-shuttle\",\r\n \"\\uf199\": \"envelope-square\",\r\n \"\\uf19c\": \"university\",\r\n \"\\uf19d\": \"graduation-cap\",\r\n \"\\uf1ab\": \"language\",\r\n \"\\uf1ac\": \"fax\",\r\n \"\\uf1ad\": \"building\",\r\n \"\\uf1ae\": \"child\",\r\n \"\\uf1b0\": \"paw\",\r\n \"\\uf1b2\": \"cube\",\r\n \"\\uf1b3\": \"cubes\",\r\n \"\\uf1b8\": \"recycle\",\r\n \"\\uf1b9\": \"car\",\r\n \"\\uf1ba\": \"taxi\",\r\n \"\\uf1bb\": \"tree\",\r\n \"\\uf1c0\": \"database\",\r\n \"\\uf1c1\": \"file-pdf\",\r\n \"\\uf1c2\": \"file-word\",\r\n \"\\uf1c3\": \"file-excel\",\r\n \"\\uf1c4\": \"file-powerpoint\",\r\n \"\\uf1c5\": \"file-image\",\r\n \"\\uf1c6\": \"file-archive\",\r\n \"\\uf1c7\": \"file-audio\",\r\n \"\\uf1c8\": \"file-video\",\r\n \"\\uf1c9\": \"file-code\",\r\n \"\\uf1cd\": \"life-ring\",\r\n \"\\uf1ce\": \"circle-notch\",\r\n \"\\uf1d8\": \"paper-plane\",\r\n \"\\uf1da\": \"history\",\r\n \"\\uf1dc\": \"heading\",\r\n \"\\uf1dd\": \"paragraph\",\r\n \"\\uf1de\": \"sliders-h\",\r\n \"\\uf1e0\": \"share-alt\",\r\n \"\\uf1e1\": \"share-alt-square\",\r\n \"\\uf1e2\": \"bomb\",\r\n \"\\uf1e3\": \"futbol\",\r\n \"\\uf1e4\": \"tty\",\r\n \"\\uf1e5\": \"binoculars\",\r\n \"\\uf1e6\": \"plug\",\r\n \"\\uf1ea\": \"newspaper\",\r\n \"\\uf1eb\": \"wifi\",\r\n \"\\uf1ec\": \"calculator\",\r\n \"\\uf1f6\": \"bell-slash\",\r\n \"\\uf1f8\": \"trash\",\r\n \"\\uf1f9\": \"copyright\",\r\n \"\\uf1fa\": \"at\",\r\n \"\\uf1fb\": \"eye-dropper\",\r\n \"\\uf1fc\": \"paint-brush\",\r\n \"\\uf1fd\": \"birthday-cake\",\r\n \"\\uf1fe\": \"chart-area\",\r\n \"\\uf200\": \"chart-pie\",\r\n \"\\uf201\": \"chart-line\",\r\n \"\\uf204\": \"toggle-off\",\r\n \"\\uf205\": \"toggle-on\",\r\n \"\\uf206\": \"bicycle\",\r\n \"\\uf207\": \"bus\",\r\n \"\\uf20a\": \"closed-captioning\",\r\n \"\\uf20b\": \"shekel-sign\",\r\n \"\\uf217\": \"cart-plus\",\r\n \"\\uf218\": \"cart-arrow-down\",\r\n \"\\uf219\": \"diamond\",\r\n \"\\uf21a\": \"ship\",\r\n \"\\uf21b\": \"user-secret\",\r\n \"\\uf21c\": \"motorcycle\",\r\n \"\\uf21d\": \"street-view\",\r\n \"\\uf21e\": \"heartbeat\",\r\n \"\\uf221\": \"venus\",\r\n \"\\uf222\": \"mars\",\r\n \"\\uf223\": \"mercury\",\r\n \"\\uf224\": \"transgender\",\r\n \"\\uf225\": \"transgender-alt\",\r\n \"\\uf226\": \"venus-double\",\r\n \"\\uf227\": \"mars-double\",\r\n \"\\uf228\": \"venus-mars\",\r\n \"\\uf229\": \"mars-stroke\",\r\n \"\\uf22a\": \"mars-stroke-v\",\r\n \"\\uf22b\": \"mars-stroke-h\",\r\n \"\\uf22c\": \"neuter\",\r\n \"\\uf22d\": \"genderless\",\r\n \"\\uf233\": \"server\",\r\n \"\\uf234\": \"user-plus\",\r\n \"\\uf235\": \"user-times\",\r\n \"\\uf236\": \"bed\",\r\n \"\\uf238\": \"train\",\r\n \"\\uf239\": \"subway\",\r\n \"\\uf240\": \"battery-full\",\r\n \"\\uf241\": \"battery-three-quarters\",\r\n \"\\uf242\": \"battery-half\",\r\n \"\\uf243\": \"battery-quarter\",\r\n \"\\uf244\": \"battery-empty\",\r\n \"\\uf245\": \"mouse-pointer\",\r\n \"\\uf246\": \"i-cursor\",\r\n \"\\uf247\": \"object-group\",\r\n \"\\uf248\": \"object-ungroup\",\r\n \"\\uf249\": \"sticky-note\",\r\n \"\\uf24d\": \"clone\",\r\n \"\\uf24e\": \"balance-scale\",\r\n \"\\uf251\": \"hourglass-start\",\r\n \"\\uf252\": \"hourglass-half\",\r\n \"\\uf253\": \"hourglass-end\",\r\n \"\\uf254\": \"hourglass\",\r\n \"\\uf255\": \"hand-rock\",\r\n \"\\uf256\": \"hand-paper\",\r\n \"\\uf257\": \"hand-scissors\",\r\n \"\\uf258\": \"hand-lizard\",\r\n \"\\uf259\": \"hand-spock\",\r\n \"\\uf25a\": \"hand-pointer\",\r\n \"\\uf25b\": \"hand-peace\",\r\n \"\\uf25c\": \"trademark\",\r\n \"\\uf25d\": \"registered\",\r\n \"\\uf26c\": \"tv\",\r\n \"\\uf271\": \"calendar-plus\",\r\n \"\\uf272\": \"calendar-minus\",\r\n \"\\uf273\": \"calendar-times\",\r\n \"\\uf274\": \"calendar-check\",\r\n \"\\uf275\": \"industry\",\r\n \"\\uf276\": \"map-pin\",\r\n \"\\uf277\": \"map-signs\",\r\n \"\\uf279\": \"map\",\r\n \"\\uf27a\": \"comment-alt\",\r\n \"\\uf28b\": \"pause-circle\",\r\n \"\\uf28d\": \"stop-circle\",\r\n \"\\uf290\": \"shopping-bag\",\r\n \"\\uf291\": \"shopping-basket\",\r\n \"\\uf292\": \"hashtag\",\r\n \"\\uf295\": \"percent\",\r\n \"\\uf29a\": \"universal-access\",\r\n \"\\uf29d\": \"blind\",\r\n \"\\uf29e\": \"audio-description\",\r\n \"\\uf2a0\": \"phone-volume\",\r\n \"\\uf2a1\": \"braille\",\r\n \"\\uf2a2\": \"assistive-listening-systems\",\r\n \"\\uf2a3\": \"american-sign-language-interpreting\",\r\n \"\\uf2a4\": \"deaf\",\r\n \"\\uf2a7\": \"sign-language\",\r\n \"\\uf2a8\": \"low-vision\",\r\n \"\\uf2b5\": \"handshake\",\r\n \"\\uf2b6\": \"envelope-open\",\r\n \"\\uf2b9\": \"address-book\",\r\n \"\\uf2bb\": \"address-card\",\r\n \"\\uf2bd\": \"user-circle\",\r\n \"\\uf2c1\": \"id-badge\",\r\n \"\\uf2c2\": \"id-card\",\r\n \"\\uf2c7\": \"thermometer-full\",\r\n \"\\uf2c8\": \"thermometer-three-quarters\",\r\n \"\\uf2c9\": \"thermometer-half\",\r\n \"\\uf2ca\": \"thermometer-quarter\",\r\n \"\\uf2cb\": \"thermometer-empty\",\r\n \"\\uf2cc\": \"shower\",\r\n \"\\uf2cd\": \"bath\",\r\n \"\\uf2ce\": \"podcast\",\r\n \"\\uf2d0\": \"window-maximize\",\r\n \"\\uf2d1\": \"window-minimize\",\r\n \"\\uf2d2\": \"window-restore\",\r\n \"\\uf2d3\": \"times-square\",\r\n \"\\uf2db\": \"microchip\",\r\n \"\\uf2dc\": \"snowflake\",\r\n \"\\uf2e1\": \"watch\",\r\n \"\\uf2e2\": \"volume-slash\",\r\n \"\\uf2e3\": \"utensil-fork\",\r\n \"\\uf2e4\": \"utensil-knife\",\r\n \"\\uf2e5\": \"utensil-spoon\",\r\n \"\\uf2e6\": \"utensils-alt\",\r\n \"\\uf2e7\": \"utensils\",\r\n \"\\uf2e8\": \"usd-circle\",\r\n \"\\uf2e9\": \"usd-square\",\r\n \"\\uf2ea\": \"undo-alt\",\r\n \"\\uf2eb\": \"trophy-alt\",\r\n \"\\uf2ec\": \"triangle\",\r\n \"\\uf2ed\": \"trash-alt\",\r\n \"\\uf2ee\": \"times-hexagon\",\r\n \"\\uf2f0\": \"times-octagon\",\r\n \"\\uf2f1\": \"sync-alt\",\r\n \"\\uf2f2\": \"stopwatch\",\r\n \"\\uf2f3\": \"star-exclamation\",\r\n \"\\uf2f4\": \"spade\",\r\n \"\\uf2f5\": \"sign-out-alt\",\r\n \"\\uf2f6\": \"sign-in-alt\",\r\n \"\\uf2f7\": \"shield-check\",\r\n \"\\uf2f8\": \"scrubber\",\r\n \"\\uf2f9\": \"redo-alt\",\r\n \"\\uf2fa\": \"rectangle-landscape\",\r\n \"\\uf2fb\": \"rectangle-portrait\",\r\n \"\\uf2fc\": \"rectangle-wide\",\r\n \"\\uf2fd\": \"question-square\",\r\n \"\\uf2fe\": \"poo\",\r\n \"\\uf300\": \"plus-hexagon\",\r\n \"\\uf301\": \"plus-octagon\",\r\n \"\\uf302\": \"images\",\r\n \"\\uf303\": \"pencil-alt\",\r\n \"\\uf304\": \"pen\",\r\n \"\\uf305\": \"pen-alt\",\r\n \"\\uf306\": \"octagon\",\r\n \"\\uf307\": \"minus-hexagon\",\r\n \"\\uf308\": \"minus-octagon\",\r\n \"\\uf309\": \"long-arrow-alt-down\",\r\n \"\\uf30a\": \"long-arrow-alt-left\",\r\n \"\\uf30b\": \"long-arrow-alt-right\",\r\n \"\\uf30c\": \"long-arrow-alt-up\",\r\n \"\\uf30d\": \"lock-alt\",\r\n \"\\uf30e\": \"jack-o-lantern\",\r\n \"\\uf30f\": \"info-square\",\r\n \"\\uf310\": \"inbox-in\",\r\n \"\\uf311\": \"inbox-out\",\r\n \"\\uf312\": \"hexagon\",\r\n \"\\uf313\": \"h1\",\r\n \"\\uf314\": \"h2\",\r\n \"\\uf315\": \"h3\",\r\n \"\\uf316\": \"file-check\",\r\n \"\\uf317\": \"file-times\",\r\n \"\\uf318\": \"file-minus\",\r\n \"\\uf319\": \"file-plus\",\r\n \"\\uf31a\": \"file-exclamation\",\r\n \"\\uf31c\": \"file-edit\",\r\n \"\\uf31d\": \"expand-arrows\",\r\n \"\\uf31e\": \"expand-arrows-alt\",\r\n \"\\uf320\": \"expand-wide\",\r\n \"\\uf321\": \"exclamation-square\",\r\n \"\\uf322\": \"chevron-double-down\",\r\n \"\\uf323\": \"chevron-double-left\",\r\n \"\\uf324\": \"chevron-double-right\",\r\n \"\\uf325\": \"chevron-double-up\",\r\n \"\\uf326\": \"compress-wide\",\r\n \"\\uf327\": \"club\",\r\n \"\\uf328\": \"clipboard\",\r\n \"\\uf329\": \"chevron-square-down\",\r\n \"\\uf32a\": \"chevron-square-left\",\r\n \"\\uf32b\": \"chevron-square-right\",\r\n \"\\uf32c\": \"chevron-square-up\",\r\n \"\\uf32d\": \"caret-circle-down\",\r\n \"\\uf32e\": \"caret-circle-left\",\r\n \"\\uf330\": \"caret-circle-right\",\r\n \"\\uf331\": \"caret-circle-up\",\r\n \"\\uf332\": \"camera-alt\",\r\n \"\\uf333\": \"calendar-edit\",\r\n \"\\uf334\": \"calendar-exclamation\",\r\n \"\\uf335\": \"badge\",\r\n \"\\uf336\": \"badge-check\",\r\n \"\\uf337\": \"arrows-alt-h\",\r\n \"\\uf338\": \"arrows-alt-v\",\r\n \"\\uf339\": \"arrow-square-down\",\r\n \"\\uf33a\": \"arrow-square-left\",\r\n \"\\uf33b\": \"arrow-square-right\",\r\n \"\\uf33c\": \"arrow-square-up\",\r\n \"\\uf33d\": \"arrow-to-bottom\",\r\n \"\\uf33e\": \"arrow-to-left\",\r\n \"\\uf340\": \"arrow-to-right\",\r\n \"\\uf341\": \"arrow-to-top\",\r\n \"\\uf342\": \"arrow-from-bottom\",\r\n \"\\uf343\": \"arrow-from-left\",\r\n \"\\uf344\": \"arrow-from-right\",\r\n \"\\uf345\": \"arrow-from-top\",\r\n \"\\uf346\": \"arrow-alt-from-bottom\",\r\n \"\\uf347\": \"arrow-alt-from-left\",\r\n \"\\uf348\": \"arrow-alt-from-right\",\r\n \"\\uf349\": \"arrow-alt-from-top\",\r\n \"\\uf34a\": \"arrow-alt-to-bottom\",\r\n \"\\uf34b\": \"arrow-alt-to-left\",\r\n \"\\uf34c\": \"arrow-alt-to-right\",\r\n \"\\uf34d\": \"arrow-alt-to-top\",\r\n \"\\uf34e\": \"alarm-clock\",\r\n \"\\uf350\": \"arrow-alt-square-down\",\r\n \"\\uf351\": \"arrow-alt-square-left\",\r\n \"\\uf352\": \"arrow-alt-square-right\",\r\n \"\\uf353\": \"arrow-alt-square-up\",\r\n \"\\uf354\": \"arrow-alt-down\",\r\n \"\\uf355\": \"arrow-alt-left\",\r\n \"\\uf356\": \"arrow-alt-right\",\r\n \"\\uf357\": \"arrow-alt-up\",\r\n \"\\uf358\": \"arrow-alt-circle-down\",\r\n \"\\uf359\": \"arrow-alt-circle-left\",\r\n \"\\uf35a\": \"arrow-alt-circle-right\",\r\n \"\\uf35b\": \"arrow-alt-circle-up\",\r\n \"\\uf35d\": \"external-link-alt\",\r\n \"\\uf360\": \"external-link-square-alt\",\r\n \"\\uf361\": \"retweet-alt\",\r\n \"\\uf362\": \"exchange-alt\",\r\n \"\\uf363\": \"repeat\",\r\n \"\\uf364\": \"repeat-alt\",\r\n \"\\uf365\": \"repeat-1\",\r\n \"\\uf366\": \"repeat-1-alt\",\r\n \"\\uf367\": \"share-all\",\r\n \"\\uf376\": \"battery-bolt\",\r\n \"\\uf377\": \"battery-slash\",\r\n \"\\uf37e\": \"browser\",\r\n \"\\uf381\": \"cloud-download-alt\",\r\n \"\\uf382\": \"cloud-upload-alt\",\r\n \"\\uf386\": \"code-commit\",\r\n \"\\uf387\": \"code-merge\",\r\n \"\\uf389\": \"credit-card-blank\",\r\n \"\\uf38a\": \"credit-card-front\",\r\n \"\\uf390\": \"desktop-alt\",\r\n \"\\uf39b\": \"ellipsis-h-alt\",\r\n \"\\uf39c\": \"ellipsis-v-alt\",\r\n \"\\uf3a0\": \"film-alt\",\r\n \"\\uf3a5\": \"gem\",\r\n \"\\uf3b3\": \"industry-alt\",\r\n \"\\uf3be\": \"level-down-alt\",\r\n \"\\uf3bf\": \"level-up-alt\",\r\n \"\\uf3c1\": \"lock-open\",\r\n \"\\uf3c2\": \"lock-open-alt\",\r\n \"\\uf3c5\": \"map-marker-alt\",\r\n \"\\uf3c9\": \"microphone-alt\",\r\n \"\\uf3cd\": \"mobile-alt\",\r\n \"\\uf3ce\": \"mobile-android\",\r\n \"\\uf3cf\": \"mobile-android-alt\",\r\n \"\\uf3d1\": \"money-bill-alt\",\r\n \"\\uf3dd\": \"phone-slash\",\r\n \"\\uf3de\": \"plane-alt\",\r\n \"\\uf3e0\": \"portrait\",\r\n \"\\uf3e5\": \"reply\",\r\n \"\\uf3ed\": \"shield-alt\",\r\n \"\\uf3f0\": \"sliders-h-square\",\r\n \"\\uf3f1\": \"sliders-v\",\r\n \"\\uf3f2\": \"sliders-v-square\",\r\n \"\\uf3f4\": \"spinner-third\",\r\n \"\\uf3fa\": \"tablet-alt\",\r\n \"\\uf3fb\": \"tablet-android\",\r\n \"\\uf3fc\": \"tablet-android-alt\",\r\n \"\\uf3fd\": \"tachometer-alt\",\r\n \"\\uf3ff\": \"ticket-alt\",\r\n \"\\uf400\": \"tree-alt\",\r\n \"\\uf401\": \"tv-retro\",\r\n \"\\uf406\": \"user-alt\",\r\n \"\\uf40e\": \"window\",\r\n \"\\uf40f\": \"window-alt\",\r\n \"\\uf410\": \"window-close\",\r\n \"\\uf422\": \"compress-alt\",\r\n \"\\uf424\": \"expand-alt\",\r\n \"\\uf432\": \"baseball\",\r\n \"\\uf433\": \"baseball-ball\",\r\n \"\\uf434\": \"basketball-ball\",\r\n \"\\uf435\": \"basketball-hoop\",\r\n \"\\uf436\": \"bowling-ball\",\r\n \"\\uf437\": \"bowling-pins\",\r\n \"\\uf438\": \"boxing-glove\",\r\n \"\\uf439\": \"chess\",\r\n \"\\uf43a\": \"chess-bishop\",\r\n \"\\uf43b\": \"chess-bishop-alt\",\r\n \"\\uf43c\": \"chess-board\",\r\n \"\\uf43d\": \"chess-clock\",\r\n \"\\uf43e\": \"chess-clock-alt\",\r\n \"\\uf43f\": \"chess-king\",\r\n \"\\uf440\": \"chess-king-alt\",\r\n \"\\uf441\": \"chess-knight\",\r\n \"\\uf442\": \"chess-knight-alt\",\r\n \"\\uf443\": \"chess-pawn\",\r\n \"\\uf444\": \"chess-pawn-alt\",\r\n \"\\uf445\": \"chess-queen\",\r\n \"\\uf446\": \"chess-queen-alt\",\r\n \"\\uf447\": \"chess-rook\",\r\n \"\\uf448\": \"chess-rook-alt\",\r\n \"\\uf449\": \"cricket\",\r\n \"\\uf44a\": \"curling\",\r\n \"\\uf44b\": \"dumbbell\",\r\n \"\\uf44c\": \"field-hockey\",\r\n \"\\uf44e\": \"football-ball\",\r\n \"\\uf44f\": \"football-helmet\",\r\n \"\\uf450\": \"golf-ball\",\r\n \"\\uf451\": \"golf-club\",\r\n \"\\uf453\": \"hockey-puck\",\r\n \"\\uf454\": \"hockey-sticks\",\r\n \"\\uf455\": \"luchador\",\r\n \"\\uf456\": \"pennant\",\r\n \"\\uf458\": \"quidditch\",\r\n \"\\uf45a\": \"racquet\",\r\n \"\\uf45b\": \"shuttlecock\",\r\n \"\\uf45c\": \"square-full\",\r\n \"\\uf45d\": \"table-tennis\",\r\n \"\\uf45e\": \"tennis-ball\",\r\n \"\\uf45f\": \"volleyball-ball\",\r\n \"\\uf460\": \"whistle\",\r\n \"\\uf461\": \"allergies\",\r\n \"\\uf462\": \"band-aid\",\r\n \"\\uf463\": \"barcode-alt\",\r\n \"\\uf464\": \"barcode-read\",\r\n \"\\uf465\": \"barcode-scan\",\r\n \"\\uf466\": \"box\",\r\n \"\\uf467\": \"box-check\",\r\n \"\\uf468\": \"boxes\",\r\n \"\\uf469\": \"briefcase-medical\",\r\n \"\\uf46a\": \"burn\",\r\n \"\\uf46b\": \"capsules\",\r\n \"\\uf46c\": \"clipboard-check\",\r\n \"\\uf46d\": \"clipboard-list\",\r\n \"\\uf46e\": \"conveyor-belt\",\r\n \"\\uf46f\": \"conveyor-belt-alt\",\r\n \"\\uf470\": \"diagnoses\",\r\n \"\\uf471\": \"dna\",\r\n \"\\uf472\": \"dolly\",\r\n \"\\uf473\": \"dolly-empty\",\r\n \"\\uf474\": \"dolly-flatbed\",\r\n \"\\uf475\": \"dolly-flatbed-alt\",\r\n \"\\uf476\": \"dolly-flatbed-empty\",\r\n \"\\uf477\": \"file-medical\",\r\n \"\\uf478\": \"file-medical-alt\",\r\n \"\\uf479\": \"first-aid\",\r\n \"\\uf47a\": \"forklift\",\r\n \"\\uf47b\": \"hand-holding-box\",\r\n \"\\uf47c\": \"hand-receiving\",\r\n \"\\uf47d\": \"hospital-alt\",\r\n \"\\uf47e\": \"hospital-symbol\",\r\n \"\\uf47f\": \"id-card-alt\",\r\n \"\\uf480\": \"inventory\",\r\n \"\\uf481\": \"notes-medical\",\r\n \"\\uf482\": \"pallet\",\r\n \"\\uf483\": \"pallet-alt\",\r\n \"\\uf484\": \"pills\",\r\n \"\\uf485\": \"prescription-bottle\",\r\n \"\\uf486\": \"prescription-bottle-alt\",\r\n \"\\uf487\": \"procedures\",\r\n \"\\uf488\": \"scanner\",\r\n \"\\uf489\": \"scanner-keyboard\",\r\n \"\\uf48a\": \"scanner-touchscreen\",\r\n \"\\uf48b\": \"shipping-fast\",\r\n \"\\uf48c\": \"shipping-timed\",\r\n \"\\uf48d\": \"smoking\",\r\n \"\\uf48e\": \"syringe\",\r\n \"\\uf48f\": \"tablet-rugged\",\r\n \"\\uf490\": \"tablets\",\r\n \"\\uf491\": \"thermometer\",\r\n \"\\uf492\": \"vial\",\r\n \"\\uf493\": \"vials\",\r\n \"\\uf494\": \"warehouse\",\r\n \"\\uf495\": \"warehouse-alt\",\r\n \"\\uf496\": \"weight\",\r\n \"\\uf497\": \"x-ray\",\r\n \"\\uf498\": \"blanket\",\r\n \"\\uf499\": \"book-heart\",\r\n \"\\uf49a\": \"box-alt\",\r\n \"\\uf49b\": \"box-fragile\",\r\n \"\\uf49c\": \"box-full\",\r\n \"\\uf49d\": \"box-heart\",\r\n \"\\uf49e\": \"box-open\",\r\n \"\\uf49f\": \"box-up\",\r\n \"\\uf4a0\": \"box-usd\",\r\n \"\\uf4a1\": \"boxes-alt\",\r\n \"\\uf4a2\": \"comment-alt-check\",\r\n \"\\uf4a3\": \"comment-alt-dots\",\r\n \"\\uf4a4\": \"comment-alt-edit\",\r\n \"\\uf4a5\": \"comment-alt-exclamation\",\r\n \"\\uf4a6\": \"comment-alt-lines\",\r\n \"\\uf4a7\": \"comment-alt-minus\",\r\n \"\\uf4a8\": \"comment-alt-plus\",\r\n \"\\uf4a9\": \"comment-alt-slash\",\r\n \"\\uf4aa\": \"comment-alt-smile\",\r\n \"\\uf4ab\": \"comment-alt-times\",\r\n \"\\uf4ac\": \"comment-check\",\r\n \"\\uf4ad\": \"comment-dots\",\r\n \"\\uf4ae\": \"comment-edit\",\r\n \"\\uf4af\": \"comment-exclamation\",\r\n \"\\uf4b0\": \"comment-lines\",\r\n \"\\uf4b1\": \"comment-minus\",\r\n \"\\uf4b2\": \"comment-plus\",\r\n \"\\uf4b3\": \"comment-slash\",\r\n \"\\uf4b4\": \"comment-smile\",\r\n \"\\uf4b5\": \"comment-times\",\r\n \"\\uf4b6\": \"comments-alt\",\r\n \"\\uf4b7\": \"container-storage\",\r\n \"\\uf4b8\": \"couch\",\r\n \"\\uf4b9\": \"donate\",\r\n \"\\uf4ba\": \"dove\",\r\n \"\\uf4bb\": \"fragile\",\r\n \"\\uf4bc\": \"hand-heart\",\r\n \"\\uf4bd\": \"hand-holding\",\r\n \"\\uf4be\": \"hand-holding-heart\",\r\n \"\\uf4bf\": \"hand-holding-seedling\",\r\n \"\\uf4c0\": \"hand-holding-usd\",\r\n \"\\uf4c1\": \"hand-holding-water\",\r\n \"\\uf4c2\": \"hands\",\r\n \"\\uf4c3\": \"hands-heart\",\r\n \"\\uf4c4\": \"hands-helping\",\r\n \"\\uf4c5\": \"hands-usd\",\r\n \"\\uf4c6\": \"handshake-alt\",\r\n \"\\uf4c7\": \"heart-circle\",\r\n \"\\uf4c8\": \"heart-square\",\r\n \"\\uf4c9\": \"home-heart\",\r\n \"\\uf4ca\": \"lamp\",\r\n \"\\uf4cb\": \"leaf-heart\",\r\n \"\\uf4cc\": \"loveseat\",\r\n \"\\uf4cd\": \"parachute-box\",\r\n \"\\uf4ce\": \"people-carry\",\r\n \"\\uf4cf\": \"person-carry\",\r\n \"\\uf4d0\": \"person-dolly\",\r\n \"\\uf4d1\": \"person-dolly-empty\",\r\n \"\\uf4d2\": \"phone-plus\",\r\n \"\\uf4d3\": \"piggy-bank\",\r\n \"\\uf4d4\": \"ramp-loading\",\r\n \"\\uf4d6\": \"ribbon\",\r\n \"\\uf4d7\": \"route\",\r\n \"\\uf4d8\": \"seedling\",\r\n \"\\uf4d9\": \"sign\",\r\n \"\\uf4da\": \"smile-wink\",\r\n \"\\uf4db\": \"tape\",\r\n \"\\uf4dc\": \"truck-container\",\r\n \"\\uf4dd\": \"truck-couch\",\r\n \"\\uf4de\": \"truck-loading\",\r\n \"\\uf4df\": \"truck-moving\",\r\n \"\\uf4e0\": \"truck-ramp\",\r\n \"\\uf4e1\": \"video-plus\",\r\n \"\\uf4e2\": \"video-slash\",\r\n \"\\uf4e3\": \"wine-glass\",\r\n \"\\uf4fa\": \"user-alt-slash\",\r\n \"\\uf4fb\": \"user-astronaut\",\r\n \"\\uf4fc\": \"user-check\",\r\n \"\\uf4fd\": \"user-clock\",\r\n \"\\uf4fe\": \"user-cog\",\r\n \"\\uf4ff\": \"user-edit\",\r\n \"\\uf500\": \"user-friends\",\r\n \"\\uf501\": \"user-graduate\",\r\n \"\\uf502\": \"user-lock\",\r\n \"\\uf503\": \"user-minus\",\r\n \"\\uf504\": \"user-ninja\",\r\n \"\\uf505\": \"user-shield\",\r\n \"\\uf506\": \"user-slash\",\r\n \"\\uf507\": \"user-tag\",\r\n \"\\uf508\": \"user-tie\",\r\n \"\\uf509\": \"users-cog\",\r\n \"\\uf515\": \"balance-scale-left\",\r\n \"\\uf516\": \"balance-scale-right\",\r\n \"\\uf517\": \"blender\",\r\n \"\\uf518\": \"book-open\",\r\n \"\\uf519\": \"broadcast-tower\",\r\n \"\\uf51a\": \"broom\",\r\n \"\\uf51b\": \"chalkboard\",\r\n \"\\uf51c\": \"chalkboard-teacher\",\r\n \"\\uf51d\": \"church\",\r\n \"\\uf51e\": \"coins\",\r\n \"\\uf51f\": \"compact-disc\",\r\n \"\\uf520\": \"crow\",\r\n \"\\uf521\": \"crown\",\r\n \"\\uf522\": \"dice\",\r\n \"\\uf523\": \"dice-five\",\r\n \"\\uf524\": \"dice-four\",\r\n \"\\uf525\": \"dice-one\",\r\n \"\\uf526\": \"dice-six\",\r\n \"\\uf527\": \"dice-three\",\r\n \"\\uf528\": \"dice-two\",\r\n \"\\uf529\": \"divide\",\r\n \"\\uf52a\": \"door-closed\",\r\n \"\\uf52b\": \"door-open\",\r\n \"\\uf52c\": \"equals\",\r\n \"\\uf52d\": \"feather\",\r\n \"\\uf52e\": \"frog\",\r\n \"\\uf52f\": \"gas-pump\",\r\n \"\\uf530\": \"glasses\",\r\n \"\\uf531\": \"greater-than\",\r\n \"\\uf532\": \"greater-than-equal\",\r\n \"\\uf533\": \"helicopter\",\r\n \"\\uf534\": \"infinity\",\r\n \"\\uf535\": \"kiwi-bird\",\r\n \"\\uf536\": \"less-than\",\r\n \"\\uf537\": \"less-than-equal\",\r\n \"\\uf538\": \"memory\",\r\n \"\\uf539\": \"microphone-alt-slash\",\r\n \"\\uf53a\": \"money-bill-wave\",\r\n \"\\uf53b\": \"money-bill-wave-alt\",\r\n \"\\uf53c\": \"money-check\",\r\n \"\\uf53d\": \"money-check-alt\",\r\n \"\\uf53e\": \"not-equal\",\r\n \"\\uf53f\": \"palette\",\r\n \"\\uf540\": \"parking\",\r\n \"\\uf541\": \"percentage\",\r\n \"\\uf542\": \"project-diagram\",\r\n \"\\uf543\": \"receipt\",\r\n \"\\uf544\": \"robot\",\r\n \"\\uf545\": \"ruler\",\r\n \"\\uf546\": \"ruler-combined\",\r\n \"\\uf547\": \"ruler-horizontal\",\r\n \"\\uf548\": \"ruler-vertical\",\r\n \"\\uf549\": \"school\",\r\n \"\\uf54a\": \"screwdriver\",\r\n \"\\uf54b\": \"shoe-prints\",\r\n \"\\uf54c\": \"skull\",\r\n \"\\uf54d\": \"smoking-ban\",\r\n \"\\uf54e\": \"store\",\r\n \"\\uf54f\": \"store-alt\",\r\n \"\\uf550\": \"stream\",\r\n \"\\uf551\": \"stroopwafel\",\r\n \"\\uf552\": \"toolbox\",\r\n \"\\uf553\": \"tshirt\",\r\n \"\\uf554\": \"walking\",\r\n \"\\uf555\": \"wallet\",\r\n \"\\uf556\": \"angry\",\r\n \"\\uf557\": \"archway\",\r\n \"\\uf558\": \"atlas\",\r\n \"\\uf559\": \"award\",\r\n \"\\uf55a\": \"backspace\",\r\n \"\\uf55b\": \"bezier-curve\",\r\n \"\\uf55c\": \"bong\",\r\n \"\\uf55d\": \"brush\",\r\n \"\\uf55e\": \"bus-alt\",\r\n \"\\uf55f\": \"cannabis\",\r\n \"\\uf560\": \"check-double\",\r\n \"\\uf561\": \"cocktail\",\r\n \"\\uf562\": \"concierge-bell\",\r\n \"\\uf563\": \"cookie\",\r\n \"\\uf564\": \"cookie-bite\",\r\n \"\\uf565\": \"crop-alt\",\r\n \"\\uf566\": \"digital-tachograph\",\r\n \"\\uf567\": \"dizzy\",\r\n \"\\uf568\": \"drafting-compass\",\r\n \"\\uf569\": \"drum\",\r\n \"\\uf56a\": \"drum-steelpan\",\r\n \"\\uf56b\": \"feather-alt\",\r\n \"\\uf56c\": \"file-contract\",\r\n \"\\uf56d\": \"file-download\",\r\n \"\\uf56e\": \"file-export\",\r\n \"\\uf56f\": \"file-import\",\r\n \"\\uf570\": \"file-invoice\",\r\n \"\\uf571\": \"file-invoice-dollar\",\r\n \"\\uf572\": \"file-prescription\",\r\n \"\\uf573\": \"file-signature\",\r\n \"\\uf574\": \"file-upload\",\r\n \"\\uf575\": \"fill\",\r\n \"\\uf576\": \"fill-drip\",\r\n \"\\uf577\": \"fingerprint\",\r\n \"\\uf578\": \"fish\",\r\n \"\\uf579\": \"flushed\",\r\n \"\\uf57a\": \"frown-open\",\r\n \"\\uf57b\": \"glass-martini-alt\",\r\n \"\\uf57c\": \"globe-africa\",\r\n \"\\uf57d\": \"globe-americas\",\r\n \"\\uf57e\": \"globe-asia\",\r\n \"\\uf57f\": \"grimace\",\r\n \"\\uf580\": \"grin\",\r\n \"\\uf581\": \"grin-alt\",\r\n \"\\uf582\": \"grin-beam\",\r\n \"\\uf583\": \"grin-beam-sweat\",\r\n \"\\uf584\": \"grin-hearts\",\r\n \"\\uf585\": \"grin-squint\",\r\n \"\\uf586\": \"grin-squint-tears\",\r\n \"\\uf587\": \"grin-stars\",\r\n \"\\uf588\": \"grin-tears\",\r\n \"\\uf589\": \"grin-tongue\",\r\n \"\\uf58a\": \"grin-tongue-squint\",\r\n \"\\uf58b\": \"grin-tongue-wink\",\r\n \"\\uf58c\": \"grin-wink\",\r\n \"\\uf58d\": \"grip-horizontal\",\r\n \"\\uf58e\": \"grip-vertical\",\r\n \"\\uf58f\": \"headphones-alt\",\r\n \"\\uf590\": \"headset\",\r\n \"\\uf591\": \"highlighter\",\r\n \"\\uf593\": \"hot-tub\",\r\n \"\\uf594\": \"hotel\",\r\n \"\\uf595\": \"joint\",\r\n \"\\uf596\": \"kiss\",\r\n \"\\uf597\": \"kiss-beam\",\r\n \"\\uf598\": \"kiss-wink-heart\",\r\n \"\\uf599\": \"laugh\",\r\n \"\\uf59a\": \"laugh-beam\",\r\n \"\\uf59b\": \"laugh-squint\",\r\n \"\\uf59c\": \"laugh-wink\",\r\n \"\\uf59d\": \"luggage-cart\",\r\n \"\\uf59f\": \"map-marked\",\r\n \"\\uf5a0\": \"map-marked-alt\",\r\n \"\\uf5a1\": \"marker\",\r\n \"\\uf5a2\": \"medal\",\r\n \"\\uf5a4\": \"meh-blank\",\r\n \"\\uf5a5\": \"meh-rolling-eyes\",\r\n \"\\uf5a6\": \"monument\",\r\n \"\\uf5a7\": \"mortar-pestle\",\r\n \"\\uf5a9\": \"paint-brush-alt\",\r\n \"\\uf5aa\": \"paint-roller\",\r\n \"\\uf5ab\": \"passport\",\r\n \"\\uf5ac\": \"pen-fancy\",\r\n \"\\uf5ad\": \"pen-nib\",\r\n \"\\uf5ae\": \"pencil-ruler\",\r\n \"\\uf5af\": \"plane-arrival\",\r\n \"\\uf5b0\": \"plane-departure\",\r\n \"\\uf5b1\": \"prescription\",\r\n \"\\uf5b3\": \"sad-cry\",\r\n \"\\uf5b4\": \"sad-tear\",\r\n \"\\uf5b6\": \"shuttle-van\",\r\n \"\\uf5b7\": \"signature\",\r\n \"\\uf5b8\": \"smile-beam\",\r\n \"\\uf5b9\": \"smile-plus\",\r\n \"\\uf5ba\": \"solar-panel\",\r\n \"\\uf5bb\": \"spa\",\r\n \"\\uf5bc\": \"splotch\",\r\n \"\\uf5bd\": \"spray-can\",\r\n \"\\uf5bf\": \"stamp\",\r\n \"\\uf5c0\": \"star-half-alt\",\r\n \"\\uf5c1\": \"suitcase-rolling\",\r\n \"\\uf5c2\": \"surprise\",\r\n \"\\uf5c3\": \"swatchbook\",\r\n \"\\uf5c4\": \"swimmer\",\r\n \"\\uf5c5\": \"swimming-pool\",\r\n \"\\uf5c7\": \"tint-slash\",\r\n \"\\uf5c8\": \"tired\",\r\n \"\\uf5c9\": \"tooth\",\r\n \"\\uf5ca\": \"umbrella-beach\",\r\n \"\\uf5cb\": \"vector-square\",\r\n \"\\uf5cd\": \"weight-hanging\",\r\n \"\\uf5ce\": \"wine-glass-alt\",\r\n \"\\uf5d0\": \"air-freshener\",\r\n \"\\uf5d1\": \"apple-alt\",\r\n \"\\uf5d2\": \"atom\",\r\n \"\\uf5d3\": \"atom-alt\",\r\n \"\\uf5d4\": \"backpack\",\r\n \"\\uf5d5\": \"bell-school\",\r\n \"\\uf5d6\": \"bell-school-slash\",\r\n \"\\uf5d7\": \"bone\",\r\n \"\\uf5d8\": \"bone-break\",\r\n \"\\uf5d9\": \"book-alt\",\r\n \"\\uf5da\": \"book-reader\",\r\n \"\\uf5db\": \"books\",\r\n \"\\uf5dc\": \"brain\",\r\n \"\\uf5dd\": \"bus-school\",\r\n \"\\uf5de\": \"car-alt\",\r\n \"\\uf5df\": \"car-battery\",\r\n \"\\uf5e0\": \"car-bump\",\r\n \"\\uf5e1\": \"car-crash\",\r\n \"\\uf5e2\": \"car-garage\",\r\n \"\\uf5e3\": \"car-mechanic\",\r\n \"\\uf5e4\": \"car-side\",\r\n \"\\uf5e5\": \"car-tilt\",\r\n \"\\uf5e6\": \"car-wash\",\r\n \"\\uf5e7\": \"charging-station\",\r\n \"\\uf5e8\": \"clipboard-prescription\",\r\n \"\\uf5e9\": \"compass-slash\",\r\n \"\\uf5ea\": \"diploma\",\r\n \"\\uf5eb\": \"directions\",\r\n \"\\uf5ec\": \"do-not-enter\",\r\n \"\\uf5ed\": \"draw-circle\",\r\n \"\\uf5ee\": \"draw-polygon\",\r\n \"\\uf5ef\": \"draw-square\",\r\n \"\\uf5f0\": \"ear\",\r\n \"\\uf5f2\": \"engine-warning\",\r\n \"\\uf5f3\": \"file-certificate\",\r\n \"\\uf5f4\": \"gas-pump-slash\",\r\n \"\\uf5f5\": \"glasses-alt\",\r\n \"\\uf5f6\": \"globe-stand\",\r\n \"\\uf5f8\": \"heart-rate\",\r\n \"\\uf5f9\": \"inhaler\",\r\n \"\\uf5fb\": \"kidneys\",\r\n \"\\uf5fc\": \"laptop-code\",\r\n \"\\uf5fd\": \"layer-group\",\r\n \"\\uf5fe\": \"layer-minus\",\r\n \"\\uf5ff\": \"layer-plus\",\r\n \"\\uf600\": \"lips\",\r\n \"\\uf601\": \"location\",\r\n \"\\uf602\": \"location-circle\",\r\n \"\\uf603\": \"location-slash\",\r\n \"\\uf604\": \"lungs\",\r\n \"\\uf605\": \"map-marker-alt-slash\",\r\n \"\\uf606\": \"map-marker-check\",\r\n \"\\uf607\": \"map-marker-edit\",\r\n \"\\uf608\": \"map-marker-exclamation\",\r\n \"\\uf609\": \"map-marker-minus\",\r\n \"\\uf60a\": \"map-marker-plus\",\r\n \"\\uf60b\": \"map-marker-question\",\r\n \"\\uf60c\": \"map-marker-slash\",\r\n \"\\uf60d\": \"map-marker-smile\",\r\n \"\\uf60e\": \"map-marker-times\",\r\n \"\\uf610\": \"microscope\",\r\n \"\\uf611\": \"monitor-heart-rate\",\r\n \"\\uf613\": \"oil-can\",\r\n \"\\uf614\": \"oil-temp\",\r\n \"\\uf615\": \"parking-circle\",\r\n \"\\uf616\": \"parking-circle-slash\",\r\n \"\\uf617\": \"parking-slash\",\r\n \"\\uf618\": \"pencil-paintbrush\",\r\n \"\\uf619\": \"poop\",\r\n \"\\uf61a\": \"route-highway\",\r\n \"\\uf61b\": \"route-interstate\",\r\n \"\\uf61c\": \"ruler-triangle\",\r\n \"\\uf61d\": \"scalpel\",\r\n \"\\uf61e\": \"scalpel-path\",\r\n \"\\uf61f\": \"shapes\",\r\n \"\\uf620\": \"skeleton\",\r\n \"\\uf621\": \"star-of-life\",\r\n \"\\uf622\": \"steering-wheel\",\r\n \"\\uf623\": \"stomach\",\r\n \"\\uf624\": \"tachometer-alt-average\",\r\n \"\\uf625\": \"tachometer-alt-fast\",\r\n \"\\uf626\": \"tachometer-alt-fastest\",\r\n \"\\uf627\": \"tachometer-alt-slow\",\r\n \"\\uf628\": \"tachometer-alt-slowest\",\r\n \"\\uf629\": \"tachometer-average\",\r\n \"\\uf62a\": \"tachometer-fast\",\r\n \"\\uf62b\": \"tachometer-fastest\",\r\n \"\\uf62c\": \"tachometer-slow\",\r\n \"\\uf62d\": \"tachometer-slowest\",\r\n \"\\uf62e\": \"teeth\",\r\n \"\\uf62f\": \"teeth-open\",\r\n \"\\uf630\": \"theater-masks\",\r\n \"\\uf631\": \"tire\",\r\n \"\\uf632\": \"tire-flat\",\r\n \"\\uf633\": \"tire-pressure-warning\",\r\n \"\\uf634\": \"tire-rugged\",\r\n \"\\uf635\": \"toothbrush\",\r\n \"\\uf636\": \"traffic-cone\",\r\n \"\\uf637\": \"traffic-light\",\r\n \"\\uf638\": \"traffic-light-go\",\r\n \"\\uf639\": \"traffic-light-slow\",\r\n \"\\uf63a\": \"traffic-light-stop\",\r\n \"\\uf63b\": \"truck-monster\",\r\n \"\\uf63c\": \"truck-pickup\",\r\n \"\\uf63d\": \"users-class\",\r\n \"\\uf63e\": \"watch-fitness\",\r\n \"\\uf640\": \"abacus\",\r\n \"\\uf641\": \"ad\",\r\n \"\\uf643\": \"analytics\",\r\n \"\\uf644\": \"ankh\",\r\n \"\\uf645\": \"badge-dollar\",\r\n \"\\uf646\": \"badge-percent\",\r\n \"\\uf647\": \"bible\",\r\n \"\\uf648\": \"bullseye-arrow\",\r\n \"\\uf649\": \"bullseye-pointer\",\r\n \"\\uf64a\": \"business-time\",\r\n \"\\uf64b\": \"cabinet-filing\",\r\n \"\\uf64c\": \"calculator-alt\",\r\n \"\\uf64d\": \"chart-line-down\",\r\n \"\\uf64e\": \"chart-pie-alt\",\r\n \"\\uf64f\": \"city\",\r\n \"\\uf650\": \"comment-alt-dollar\",\r\n \"\\uf651\": \"comment-dollar\",\r\n \"\\uf652\": \"comments-alt-dollar\",\r\n \"\\uf653\": \"comments-dollar\",\r\n \"\\uf654\": \"cross\",\r\n \"\\uf655\": \"dharmachakra\",\r\n \"\\uf656\": \"empty-set\",\r\n \"\\uf657\": \"envelope-open-dollar\",\r\n \"\\uf658\": \"envelope-open-text\",\r\n \"\\uf659\": \"file-chart-line\",\r\n \"\\uf65a\": \"file-chart-pie\",\r\n \"\\uf65b\": \"file-spreadsheet\",\r\n \"\\uf65c\": \"file-user\",\r\n \"\\uf65d\": \"folder-minus\",\r\n \"\\uf65e\": \"folder-plus\",\r\n \"\\uf65f\": \"folder-times\",\r\n \"\\uf660\": \"folders\",\r\n \"\\uf661\": \"function\",\r\n \"\\uf662\": \"funnel-dollar\",\r\n \"\\uf663\": \"gift-card\",\r\n \"\\uf664\": \"gopuram\",\r\n \"\\uf665\": \"hamsa\",\r\n \"\\uf666\": \"haykal\",\r\n \"\\uf667\": \"integral\",\r\n \"\\uf668\": \"intersection\",\r\n \"\\uf669\": \"jedi\",\r\n \"\\uf66a\": \"journal-whills\",\r\n \"\\uf66b\": \"kaaba\",\r\n \"\\uf66c\": \"keynote\",\r\n \"\\uf66d\": \"khanda\",\r\n \"\\uf66e\": \"lambda\",\r\n \"\\uf66f\": \"landmark\",\r\n \"\\uf670\": \"lightbulb-dollar\",\r\n \"\\uf671\": \"lightbulb-exclamation\",\r\n \"\\uf672\": \"lightbulb-on\",\r\n \"\\uf673\": \"lightbulb-slash\",\r\n \"\\uf674\": \"mail-bulk\",\r\n \"\\uf675\": \"megaphone\",\r\n \"\\uf676\": \"menorah\",\r\n \"\\uf677\": \"mind-share\",\r\n \"\\uf678\": \"mosque\",\r\n \"\\uf679\": \"om\",\r\n \"\\uf67a\": \"omega\",\r\n \"\\uf67b\": \"pastafarianism\",\r\n \"\\uf67c\": \"peace\",\r\n \"\\uf67d\": \"phone-office\",\r\n \"\\uf67e\": \"pi\",\r\n \"\\uf67f\": \"place-of-worship\",\r\n \"\\uf680\": \"podium\",\r\n \"\\uf681\": \"poll\",\r\n \"\\uf682\": \"poll-h\",\r\n \"\\uf683\": \"pray\",\r\n \"\\uf684\": \"praying-hands\",\r\n \"\\uf685\": \"presentation\",\r\n \"\\uf686\": \"print-slash\",\r\n \"\\uf687\": \"quran\",\r\n \"\\uf688\": \"search-dollar\",\r\n \"\\uf689\": \"search-location\",\r\n \"\\uf68a\": \"shredder\",\r\n \"\\uf68b\": \"sigma\",\r\n \"\\uf68c\": \"signal-1\",\r\n \"\\uf68d\": \"signal-2\",\r\n \"\\uf68e\": \"signal-3\",\r\n \"\\uf68f\": \"signal-4\",\r\n \"\\uf690\": \"signal-alt\",\r\n \"\\uf691\": \"signal-alt-1\",\r\n \"\\uf692\": \"signal-alt-2\",\r\n \"\\uf693\": \"signal-alt-3\",\r\n \"\\uf694\": \"signal-alt-slash\",\r\n \"\\uf695\": \"signal-slash\",\r\n \"\\uf696\": \"socks\",\r\n \"\\uf697\": \"square-root\",\r\n \"\\uf698\": \"square-root-alt\",\r\n \"\\uf699\": \"star-and-crescent\",\r\n \"\\uf69a\": \"star-of-david\",\r\n \"\\uf69b\": \"synagogue\",\r\n \"\\uf69c\": \"tally\",\r\n \"\\uf69e\": \"theta\",\r\n \"\\uf69f\": \"tilde\",\r\n \"\\uf6a0\": \"torah\",\r\n \"\\uf6a1\": \"torii-gate\",\r\n \"\\uf6a2\": \"union\",\r\n \"\\uf6a3\": \"user-chart\",\r\n \"\\uf6a4\": \"user-crown\",\r\n \"\\uf6a5\": \"users-crown\",\r\n \"\\uf6a6\": \"value-absolute\",\r\n \"\\uf6a7\": \"vihara\",\r\n \"\\uf6a8\": \"volume\",\r\n \"\\uf6a9\": \"volume-mute\",\r\n \"\\uf6aa\": \"wifi-1\",\r\n \"\\uf6ab\": \"wifi-2\",\r\n \"\\uf6ac\": \"wifi-slash\",\r\n \"\\uf6ad\": \"yin-yang\",\r\n \"\\uf6ae\": \"acorn\",\r\n \"\\uf6b0\": \"alicorn\",\r\n \"\\uf6b1\": \"apple-crate\",\r\n \"\\uf6b2\": \"axe\",\r\n \"\\uf6b3\": \"axe-battle\",\r\n \"\\uf6b4\": \"badger-honey\",\r\n \"\\uf6b5\": \"bat\",\r\n \"\\uf6b6\": \"blender-phone\",\r\n \"\\uf6b7\": \"book-dead\",\r\n \"\\uf6b8\": \"book-spells\",\r\n \"\\uf6b9\": \"bow-arrow\",\r\n \"\\uf6ba\": \"campfire\",\r\n \"\\uf6bb\": \"campground\",\r\n \"\\uf6bc\": \"candle-holder\",\r\n \"\\uf6bd\": \"candy-corn\",\r\n \"\\uf6be\": \"cat\",\r\n \"\\uf6bf\": \"cauldron\",\r\n \"\\uf6c0\": \"chair\",\r\n \"\\uf6c1\": \"chair-office\",\r\n \"\\uf6c2\": \"claw-marks\",\r\n \"\\uf6c3\": \"cloud-moon\",\r\n \"\\uf6c4\": \"cloud-sun\",\r\n \"\\uf6c5\": \"coffee-togo\",\r\n \"\\uf6c6\": \"coffin\",\r\n \"\\uf6c7\": \"corn\",\r\n \"\\uf6c8\": \"cow\",\r\n \"\\uf6cb\": \"dagger\",\r\n \"\\uf6cd\": \"dice-d10\",\r\n \"\\uf6ce\": \"dice-d12\",\r\n \"\\uf6cf\": \"dice-d20\",\r\n \"\\uf6d0\": \"dice-d4\",\r\n \"\\uf6d1\": \"dice-d6\",\r\n \"\\uf6d2\": \"dice-d8\",\r\n \"\\uf6d3\": \"dog\",\r\n \"\\uf6d4\": \"dog-leashed\",\r\n \"\\uf6d5\": \"dragon\",\r\n \"\\uf6d6\": \"drumstick\",\r\n \"\\uf6d7\": \"drumstick-bite\",\r\n \"\\uf6d8\": \"duck\",\r\n \"\\uf6d9\": \"dungeon\",\r\n \"\\uf6da\": \"elephant\",\r\n \"\\uf6db\": \"eye-evil\",\r\n \"\\uf6dd\": \"file-csv\",\r\n \"\\uf6de\": \"fist-raised\",\r\n \"\\uf6df\": \"flame\",\r\n \"\\uf6e0\": \"flask-poison\",\r\n \"\\uf6e1\": \"flask-potion\",\r\n \"\\uf6e2\": \"ghost\",\r\n \"\\uf6e3\": \"hammer\",\r\n \"\\uf6e4\": \"hammer-war\",\r\n \"\\uf6e5\": \"hand-holding-magic\",\r\n \"\\uf6e6\": \"hanukiah\",\r\n \"\\uf6e7\": \"hat-witch\",\r\n \"\\uf6e8\": \"hat-wizard\",\r\n \"\\uf6e9\": \"head-side\",\r\n \"\\uf6ea\": \"head-vr\",\r\n \"\\uf6eb\": \"helmet-battle\",\r\n \"\\uf6ec\": \"hiking\",\r\n \"\\uf6ed\": \"hippo\",\r\n \"\\uf6ee\": \"hockey-mask\",\r\n \"\\uf6ef\": \"hood-cloak\",\r\n \"\\uf6f0\": \"horse\",\r\n \"\\uf6f1\": \"house-damage\",\r\n \"\\uf6f2\": \"hryvnia\",\r\n \"\\uf6f3\": \"key-skeleton\",\r\n \"\\uf6f4\": \"kite\",\r\n \"\\uf6f5\": \"knife-kitchen\",\r\n \"\\uf6f6\": \"leaf-maple\",\r\n \"\\uf6f7\": \"leaf-oak\",\r\n \"\\uf6f8\": \"mace\",\r\n \"\\uf6f9\": \"mandolin\",\r\n \"\\uf6fa\": \"mask\",\r\n \"\\uf6fb\": \"monkey\",\r\n \"\\uf6fc\": \"mountain\",\r\n \"\\uf6fd\": \"mountains\",\r\n \"\\uf6fe\": \"narwhal\",\r\n \"\\uf6ff\": \"network-wired\",\r\n \"\\uf700\": \"otter\",\r\n \"\\uf701\": \"paw-alt\",\r\n \"\\uf702\": \"paw-claws\",\r\n \"\\uf703\": \"pegasus\",\r\n \"\\uf705\": \"pie\",\r\n \"\\uf706\": \"pig\",\r\n \"\\uf707\": \"pumpkin\",\r\n \"\\uf708\": \"rabbit\",\r\n \"\\uf709\": \"rabbit-fast\",\r\n \"\\uf70a\": \"ram\",\r\n \"\\uf70b\": \"ring\",\r\n \"\\uf70c\": \"running\",\r\n \"\\uf70d\": \"scarecrow\",\r\n \"\\uf70e\": \"scroll\",\r\n \"\\uf70f\": \"scroll-old\",\r\n \"\\uf710\": \"scythe\",\r\n \"\\uf711\": \"sheep\",\r\n \"\\uf712\": \"shield-cross\",\r\n \"\\uf713\": \"shovel\",\r\n \"\\uf714\": \"skull-crossbones\",\r\n \"\\uf715\": \"slash\",\r\n \"\\uf716\": \"snake\",\r\n \"\\uf717\": \"spider\",\r\n \"\\uf718\": \"spider-black-widow\",\r\n \"\\uf719\": \"spider-web\",\r\n \"\\uf71a\": \"squirrel\",\r\n \"\\uf71b\": \"staff\",\r\n \"\\uf71c\": \"sword\",\r\n \"\\uf71d\": \"swords\",\r\n \"\\uf71e\": \"toilet-paper\",\r\n \"\\uf71f\": \"toilet-paper-alt\",\r\n \"\\uf720\": \"tombstone\",\r\n \"\\uf721\": \"tombstone-alt\",\r\n \"\\uf722\": \"tractor\",\r\n \"\\uf723\": \"treasure-chest\",\r\n \"\\uf724\": \"trees\",\r\n \"\\uf725\": \"turkey\",\r\n \"\\uf726\": \"turtle\",\r\n \"\\uf727\": \"unicorn\",\r\n \"\\uf728\": \"user-injured\",\r\n \"\\uf729\": \"vr-cardboard\",\r\n \"\\uf72a\": \"wand\",\r\n \"\\uf72b\": \"wand-magic\",\r\n \"\\uf72c\": \"whale\",\r\n \"\\uf72d\": \"wheat\",\r\n \"\\uf72e\": \"wind\",\r\n \"\\uf72f\": \"wine-bottle\",\r\n \"\\uf732\": \"ballot\",\r\n \"\\uf733\": \"ballot-check\",\r\n \"\\uf734\": \"booth-curtain\",\r\n \"\\uf735\": \"box-ballot\",\r\n \"\\uf736\": \"calendar-star\",\r\n \"\\uf737\": \"clipboard-list-check\",\r\n \"\\uf738\": \"cloud-drizzle\",\r\n \"\\uf739\": \"cloud-hail\",\r\n \"\\uf73a\": \"cloud-hail-mixed\",\r\n \"\\uf73b\": \"cloud-meatball\",\r\n \"\\uf73c\": \"cloud-moon-rain\",\r\n \"\\uf73d\": \"cloud-rain\",\r\n \"\\uf73e\": \"cloud-rainbow\",\r\n \"\\uf73f\": \"cloud-showers\",\r\n \"\\uf740\": \"cloud-showers-heavy\",\r\n \"\\uf741\": \"cloud-sleet\",\r\n \"\\uf742\": \"cloud-snow\",\r\n \"\\uf743\": \"cloud-sun-rain\",\r\n \"\\uf744\": \"clouds\",\r\n \"\\uf745\": \"clouds-moon\",\r\n \"\\uf746\": \"clouds-sun\",\r\n \"\\uf747\": \"democrat\",\r\n \"\\uf748\": \"dewpoint\",\r\n \"\\uf749\": \"eclipse\",\r\n \"\\uf74a\": \"eclipse-alt\",\r\n \"\\uf74b\": \"fire-smoke\",\r\n \"\\uf74c\": \"flag-alt\",\r\n \"\\uf74d\": \"flag-usa\",\r\n \"\\uf74e\": \"fog\",\r\n \"\\uf74f\": \"house-flood\",\r\n \"\\uf750\": \"humidity\",\r\n \"\\uf751\": \"hurricane\",\r\n \"\\uf752\": \"landmark-alt\",\r\n \"\\uf753\": \"meteor\",\r\n \"\\uf754\": \"moon-cloud\",\r\n \"\\uf755\": \"moon-stars\",\r\n \"\\uf756\": \"person-booth\",\r\n \"\\uf757\": \"person-sign\",\r\n \"\\uf758\": \"podium-star\",\r\n \"\\uf759\": \"poll-people\",\r\n \"\\uf75a\": \"poo-storm\",\r\n \"\\uf75b\": \"rainbow\",\r\n \"\\uf75c\": \"raindrops\",\r\n \"\\uf75e\": \"republican\",\r\n \"\\uf75f\": \"smog\",\r\n \"\\uf760\": \"smoke\",\r\n \"\\uf761\": \"snow-blowing\",\r\n \"\\uf762\": \"stars\",\r\n \"\\uf763\": \"sun-cloud\",\r\n \"\\uf764\": \"sun-dust\",\r\n \"\\uf765\": \"sun-haze\",\r\n \"\\uf766\": \"sunrise\",\r\n \"\\uf767\": \"sunset\",\r\n \"\\uf768\": \"temperature-frigid\",\r\n \"\\uf769\": \"temperature-high\",\r\n \"\\uf76a\": \"temperature-hot\",\r\n \"\\uf76b\": \"temperature-low\",\r\n \"\\uf76c\": \"thunderstorm\",\r\n \"\\uf76d\": \"thunderstorm-moon\",\r\n \"\\uf76e\": \"thunderstorm-sun\",\r\n \"\\uf76f\": \"tornado\",\r\n \"\\uf770\": \"volcano\",\r\n \"\\uf771\": \"vote-nay\",\r\n \"\\uf772\": \"vote-yea\",\r\n \"\\uf773\": \"water\",\r\n \"\\uf774\": \"water-lower\",\r\n \"\\uf775\": \"water-rise\",\r\n \"\\uf776\": \"wind-warning\",\r\n \"\\uf777\": \"windsock\",\r\n \"\\uf779\": \"angel\",\r\n \"\\uf77c\": \"baby\",\r\n \"\\uf77d\": \"baby-carriage\",\r\n \"\\uf77e\": \"ball-pile\",\r\n \"\\uf77f\": \"bells\",\r\n \"\\uf780\": \"biohazard\",\r\n \"\\uf781\": \"blog\",\r\n \"\\uf782\": \"boot\",\r\n \"\\uf783\": \"calendar-day\",\r\n \"\\uf784\": \"calendar-week\",\r\n \"\\uf786\": \"candy-cane\",\r\n \"\\uf787\": \"carrot\",\r\n \"\\uf788\": \"cash-register\",\r\n \"\\uf78a\": \"chart-network\",\r\n \"\\uf78b\": \"chimney\",\r\n \"\\uf78c\": \"compress-arrows-alt\",\r\n \"\\uf78e\": \"deer\",\r\n \"\\uf78f\": \"deer-rudolph\",\r\n \"\\uf792\": \"dreidel\",\r\n \"\\uf793\": \"dumpster\",\r\n \"\\uf794\": \"dumpster-fire\",\r\n \"\\uf795\": \"ear-muffs\",\r\n \"\\uf796\": \"ethernet\",\r\n \"\\uf79a\": \"fireplace\",\r\n \"\\uf79b\": \"frosty-head\",\r\n \"\\uf79c\": \"gifts\",\r\n \"\\uf79d\": \"gingerbread-man\",\r\n \"\\uf79e\": \"glass-champagne\",\r\n \"\\uf79f\": \"glass-cheers\",\r\n \"\\uf7a0\": \"glass-whiskey\",\r\n \"\\uf7a1\": \"glass-whiskey-rocks\",\r\n \"\\uf7a2\": \"globe-europe\",\r\n \"\\uf7a3\": \"globe-snow\",\r\n \"\\uf7a4\": \"grip-lines\",\r\n \"\\uf7a5\": \"grip-lines-vertical\",\r\n \"\\uf7a6\": \"guitar\",\r\n \"\\uf7a7\": \"hat-santa\",\r\n \"\\uf7a8\": \"hat-winter\",\r\n \"\\uf7a9\": \"heart-broken\",\r\n \"\\uf7aa\": \"holly-berry\",\r\n \"\\uf7ab\": \"horse-head\",\r\n \"\\uf7ac\": \"ice-skate\",\r\n \"\\uf7ad\": \"icicles\",\r\n \"\\uf7ae\": \"igloo\",\r\n \"\\uf7b2\": \"lights-holiday\",\r\n \"\\uf7b4\": \"mistletoe\",\r\n \"\\uf7b5\": \"mitten\",\r\n \"\\uf7b6\": \"mug-hot\",\r\n \"\\uf7b7\": \"mug-marshmallows\",\r\n \"\\uf7b8\": \"ornament\",\r\n \"\\uf7b9\": \"radiation\",\r\n \"\\uf7ba\": \"radiation-alt\",\r\n \"\\uf7bd\": \"restroom\",\r\n \"\\uf7be\": \"rv\",\r\n \"\\uf7bf\": \"satellite\",\r\n \"\\uf7c0\": \"satellite-dish\",\r\n \"\\uf7c1\": \"scarf\",\r\n \"\\uf7c2\": \"sd-card\",\r\n \"\\uf7c3\": \"shovel-snow\",\r\n \"\\uf7c4\": \"sim-card\",\r\n \"\\uf7c5\": \"skating\",\r\n \"\\uf7c7\": \"ski-jump\",\r\n \"\\uf7c8\": \"ski-lift\",\r\n \"\\uf7c9\": \"skiing\",\r\n \"\\uf7ca\": \"skiing-nordic\",\r\n \"\\uf7cb\": \"sledding\",\r\n \"\\uf7cc\": \"sleigh\",\r\n \"\\uf7cd\": \"sms\",\r\n \"\\uf7ce\": \"snowboarding\",\r\n \"\\uf7cf\": \"snowflakes\",\r\n \"\\uf7d0\": \"snowman\",\r\n \"\\uf7d1\": \"snowmobile\",\r\n \"\\uf7d2\": \"snowplow\",\r\n \"\\uf7d4\": \"star-christmas\",\r\n \"\\uf7d5\": \"stocking\",\r\n \"\\uf7d7\": \"tenge\",\r\n \"\\uf7d8\": \"toilet\",\r\n \"\\uf7d9\": \"tools\",\r\n \"\\uf7da\": \"tram\",\r\n \"\\uf7db\": \"tree-christmas\",\r\n \"\\uf7dc\": \"tree-decorated\",\r\n \"\\uf7dd\": \"tree-large\",\r\n \"\\uf7de\": \"truck-plow\",\r\n \"\\uf7e2\": \"wreath\",\r\n \"\\uf7e4\": \"fire-alt\",\r\n \"\\uf7e5\": \"bacon\",\r\n \"\\uf7e6\": \"book-medical\",\r\n \"\\uf7e7\": \"book-user\",\r\n \"\\uf7e8\": \"books-medical\",\r\n \"\\uf7e9\": \"brackets\",\r\n \"\\uf7ea\": \"brackets-curly\",\r\n \"\\uf7eb\": \"bread-loaf\",\r\n \"\\uf7ec\": \"bread-slice\",\r\n \"\\uf7ed\": \"burrito\",\r\n \"\\uf7ee\": \"chart-scatter\",\r\n \"\\uf7ef\": \"cheese\",\r\n \"\\uf7f0\": \"cheese-swiss\",\r\n \"\\uf7f1\": \"cheeseburger\",\r\n \"\\uf7f2\": \"clinic-medical\",\r\n \"\\uf7f3\": \"clipboard-user\",\r\n \"\\uf7f4\": \"comment-alt-medical\",\r\n \"\\uf7f5\": \"comment-medical\",\r\n \"\\uf7f6\": \"croissant\",\r\n \"\\uf7f7\": \"crutch\",\r\n \"\\uf7f8\": \"crutches\",\r\n \"\\uf7f9\": \"debug\",\r\n \"\\uf7fa\": \"disease\",\r\n \"\\uf7fb\": \"egg\",\r\n \"\\uf7fc\": \"egg-fried\",\r\n \"\\uf7fd\": \"files-medical\",\r\n \"\\uf7fe\": \"fish-cooked\",\r\n \"\\uf7ff\": \"flower\",\r\n \"\\uf800\": \"flower-daffodil\",\r\n \"\\uf801\": \"flower-tulip\",\r\n \"\\uf802\": \"folder-tree\",\r\n \"\\uf803\": \"french-fries\",\r\n \"\\uf804\": \"glass\",\r\n \"\\uf805\": \"hamburger\",\r\n \"\\uf806\": \"hand-middle-finger\",\r\n \"\\uf807\": \"hard-hat\",\r\n \"\\uf808\": \"head-side-brain\",\r\n \"\\uf809\": \"head-side-medical\",\r\n \"\\uf80a\": \"home-alt\",\r\n \"\\uf80b\": \"home-lg\",\r\n \"\\uf80c\": \"home-lg-alt\",\r\n \"\\uf80d\": \"hospital-user\",\r\n \"\\uf80e\": \"hospitals\",\r\n \"\\uf80f\": \"hotdog\",\r\n \"\\uf810\": \"ice-cream\",\r\n \"\\uf811\": \"island-tropical\",\r\n \"\\uf812\": \"laptop-medical\",\r\n \"\\uf813\": \"mailbox\",\r\n \"\\uf814\": \"meat\",\r\n \"\\uf815\": \"pager\",\r\n \"\\uf816\": \"pepper-hot\",\r\n \"\\uf817\": \"pizza\",\r\n \"\\uf818\": \"pizza-slice\",\r\n \"\\uf819\": \"popcorn\",\r\n \"\\uf81a\": \"print-search\",\r\n \"\\uf81b\": \"rings-wedding\",\r\n \"\\uf81c\": \"sack\",\r\n \"\\uf81d\": \"sack-dollar\",\r\n \"\\uf81e\": \"salad\",\r\n \"\\uf81f\": \"sandwich\",\r\n \"\\uf820\": \"sausage\",\r\n \"\\uf821\": \"shish-kebab\",\r\n \"\\uf822\": \"sickle\",\r\n \"\\uf823\": \"soup\",\r\n \"\\uf824\": \"steak\",\r\n \"\\uf825\": \"stretcher\",\r\n \"\\uf826\": \"taco\",\r\n \"\\uf827\": \"tanakh\",\r\n \"\\uf828\": \"tasks-alt\",\r\n \"\\uf829\": \"trash-restore\",\r\n \"\\uf82a\": \"trash-restore-alt\",\r\n \"\\uf82b\": \"tree-palm\",\r\n \"\\uf82c\": \"user-hard-hat\",\r\n \"\\uf82d\": \"user-headset\",\r\n \"\\uf82e\": \"user-md-chat\",\r\n \"\\uf82f\": \"user-nurse\",\r\n \"\\uf830\": \"users-medical\",\r\n \"\\uf831\": \"walker\",\r\n \"\\uf832\": \"webcam\",\r\n \"\\uf833\": \"webcam-slash\",\r\n \"\\uf83e\": \"wave-square\",\r\n \"\\uf843\": \"alarm-exclamation\",\r\n \"\\uf844\": \"alarm-plus\",\r\n \"\\uf845\": \"alarm-snooze\",\r\n \"\\uf846\": \"align-slash\",\r\n \"\\uf847\": \"bags-shopping\",\r\n \"\\uf848\": \"bell-exclamation\",\r\n \"\\uf849\": \"bell-plus\",\r\n \"\\uf84a\": \"biking\",\r\n \"\\uf84b\": \"biking-mountain\",\r\n \"\\uf84c\": \"border-all\",\r\n \"\\uf84d\": \"border-bottom\",\r\n \"\\uf84e\": \"border-inner\",\r\n \"\\uf84f\": \"border-left\",\r\n \"\\uf850\": \"border-none\",\r\n \"\\uf851\": \"border-outer\",\r\n \"\\uf852\": \"border-right\",\r\n \"\\uf853\": \"border-style\",\r\n \"\\uf854\": \"border-style-alt\",\r\n \"\\uf855\": \"border-top\",\r\n \"\\uf856\": \"bring-forward\",\r\n \"\\uf857\": \"bring-front\",\r\n \"\\uf858\": \"burger-soda\",\r\n \"\\uf859\": \"car-building\",\r\n \"\\uf85a\": \"car-bus\",\r\n \"\\uf85b\": \"cars\",\r\n \"\\uf85c\": \"coin\",\r\n \"\\uf85d\": \"construction\",\r\n \"\\uf85e\": \"digging\",\r\n \"\\uf85f\": \"drone\",\r\n \"\\uf860\": \"drone-alt\",\r\n \"\\uf861\": \"dryer\",\r\n \"\\uf862\": \"dryer-alt\",\r\n \"\\uf863\": \"fan\",\r\n \"\\uf864\": \"farm\",\r\n \"\\uf865\": \"file-search\",\r\n \"\\uf866\": \"font-case\",\r\n \"\\uf867\": \"game-board\",\r\n \"\\uf868\": \"game-board-alt\",\r\n \"\\uf869\": \"glass-citrus\",\r\n \"\\uf86a\": \"h4\",\r\n \"\\uf86b\": \"hat-chef\",\r\n \"\\uf86c\": \"horizontal-rule\",\r\n \"\\uf86d\": \"icons\",\r\n \"\\uf86e\": \"icons-alt\",\r\n \"\\uf86f\": \"kerning\",\r\n \"\\uf870\": \"line-columns\",\r\n \"\\uf871\": \"line-height\",\r\n \"\\uf872\": \"money-check-edit\",\r\n \"\\uf873\": \"money-check-edit-alt\",\r\n \"\\uf874\": \"mug\",\r\n \"\\uf875\": \"mug-tea\",\r\n \"\\uf876\": \"overline\",\r\n \"\\uf877\": \"page-break\",\r\n \"\\uf878\": \"paragraph-rtl\",\r\n \"\\uf879\": \"phone-alt\",\r\n \"\\uf87a\": \"phone-laptop\",\r\n \"\\uf87b\": \"phone-square-alt\",\r\n \"\\uf87c\": \"photo-video\",\r\n \"\\uf87d\": \"remove-format\",\r\n \"\\uf87e\": \"send-back\",\r\n \"\\uf87f\": \"send-backward\",\r\n \"\\uf880\": \"snooze\",\r\n \"\\uf881\": \"sort-alpha-down-alt\",\r\n \"\\uf882\": \"sort-alpha-up-alt\",\r\n \"\\uf883\": \"sort-alt\",\r\n \"\\uf884\": \"sort-amount-down-alt\",\r\n \"\\uf885\": \"sort-amount-up-alt\",\r\n \"\\uf886\": \"sort-numeric-down-alt\",\r\n \"\\uf887\": \"sort-numeric-up-alt\",\r\n \"\\uf888\": \"sort-shapes-down\",\r\n \"\\uf889\": \"sort-shapes-down-alt\",\r\n \"\\uf88a\": \"sort-shapes-up\",\r\n \"\\uf88b\": \"sort-shapes-up-alt\",\r\n \"\\uf88c\": \"sort-size-down\",\r\n \"\\uf88d\": \"sort-size-down-alt\",\r\n \"\\uf88e\": \"sort-size-up\",\r\n \"\\uf88f\": \"sort-size-up-alt\",\r\n \"\\uf890\": \"sparkles\",\r\n \"\\uf891\": \"spell-check\",\r\n \"\\uf892\": \"sunglasses\",\r\n \"\\uf893\": \"text\",\r\n \"\\uf894\": \"text-size\",\r\n \"\\uf895\": \"trash-undo\",\r\n \"\\uf896\": \"trash-undo-alt\",\r\n \"\\uf897\": \"voicemail\",\r\n \"\\uf898\": \"washer\",\r\n \"\\uf899\": \"wave-sine\",\r\n \"\\uf89a\": \"wave-triangle\",\r\n \"\\uf89b\": \"wind-turbine\"\r\n};\r\n\r\nfunction createUse(type, id) {\r\n const c = typeof consts !== 'undefined' ? consts : {};\r\n const path = c.path ||\r\n (typeof _network !== 'undefined' ? _network.root :\r\n (typeof _net !== 'undefined' ? _net.root : ''));\r\n const ver = c.resver == null ? '' : `?${c.resver}`;\r\n const use = document.createElementNS(svgns, 'use');\r\n if (id?.length === 1 && id.charCodeAt(0) > 0xf000) {\r\n id = dict[id];\r\n }\r\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `${path}fonts/${type}.svg${ver}#${id}`);\r\n return use;\r\n}\r\n\r\nexport function changeIcon(svg, type, id) {\r\n if (svg instanceof SVGElement) {\r\n svg.replaceChildren(createUse(type, id));\r\n }\r\n return svg;\r\n}\r\n\r\nexport function createIcon(type, id, style) {\r\n const svg = document.createElementNS(svgns, 'svg');\r\n svg.appendChild(createUse(type, id));\r\n if (style != null) {\r\n for (let css of Object.entries(style)) {\r\n svg.style.setProperty(css[0], css[1]);\r\n }\r\n }\r\n return svg;\r\n}\r\n\r\nexport function resolveIcon(container) {\r\n const svgs = container.querySelectorAll('svg[data-id]');\r\n for (let icon of svgs) {\r\n const type = icon.dataset.type;\r\n const id = icon.dataset.id;\r\n icon.replaceChildren(createUse(type, id));\r\n icon.removeAttribute('data-type');\r\n icon.removeAttribute('data-id');\r\n }\r\n return container;\r\n}","import './css/checkbox.scss';\r\nimport { createElement } from \"../functions\";\r\nimport { createIcon } from \"./icon\";\r\n\r\nfunction fillCheckbox(container, type = 'fa-regular', label, tabindex = -1, charactor = 'check', title) {\r\n container.appendChild(\r\n createElement('layer', layer => {\r\n layer.className = 'ui-check-inner';\r\n layer.addEventListener('keypress', e => {\r\n if (e.key === ' ' || e.key === 'Enter') {\r\n const input = container.querySelector('input');\r\n if (input != null) {\r\n input.checked = !input.checked;\r\n input.dispatchEvent(new Event('change'));\r\n }\r\n }\r\n });\r\n if (tabindex >= 0) {\r\n layer.tabIndex = tabindex;\r\n }\r\n }, createIcon(type, charactor))\r\n );\r\n if (label instanceof Element) {\r\n container.appendChild(label);\r\n } else if (label != null && String(label).length > 0) {\r\n container.appendChild(\r\n createElement('span', span => {\r\n span.innerText = label;\r\n span.title = title;\r\n })\r\n );\r\n }\r\n}\r\n\r\nexport function createRadiobox(opts = {}) {\r\n const container = createElement('label', 'ui-check-wrapper ui-radio-wrapper',\r\n createElement('input', input => {\r\n input.setAttribute('type', 'radio');\r\n input.name = opts.name;\r\n if (opts.checked === true) {\r\n input.checked = true;\r\n }\r\n if (opts.enabled === false) {\r\n input.disabled = true;\r\n }\r\n if (opts.customAttributes != null) {\r\n for (let entry of Object.entries(opts.customAttributes)) {\r\n input.setAttribute(entry[0], entry[1]);\r\n }\r\n }\r\n if (typeof opts.onchange === 'function') {\r\n input.addEventListener('change', opts.onchange);\r\n }\r\n }));\r\n if (opts.className) {\r\n container.classList.add(opts.className);\r\n }\r\n fillCheckbox(container, opts.type, opts.label, opts.tabIndex, 'circle', opts.title);\r\n return container;\r\n}\r\n\r\nexport function createCheckbox(opts = {}) {\r\n const container = createElement('label', 'ui-check-wrapper',\r\n createElement('input', input => {\r\n input.setAttribute('type', 'checkbox');\r\n if (opts.checked === true) {\r\n input.checked = true;\r\n }\r\n if (opts.enabled === false) {\r\n input.disabled = true;\r\n }\r\n if (opts.customAttributes != null) {\r\n for (let entry of Object.entries(opts.customAttributes)) {\r\n input.setAttribute(entry[0], entry[1]);\r\n }\r\n }\r\n if (typeof opts.onchange === 'function') {\r\n input.addEventListener('change', opts.onchange);\r\n }\r\n }));\r\n if (opts.className) {\r\n container.classList.add(opts.className);\r\n }\r\n if (opts.enabled === false) {\r\n container.classList.add('disabled');\r\n }\r\n if (opts.checkedNode != null && opts.uncheckedNode != null) {\r\n container.classList.add('ui-check-image-wrapper');\r\n let height = opts.imageHeight;\r\n if (isNaN(height) || height <= 0) {\r\n height = 14;\r\n }\r\n opts.checkedNode.classList.add('checked');\r\n container.appendChild(opts.checkedNode);\r\n opts.uncheckedNode.classList.add('unchecked');\r\n container.appendChild(opts.uncheckedNode);\r\n } else {\r\n fillCheckbox(container, opts.type, opts.label, opts.tabIndex, undefined, opts.title);\r\n }\r\n return container;\r\n}\r\n\r\nexport function resolveCheckbox(container = document.body, legacy) {\r\n if (legacy) {\r\n const checks = container.querySelectorAll('input[type=\"checkbox\"]');\r\n for (let chk of checks) {\r\n if (chk.parentElement.classList.contains('ui-check-wrapper')) {\r\n // skip\r\n continue;\r\n }\r\n const id = chk.id;\r\n let label, text;\r\n if (id != null) {\r\n label = container.querySelector(`label[for=\"${id}\"]`);\r\n }\r\n if (label == null) {\r\n const e = chk.nextElementSibling;\r\n if (e != null) {\r\n if (e.tagName === 'LABEL') {\r\n label = e;\r\n } else if (e.tagName === 'SPAN' && e.dataset.lgid != null) {\r\n text = e.innerText;\r\n e.style.display = 'none';\r\n }\r\n }\r\n }\r\n if (label == null) {\r\n const e = chk.previousElementSibling;\r\n if (e != null) {\r\n if (e.tagName === 'LABEL') {\r\n label = e;\r\n } else if (text == null && e.tagName === 'SPAN' && e.dataset.lgid != null) {\r\n text = e.innerText;\r\n e.style.display = 'none';\r\n }\r\n }\r\n }\r\n if (label == null) {\r\n label = createElement('label');\r\n chk.parentElement.insertBefore(label, chk);\r\n } else {\r\n text = label.innerText;\r\n }\r\n if (chk.disabled) {\r\n label.className = 'ui-check-wrapper disabled';\r\n } else {\r\n label.className = 'ui-check-wrapper';\r\n }\r\n label.replaceChildren();\r\n fillCheckbox(label, 'fa-regular', text, chk.tabIndex, undefined, label.title);\r\n label.insertBefore(chk, label.firstChild);\r\n }\r\n }\r\n const boxes = container.querySelectorAll('label[data-checkbox]');\r\n for (let box of boxes) {\r\n if (!box.classList.contains('ui-check-wrapper')) {\r\n box.classList.add('ui-check-wrapper');\r\n }\r\n if (box.hasChildNodes()) {\r\n if (!box.classList.contains('ui-check-image-wrapper')) {\r\n box.classList.add('ui-check-image-wrapper');\r\n }\r\n } else {\r\n fillCheckbox(box,\r\n box.dataset.type,\r\n box.dataset.label,\r\n box.dataset.tabIndex,\r\n undefined,\r\n box.title);\r\n box.removeAttribute('title');\r\n box.removeAttribute('data-type');\r\n box.removeAttribute('data-label');\r\n }\r\n const input = createElement('input');\r\n const id = box.dataset.id;\r\n if (id?.length > 0) {\r\n input.id = id;\r\n }\r\n if (box.dataset.checked != null) {\r\n input.checked = true;\r\n }\r\n input.setAttribute('type', 'checkbox');\r\n box.insertBefore(input, box.firstChild);\r\n }\r\n return container;\r\n}","import './css/tooltip.scss';\r\nimport { createElement } from \"../functions\";\r\n// import { global } from \"../utility\";\r\n\r\nconst pointerHeight = 12;\r\n\r\nexport function setTooltip(container, content, flag = false, parent = null) {\r\n const isParent = parent instanceof HTMLElement;\r\n if (isParent) {\r\n const tipid = container.dataset.tipId;\r\n const tip = parent.querySelector(`.ui-tooltip-wrapper[data-tip-id=\"${tipid}\"]`);\r\n tip?.remove();\r\n } else {\r\n const tip = container.querySelector('.ui-tooltip-wrapper');\r\n tip?.remove();\r\n }\r\n const wrapper = createElement('div', wrapper => {\r\n wrapper.className = 'ui-tooltip-wrapper ui-tooltip-color';\r\n // wrapper.style.visibility = 'hidden';\r\n // wrapper.style.opacity = 0;\r\n // wrapper.style.top = '0';\r\n // wrapper.style.left = '0';\r\n wrapper.style.cssText += 'display: none; visibility: hidden; opacity: 0; top: 0; left: 0';\r\n },\r\n createElement('div', 'ui-tooltip-pointer ui-tooltip-color'),\r\n createElement('div', 'ui-tooltip-curtain ui-tooltip-color'),\r\n createElement('div', cnt => {\r\n cnt.className = 'ui-tooltip-content';\r\n if (content instanceof Element) {\r\n cnt.appendChild(content);\r\n } else {\r\n cnt.innerText = content;\r\n }\r\n })\r\n );\r\n // container.insertAdjacentElement('afterend', wrapper);\r\n if (isParent) {\r\n const tipId = String(Math.random()).substring(2);\r\n container.dataset.tipId = tipId;\r\n wrapper.dataset.tipId = tipId;\r\n parent.appendChild(wrapper);\r\n } else {\r\n container.appendChild(wrapper);\r\n }\r\n\r\n let tid;\r\n container.addEventListener('mouseenter', () => {\r\n tid && clearTimeout(tid);\r\n let c = container;\r\n while (c?.offsetWidth == null) {\r\n c = c.parentElement;\r\n }\r\n if (c == null) {\r\n return;\r\n }\r\n if (!flag || c.scrollWidth > c.offsetWidth) {\r\n tid = setTimeout(() => {\r\n let p;\r\n let left;\r\n let top;\r\n left = c.offsetLeft;\r\n top = c.offsetTop;\r\n if (isParent) {\r\n p = c.offsetParent;\r\n while (p != null && p !== parent) {\r\n left += p.offsetLeft;\r\n top += p.offsetTop;\r\n p = p.offsetParent;\r\n }\r\n }\r\n p = c.parentElement;\r\n const offsetParent = isParent ? parent : c.offsetParent;\r\n while (p != null && p !== offsetParent) {\r\n left -= p.scrollLeft;\r\n top -= p.scrollTop;\r\n p = p.parentElement;\r\n }\r\n wrapper.style.display = '';\r\n const offsetHeight = wrapper.offsetHeight;\r\n const offsetWidth = wrapper.offsetWidth;\r\n if (isParent) {\r\n top -= offsetHeight + pointerHeight;\r\n if (top < 0) {\r\n top += c.offsetHeight + offsetHeight + pointerHeight * 2;\r\n wrapper.classList.add('ui-tooltip-down');\r\n }\r\n left += (c.offsetWidth - offsetWidth) / 2;\r\n if (left < 1) {\r\n left = 1;\r\n }\r\n } else {\r\n // check overflow\r\n let t = c.offsetTop;\r\n let l = c.offsetLeft;\r\n p = c.offsetParent;\r\n if (p == null) {\r\n return;\r\n }\r\n let lastWidth = p.clientWidth;\r\n let lastHeight = p.clientHeight;\r\n while (p != null) {\r\n const overflow = window.getComputedStyle(p).overflow;\r\n if (overflow !== 'visible') {\r\n break;\r\n }\r\n t += p.offsetTop;\r\n l += p.offsetLeft;\r\n const parent = p.offsetParent;\r\n while (p != null) {\r\n const w = p.clientWidth;\r\n if (w < lastWidth) {\r\n lastWidth += l;\r\n } else {\r\n lastWidth = p.clientWidth;\r\n }\r\n const h = p.clientHeight;\r\n if (h < lastHeight) {\r\n lastHeight += t;\r\n } else {\r\n lastHeight = p.clientHeight;\r\n }\r\n t -= p.scrollTop;\r\n l -= p.scrollLeft;\r\n if (p === parent) {\r\n break;\r\n }\r\n p = p.parentElement;\r\n }\r\n }\r\n if (t - offsetHeight - pointerHeight < 0) {\r\n const containerOffsetHeight = c.offsetHeight;\r\n if (t + containerOffsetHeight + offsetHeight + pointerHeight > lastHeight) {\r\n top = t + (containerOffsetHeight - offsetHeight) / 2;\r\n if (top + offsetHeight + 1 > lastHeight) {\r\n top = lastHeight - offsetHeight - 1;\r\n }\r\n wrapper.classList.add('ui-tooltip-no');\r\n } else {\r\n top += containerOffsetHeight + pointerHeight;\r\n wrapper.classList.add('ui-tooltip-down');\r\n }\r\n } else {\r\n top -= offsetHeight + pointerHeight;\r\n wrapper.classList.remove('ui-tooltip-down');\r\n }\r\n left += (c.offsetWidth - offsetWidth) / 2;\r\n if (l - offsetWidth < 0) {\r\n left = 1;\r\n } else if (left + offsetWidth + 1 > lastWidth) {\r\n left = lastWidth - offsetWidth - 1;\r\n }\r\n }\r\n // wrapper.style.left = `${left}px`;\r\n // wrapper.style.top = `${top}px`;\r\n // wrapper.style.visibility = 'visible';\r\n // wrapper.style.opacity = 1;\r\n wrapper.style.cssText += `left: ${left}px; top: ${top}px; visibility: visible; opacity: 1`;\r\n }, 100);\r\n }\r\n });\r\n container.addEventListener('mouseleave', () => {\r\n tid && clearTimeout(tid);\r\n tid = setTimeout(() => {\r\n wrapper.style.visibility = 'hidden';\r\n wrapper.style.opacity = 0;\r\n tid = setTimeout(() => wrapper.style.display = 'none', 120);\r\n }, 300);\r\n });\r\n return container;\r\n}\r\n\r\nexport function resolveTooltip(container = document.body) {\r\n const tips = container.querySelectorAll('[title]');\r\n for (let tip of tips) {\r\n const title = tip.getAttribute('title');\r\n if (title != null) {\r\n tip.removeAttribute('title');\r\n setTooltip(tip, title);\r\n }\r\n }\r\n return container;\r\n}","import \"./css/tab.scss\";\r\n\r\n/**\r\n * Tab 页创建参数类\r\n * @typedef TabOption\r\n * @property {HTMLElement} container - 父容器\r\n */\r\n\r\nimport { createElement } from \"../functions\";\r\n\r\n/**\r\n * 创建 Tab 页\r\n * @param {TabOption | HTMLElement} options - 创建选项\r\n */\r\nexport function createTab(options) {\r\n if (options instanceof HTMLElement) {\r\n options = { container: options };\r\n }\r\n let container;\r\n if (options?.container instanceof HTMLElement) {\r\n container = options.container;\r\n if (!container.classList.contains('ui-tab-container')) {\r\n container.classList.add('ui-tab-container');\r\n }\r\n } else {\r\n container = createElement('div', 'ui-tab-container');\r\n }\r\n container.replaceChildren(\r\n createElement('div', header => {\r\n header.className = 'ui-tab-header';\r\n header.addEventListener('click', e => {\r\n const title = e.target;\r\n if (title.classList.contains('ui-tab-title')) {\r\n // title\r\n header.querySelectorAll('.ui-tab-title').forEach(t => t === title ? t.classList.add('selected') : t.classList.remove('selected'));\r\n // pages\r\n const page = title.dataset.for;\r\n container.querySelectorAll('[data-page]').forEach(p => p.style.display = p.dataset.page === page ? 'block' : '');\r\n }\r\n });\r\n })\r\n );\r\n}","function combineUrl(url) {\r\n if (/^(https?|wss?|ftp):/.test(url)) {\r\n return url;\r\n }\r\n if (typeof consts === 'undefined') {\r\n return url;\r\n }\r\n return (consts.path || '') + url;\r\n}\r\n\r\nexport function get(url, options = {}) {\r\n return fetch(combineUrl(url), {\r\n method: options.method || 'GET',\r\n headers: {\r\n ...options.customHeaders,\r\n 'Accept': options.accept ?? 'application/json'\r\n },\r\n mode: options.mode,\r\n signal: options.signal,\r\n cache: 'default'\r\n });\r\n}\r\n\r\nexport function post(url, data, options = {}) {\r\n // let contentType;\r\n if (data instanceof FormData) {\r\n // contentType = 'multipart/form-data';\r\n } else {\r\n if (typeof data !== 'string') {\r\n data = JSON.stringify(data);\r\n }\r\n // contentType = 'application/json';\r\n if (options.customHeaders == null) {\r\n options.customHeaders = {};\r\n }\r\n if (options.customHeaders['Content-Type'] == null) {\r\n options.customHeaders['Content-Type'] = 'application/json';\r\n }\r\n }\r\n return fetch(combineUrl(url), {\r\n method: options.method || 'POST',\r\n headers: options.customHeaders,\r\n body: data,\r\n signal: options.signal,\r\n cache: 'no-cache'\r\n });\r\n}\r\n\r\nexport function upload(url, data, options = {}) {\r\n return new Promise((resolve, reject) => {\r\n const request = new XMLHttpRequest();\r\n request.onreadystatechange = function () {\r\n if (this.readyState === XMLHttpRequest.DONE) {\r\n if (this.status === 200) {\r\n resolve(this);\r\n } else {\r\n reject(`${this.status} ${this.statusText}: ${this.responseText}`);\r\n }\r\n }\r\n };\r\n if (typeof options.progress === 'function') {\r\n request.upload.addEventListener('progress', function (ev) {\r\n if (ev.lengthComputable) {\r\n options.progress.call(this, ev);\r\n }\r\n }, false);\r\n }\r\n request.open('POST', combineUrl(url));\r\n if (options.customHeaders != null) {\r\n for (let header of Object.entries(options.customHeaders)) {\r\n request.setRequestHeader(header[0], header[1]);\r\n }\r\n }\r\n request.send(data);\r\n });\r\n}","export function nullOrEmpty(s) {\r\n return s == null || typeof s !== 'string' || s.length === 0;\r\n}\r\n\r\nexport function contains(s, key, ignoreCase) {\r\n if (nullOrEmpty(s) || key == null) {\r\n return false;\r\n }\r\n if (typeof key !== 'string') {\r\n key = String(key);\r\n }\r\n if (ignoreCase) {\r\n return s.toLowerCase().includes(key.toLowerCase());\r\n }\r\n return s.includes(key);\r\n}\r\n\r\nexport function endsWith(s, suffix) {\r\n if (nullOrEmpty(s) || nullOrEmpty(suffix)) {\r\n return false;\r\n }\r\n return s.endsWith(suffix); // === s.length - suffix.length;\r\n}\r\n\r\nexport function padStart(s, num, char) {\r\n if (nullOrEmpty(s) || isNaN(num) || num <= s.length) {\r\n return s;\r\n }\r\n return (char ?? ' ').repeat(num - s.length);\r\n}\r\n\r\nexport function formatUrl(msg) {\r\n //const urlReg = /(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?/ig;\r\n //const urlArrray = str.match(urlReg);\r\n const p = /(http|ftp|https):\\/\\/.+?(\\s|\\r\\n|\\r|\\n|\\\"|\\'|\\*|$)/g;\r\n const r = msg.match(p);\r\n msg = escapeHtml(msg);\r\n\r\n if (r?.length > 0) {\r\n const rs = [];\r\n for (let t of r) {\r\n t = t.replace(/[\"'\\r\\n ]/g, '');\r\n if (rs.indexOf(t) < 0) {\r\n rs.push(t);\r\n }\r\n }\r\n\r\n let path;\r\n if (typeof consts !== 'undefined') {\r\n path = consts.path;\r\n } else if (typeof _network !== 'undefined') {\r\n path = _network.root;\r\n } else if (typeof _net !== 'undefined') {\r\n path = _net.root;\r\n }\r\n for (let r of rs) {\r\n msg = msg.replaceAll(r, ``);\r\n }\r\n }\r\n\r\n return msg;\r\n}\r\n\r\nexport function escapeHtml(text) {\r\n if (text == null) {\r\n return '';\r\n }\r\n return String(text)\r\n .replaceAll('&', '&')\r\n .replaceAll('<', '<')\r\n .replaceAll('>', '>')\r\n .replaceAll('\\r\\n', '
')\r\n .replaceAll('\\n', '
')\r\n .replaceAll(' ', ' ');\r\n}\r\n\r\nexport function escapeEmoji(text) {\r\n if (text == null) {\r\n return '';\r\n }\r\n if (typeof text !== 'string') {\r\n text = String(text);\r\n }\r\n return text\r\n .replace(/(=[A-Fa-f0-9]{2}){4}/g, s => decodeURIComponent(s.replaceAll('=', '%')))\r\n .replace(/([0-9a-fA-F]{2,6});/g, (_, h) => String.fromCodePoint(parseInt(h, 16)));\r\n}","import { getCookie } from \"./cookie\";\r\nimport { get } from \"./request\";\r\nimport { nullOrEmpty } from \"./strings\";\r\n\r\nlet cache;\r\n\r\nfunction getCurrentLgId() {\r\n let lgid;\r\n if (typeof consts !== 'undefined') {\r\n lgid = getCookie(consts.cookie?.lang);\r\n if (nullOrEmpty(lgid)) {\r\n lgid = consts.user?.language;\r\n }\r\n }\r\n if (nullOrEmpty(lgid)) {\r\n lgid = getCookie('lgid');\r\n }\r\n if (nullOrEmpty(lgid)) {\r\n lgid = navigator.language || 'en-us';\r\n }\r\n lgid = lgid.toLowerCase().replace(/-/g, '_');\r\n if (nullOrEmpty(lgid)) {\r\n lgid = 'en';\r\n }\r\n switch (lgid) {\r\n case 'en':\r\n case 'en_au':\r\n case 'fr':\r\n case 'zh_cn':\r\n return lgid;\r\n }\r\n const lang = lgid.split('_')[0];\r\n switch (lang) {\r\n case 'en':\r\n case 'fr':\r\n return lang;\r\n }\r\n return 'en';\r\n}\r\n\r\nfunction getStorageKey(lgid) {\r\n if (typeof consts !== 'undefined') {\r\n return (consts.prefix || '') + `res_${lgid}`;\r\n }\r\n return `res_${lgid}`;\r\n}\r\n\r\nasync function doRefreshLgres(template = '') {\r\n const lgid = getCurrentLgId();\r\n const url = template.length > 0 ? template.replace('{lgid}', lgid) : `language/${lgid}`;\r\n const r = await get(url);\r\n const dict = await r.json();\r\n localStorage.setItem(getStorageKey(lgid), JSON.stringify(dict));\r\n return dict;\r\n}\r\n\r\nasync function refreshLgres(template, lgres) {\r\n if (lgres == null || typeof consts === 'undefined') {\r\n lgres = await doRefreshLgres(template);\r\n }\r\n const ver = Number(consts.resver);\r\n if (isNaN(lgres.ver) || isNaN(ver) || ver > lgres.ver) {\r\n console.log(`found new language res version: ${lgres.ver} => ${ver}`);\r\n lgres = await doRefreshLgres(template);\r\n }\r\n Object.defineProperty(lgres, 'r', {\r\n writable: false,\r\n configurable: false,\r\n enumerable: false,\r\n value: function (key, defaultValue) {\r\n return getLanguage(this, key, defaultValue);\r\n }\r\n });\r\n cache = lgres;\r\n return lgres;\r\n}\r\n\r\nfunction getLanguage(lgres, key, defaultValue) {\r\n let value = lgres[key];\r\n return value ?? defaultValue;\r\n}\r\n\r\nfunction applyLanguage(dom, result) {\r\n for (let text of dom.querySelectorAll('[data-lgid]')) {\r\n const key = text.dataset.lgid;\r\n if (text.tagName === 'INPUT') {\r\n text.value = getLanguage(result, key, text.value);\r\n } else {\r\n text.innerText = getLanguage(result, key, text.innerText);\r\n }\r\n }\r\n for (let title of dom.querySelectorAll('[data-title-lgid]')) {\r\n const key = title.dataset.titleLgid;\r\n title.setAttribute('title', getLanguage(result, key, title.getAttribute('title')));\r\n }\r\n for (let holder of dom.querySelectorAll('[data-placeholder-lgid]')) {\r\n const key = holder.dataset.placeholderLgid;\r\n holder.setAttribute('placeholder', getLanguage(result, key, holder.getAttribute('placeholder')));\r\n }\r\n}\r\n\r\nexport async function init(dom = document.body, options = {}) {\r\n const lgid = getCurrentLgId();\r\n let lgres = localStorage.getItem(getStorageKey(lgid));\r\n let result;\r\n if (lgres != null) {\r\n try {\r\n lgres = JSON.parse(lgres);\r\n result = await refreshLgres(options.template, lgres);\r\n } catch (e) {\r\n console.error('error while parsing lgres, try refresh ...', e);\r\n result = await refreshLgres(options.template);\r\n }\r\n } else {\r\n result = await refreshLgres(options.template);\r\n }\r\n\r\n try {\r\n if (document.readyState === 'loading') {\r\n return await new Promise((resolve, reject) => {\r\n let tid = setTimeout(() => reject('timeout'), 30000);\r\n document.addEventListener('DOMContentLoaded', () => {\r\n clearTimeout(tid);\r\n tid = void 0;\r\n if (typeof options.callback === 'function') {\r\n options.callback(result);\r\n }\r\n applyLanguage(dom, result);\r\n resolve(result);\r\n });\r\n });\r\n }\r\n if (typeof options.callback === 'function') {\r\n options.callback(result);\r\n }\r\n applyLanguage(dom, result);\r\n return result;\r\n } catch (err) {\r\n console.error('error while loading language res ...', err);\r\n }\r\n}\r\n\r\nexport function r(key, defaultValue) {\r\n if (cache != null) {\r\n return getLanguage(cache, key, defaultValue);\r\n }\r\n return defaultValue;\r\n}\r\n\r\nexport const lang = {\r\n get current() {\r\n return getCurrentLgId();\r\n },\r\n get unknownError() {\r\n return r('unknownError', 'An unknown error occurred, please contact the administrator.');\r\n },\r\n get savedSuccessfully() {\r\n return r('savedSuccessfully', 'Saved successfully.');\r\n }\r\n}","import { getCookie, setCookie, deleteCookie } from \"./utility/cookie\";\r\nimport { init, r, lang } from \"./utility/lgres\";\r\nimport { get, post, upload } from \"./utility/request\";\r\nimport { nullOrEmpty, contains, endsWith, padStart, formatUrl, escapeHtml, escapeEmoji } from \"./utility/strings\";\r\n\r\nlet g = typeof globalThis !== 'undefined' ? globalThis : self;\r\n\r\nfunction isPositive(n) {\r\n return !isNaN(n) && n > 0;\r\n}\r\n\r\nfunction isMobile() {\r\n return /mobile/i.test(navigator.userAgent);\r\n}\r\n\r\nfunction throttle(method, delay = 100, context = g, ...args) {\r\n if (method == null) {\r\n return;\r\n }\r\n method.tiid && clearTimeout(method.tiid);\r\n const current = new Date();\r\n if (method.tdate == null || current - method.tdate > delay) {\r\n method.apply(context, args);\r\n method.tdate = current;\r\n } else {\r\n method.tiid = setTimeout(() => method.apply(context, args), delay);\r\n }\r\n}\r\n\r\nfunction debounce(method, delay = 100, context = g, ...args) {\r\n if (method == null) {\r\n return;\r\n }\r\n method.tiid && clearTimeout(method.tiid);\r\n method.tiid = setTimeout(() => method.apply(context, args), delay);\r\n}\r\n\r\nfunction truncate(v) {\r\n return (v > 0 ? Math.floor : Math.ceil)(v);\r\n}\r\n\r\nfunction isEmail(text) {\r\n return /^\\w[-\\w.+]*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/.test(text);\r\n}\r\n\r\nfunction isPhone(text) {\r\n if (/^[1-9]\\d{9,}$/.test(text)) {\r\n return true;\r\n }\r\n if (/^\\+?[1-9][\\d-]{9,}\\d$/.test(text) && /^[1-9]\\d{9,}$/.test(text.replace('+', '').replace(new RegExp('-', 'g'), ''))) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport {\r\n // cookie\r\n getCookie,\r\n setCookie,\r\n deleteCookie,\r\n // lgres\r\n init,\r\n r,\r\n lang,\r\n // request\r\n get,\r\n post,\r\n upload,\r\n // strings\r\n nullOrEmpty,\r\n contains,\r\n endsWith,\r\n padStart,\r\n formatUrl,\r\n escapeHtml,\r\n escapeEmoji,\r\n // variables\r\n g as global,\r\n isPositive,\r\n isMobile,\r\n // functions\r\n throttle,\r\n debounce,\r\n truncate,\r\n isEmail,\r\n isPhone\r\n}","// import { r, global, contains, isPositive, nullOrEmpty } from \"../utility\";\r\nimport './css/dropdown.scss';\r\nimport { r } from \"../utility/lgres\";\r\nimport { contains, nullOrEmpty } from \"../utility/strings\";\r\nimport { global, isPositive } from \"../utility\";\r\nimport { createElement } from \"../functions\";\r\nimport { createCheckbox } from \"./checkbox\";\r\nimport { createIcon } from \"./icon\"\r\n\r\nconst SymbolDropdown = Symbol.for('ui-dropdown');\r\nconst DropdownItemHeight = 30;\r\n\r\nlet dropdownGlobal = global[SymbolDropdown];\r\n\r\nif (dropdownGlobal == null) {\r\n // init\r\n dropdownGlobal = {};\r\n Object.defineProperty(dropdownGlobal, 'clear', {\r\n writable: false,\r\n configurable: false,\r\n enumerable: false,\r\n value: function () {\r\n const panels = document.querySelectorAll('.ui-drop-box.active');\r\n for (let panel of [...panels]) {\r\n if (panel == null) {\r\n continue;\r\n }\r\n panel.classList.remove('active');\r\n const dropId = panel.parentElement.dataset.dropId;\r\n if (dropId == null) {\r\n continue;\r\n }\r\n const dropdown = this[dropId];\r\n if (dropdown?.multiSelect && typeof dropdown.onCollapsed === 'function') {\r\n dropdown.onCollapsed();\r\n }\r\n }\r\n }\r\n })\r\n global[SymbolDropdown] = dropdownGlobal;\r\n\r\n document.addEventListener('mousedown', e => {\r\n let parent = e.target;\r\n while (parent != null) {\r\n if (parent.classList.contains('ui-drop-box')) {\r\n e.stopPropagation();\r\n return;\r\n }\r\n parent = parent.parentElement;\r\n }\r\n dropdownGlobal.clear();\r\n });\r\n}\r\n\r\nfunction selectItems(label, itemlist, htmlkey, textkey) {\r\n const htmls = itemlist.map(it => it[htmlkey]);\r\n if (htmls.some(it => it instanceof HTMLElement)) {\r\n label.replaceChildren(...htmls.filter(it => it != null).map(it => it.cloneNode(true)));\r\n } else {\r\n let text = itemlist.map(it => it[textkey]).join(', ');\r\n if (nullOrEmpty(text)) {\r\n text = r('noneItem', '( None )');\r\n }\r\n label.innerText = text;\r\n }\r\n}\r\n\r\nfunction filterSource(searchkeys, textkey, key, source) {\r\n if (!Array.isArray(searchkeys) || searchkeys.length === 0) {\r\n searchkeys = [textkey];\r\n }\r\n if (key.length > 0) {\r\n source = source.filter(it => {\r\n for (let k of searchkeys) {\r\n if (contains(it[k].toLowerCase(), key)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n }\r\n return source;\r\n}\r\n\r\n/**\r\n * 下拉列表参数对象\r\n * @typedef DropdownOptions\r\n * @property {string} [textKey=text] - 文本关键字\r\n * @property {string} [valueKey=value] - 值关键字\r\n * @property {string} [htmlKey=html] - 源码显示的关键字\r\n * @property {number} [maxLength=500] - 最大输入长度\r\n * @property {boolean} [multiSelect] - 是否允许多选\r\n * @property {string} [selected] - 选中值\r\n * @property {string[]} [selectedList] - 选中的数组\r\n * @property {boolean} [disabled] - 是否禁用\r\n * @property {boolean} [input] - 是否支持输入\r\n * @property {boolean} [search] - 是否支持搜索\r\n * @property {string[]} [searchKeys] - 搜索的关键字数组\r\n * @property {string} [searchPlaceholder] - 搜索提示文本,默认值取语言资源 `searchHolder` \"Search...\"\r\n * @property {number} [tabIndex] - 焦点索引\r\n * @property {string} [placeholder] - 输入框的提示文本\r\n * @property {boolean} [slideFixed] - 是否固定为向下展开\r\n * @property {HTMLElement} [wrapper] - 父元素,默认添加到头元素之后\r\n */\r\n\r\nexport class Dropdown {\r\n _var = {};\r\n // _var.options;\r\n\r\n // _var.wrapper;\r\n // _var.container;\r\n // _var.label;\r\n\r\n // _var.allChecked;\r\n // _var.source;\r\n // _var.lastSelected;\r\n // _var.selected;\r\n // _var.selectedList;\r\n\r\n sourceFilter;\r\n onSelectedList;\r\n onSelected;\r\n onExpanded;\r\n onCollapsed;\r\n\r\n constructor(options = {}) {\r\n options.searchPlaceholder ??= r('searchHolder', 'Search...');\r\n options.textKey ??= 'text';\r\n options.valueKey ??= 'value';\r\n options.htmlKey ??= 'html';\r\n options.maxLength ??= 500;\r\n this._var.options = options;\r\n }\r\n\r\n create() {\r\n const options = this._var.options;\r\n\r\n // wrapper\r\n const wrapper = createElement('div', 'ui-drop-wrapper');\r\n const dropId = String(Math.random()).substring(2);\r\n wrapper.dataset.dropId = dropId;\r\n dropdownGlobal[dropId] = this;\r\n this._var.wrapper = wrapper;\r\n\r\n // header\r\n const header = createElement('div', 'ui-drop-header');\r\n header.addEventListener('keypress', e => {\r\n if (e.key === ' ' || e.key === 'Enter') {\r\n header.dispatchEvent(new MouseEvent('click'));\r\n }\r\n });\r\n header.addEventListener('keydown', e => {\r\n const up = e.key === 'ArrowUp';\r\n const down = e.key === 'ArrowDown';\r\n if (up || down) {\r\n const source = this.source;\r\n const count = source.length;\r\n const valuekey = this._var.options.valueKey;\r\n let index = source?.indexOf(this._var.selected);\r\n if (isNaN(index) || index < -1) {\r\n index = -1;\r\n } else if (index >= count) {\r\n index = count - 1;\r\n }\r\n if (up) {\r\n if (index > 0) {\r\n index--;\r\n } else {\r\n index = 0;\r\n }\r\n } else if (down) {\r\n if (index < 0) {\r\n index = 0;\r\n } else if (index < count) {\r\n index++;\r\n } else {\r\n index = count - 1;\r\n }\r\n }\r\n const target = source[index]?.[valuekey];\r\n if (target != null) {\r\n this.select(target);\r\n }\r\n } else if (e.key === 'Tab') {\r\n this._dropdown(false);\r\n }\r\n });\r\n header.addEventListener('click', () => {\r\n if (this.disabled) {\r\n return;\r\n }\r\n const active = this._expanded;\r\n const label = this._var.label;\r\n if (active && label.ownerDocument.activeElement === label) {\r\n return;\r\n }\r\n this._dropdown(!active);\r\n if (!active && typeof this.onExpanded === 'function') {\r\n setTimeout(() => this.onExpanded(), 120);\r\n }\r\n });\r\n\r\n // label or input\r\n let label;\r\n if (options.input) {\r\n label = createElement('input', 'ui-drop-text');\r\n label.setAttribute('type', 'text');\r\n options.placeholder && label.setAttribute('placeholder', options.placeholder);\r\n isPositive(options.maxLength) && label.setAttribute('maxlength', options.maxLength);\r\n isPositive(options.tabIndex) && label.setAttribute('tabindex', options.tabIndex);\r\n label.addEventListener('input', e => {\r\n const key = e.target.value.toLowerCase();\r\n const source = filterSource(options.searchKeys, options.textKey, key, this.source);\r\n this._filllist(source);\r\n this._var.container.classList.add('active');\r\n });\r\n label.addEventListener('blur', e => this.select(e.target.value));\r\n label.addEventListener('mousedown', e => this._expanded && e.stopPropagation());\r\n } else {\r\n isPositive(options.tabIndex) && header.setAttribute('tabindex', options.tabIndex);\r\n label = createElement('label', 'ui-drop-text');\r\n }\r\n this._var.label = label;\r\n if (options.multiSelect) {\r\n if (Array.isArray(options.selectedList)) {\r\n this.selectlist(options.selectedList, true);\r\n } else {\r\n this._var.allChecked = true;\r\n label.innerText = r('allItem', '( All )');\r\n }\r\n } else if (options.selected != null) {\r\n this.select(options.selected, true);\r\n }\r\n header.append(label, createElement('label', 'ui-drop-caret'));\r\n wrapper.appendChild(header);\r\n\r\n this.disabled = options.disabled || false;\r\n return wrapper;\r\n }\r\n\r\n get multiSelect() { return this._var.options.multiSelect }\r\n\r\n get disabled() { return this._var.wrapper == null || this._var.wrapper.querySelector('.ui-drop-header.disabled') != null }\r\n\r\n set disabled(flag) {\r\n if (this._var.wrapper == null) {\r\n return;\r\n }\r\n if (flag) {\r\n this._var.wrapper.querySelector('.ui-drop-header').classList.add('disabled');\r\n } else {\r\n this._var.wrapper.querySelector('.ui-drop-header').classList.remove('disabled');\r\n }\r\n }\r\n\r\n get source() {\r\n let source = this._var.source;\r\n if (source == null || !Array.isArray(source)) {\r\n if (typeof this.sourceFilter === 'function') {\r\n source = this.sourceFilter();\r\n }\r\n if (!Array.isArray(source)) {\r\n source = [];\r\n }\r\n this._var.source = source;\r\n }\r\n return source;\r\n }\r\n\r\n set source(list) {\r\n if (!Array.isArray(list)) {\r\n return;\r\n }\r\n this._var.source = list;\r\n if (this._expanded) {\r\n setTimeout(() => this._dropdown(), 120);\r\n }\r\n }\r\n\r\n get selected() { return this._var.selected }\r\n\r\n get selectedList() { return this._var.selectedList || [] }\r\n\r\n select(selected, silence) {\r\n if (typeof selected !== 'string') {\r\n selected = String(selected);\r\n }\r\n if (this._var.lastSelected === selected) {\r\n return false;\r\n }\r\n this._var.lastSelected = selected;\r\n const valuekey = this._var.options.valueKey;\r\n const textkey = this._var.options.textKey;\r\n const htmlkey = this._var.options.htmlKey;\r\n let item = this.source.find(it => String(it[valuekey]) === selected);\r\n if (this._var.options.input) {\r\n if (item == null) {\r\n item = { [valuekey]: selected };\r\n }\r\n this._var.label.value = selected;\r\n } else {\r\n const expanded = this._expanded;\r\n if (expanded) {\r\n this._var.container.querySelectorAll('li[data-value].selected').forEach(li => li.classList.remove('selected'));\r\n }\r\n if (item == null) {\r\n this._var.selected = null;\r\n this._var.label.innerText = ' ';\r\n return false;\r\n }\r\n const html = item[htmlkey];\r\n if (html instanceof HTMLElement) {\r\n this._var.label.replaceChildren(html.cloneNode(true));\r\n } else if (typeof html === 'string') {\r\n this._var.label.innerHTML = html;\r\n } else {\r\n let text = item[textkey];\r\n if (nullOrEmpty(text)) {\r\n text = ' ';\r\n }\r\n this._var.label.innerText = text;\r\n }\r\n if (expanded) {\r\n for (let li of this._var.container.querySelectorAll('li[data-value]')) {\r\n if (li.dataset.value === selected) {\r\n li.classList.add('selected');\r\n break;\r\n }\r\n }\r\n // const val = selected.replace(/\"/g, '\\\\\"');\r\n // const li = this._var.container.querySelector(`li[data-value=\"${val}\"]`);\r\n // if (li != null) {\r\n // li.classList.add('selected');\r\n // }\r\n }\r\n }\r\n this._var.selected = item;\r\n if (!silence && typeof this.onSelected === 'function') {\r\n this.onSelected(item);\r\n }\r\n }\r\n\r\n selectlist(selectedlist, silence) {\r\n const source = this.source;\r\n const valuekey = this._var.options.valueKey;\r\n const textkey = this._var.options.textKey;\r\n const htmlkey = this._var.options.htmlKey;\r\n const itemlist = selectedlist.map(a => {\r\n const v = typeof a === 'string' ? a : String(a);\r\n let item = source.find(it => String(it[valuekey]) === v);\r\n if (item == null) {\r\n item = {\r\n [valuekey]: v,\r\n [textkey]: v\r\n };\r\n }\r\n return item;\r\n });\r\n if (itemlist.length === 0) {\r\n this._var.selectedList = null;\r\n this._var.label.innerText = none;\r\n return false;\r\n }\r\n selectItems(this._var.label, itemlist, htmlkey, textkey);\r\n this._var.selectedList = itemlist;\r\n if (!silence && typeof this.onSelectedList === 'function') {\r\n this.onSelectedList(itemlist);\r\n }\r\n }\r\n\r\n get _expanded() { return this._var.container?.classList?.contains('active') }\r\n\r\n _dropdown(flag = true) {\r\n const options = this._var.options;\r\n let panel = this._var.container;\r\n if (panel == null) {\r\n panel = createElement('div', 'ui-drop-box');\r\n // search box\r\n if (!options.input && options.search) {\r\n const search = createElement('div', 'ui-drop-search');\r\n const input = createElement('input');\r\n input.setAttribute('type', 'text');\r\n isPositive(options.tabIndex) && input.setAttribute('tabindex', options.tabIndex);\r\n !nullOrEmpty(options.searchPlaceholder) && input.setAttribute('placeholder', options.searchPlaceholder);\r\n input.addEventListener('input', e => {\r\n const key = e.target.value.toLowerCase();\r\n const source = filterSource(options.searchKeys, options.textKey, key, this.source);\r\n this._filllist(source);\r\n })\r\n search.append(input, createIcon('fa-light', 'search'));\r\n panel.appendChild(search);\r\n }\r\n // list\r\n const list = createElement('ul', 'ui-drop-list');\r\n if (!this.multiSelect) {\r\n list.addEventListener('click', e => {\r\n let li = e.target;\r\n while (li.tagName !== 'LI') {\r\n li = li.parentElement;\r\n if (li == null) {\r\n return;\r\n }\r\n }\r\n const value = li.dataset.value;\r\n if (this.select(value) !== false) {\r\n dropdownGlobal.clear();\r\n }\r\n });\r\n }\r\n panel.appendChild(list);\r\n this._var.container = panel;\r\n if (options.wrapper instanceof HTMLElement) {\r\n options.wrapper.appendChild(panel);\r\n } else {\r\n this._var.wrapper.appendChild(panel);\r\n }\r\n }\r\n if (flag) {\r\n let source = this.source;\r\n if (!options.input && options.search) {\r\n const search = panel.querySelector('.ui-drop-search > input');\r\n if (!nullOrEmpty(search?.value)) {\r\n source = filterSource(options.searchKeys, options.textKey, search.value, source);\r\n }\r\n }\r\n this._filllist(source);\r\n // slide direction\r\n if (!options.slideFixed) {\r\n const parent = options.wrapper ?? document.body;\r\n let p = this._var.wrapper;\r\n panel.style.minWidth = `${p.offsetWidth}px`;\r\n const headerHeight = p.offsetHeight;\r\n let top = p.offsetTop + headerHeight;\r\n let left = p.offsetLeft;\r\n if (p !== parent) {\r\n while ((p = p.parentElement) != null && p !== parent) {\r\n top -= p.scrollTop;\r\n left -= p.scrollLeft;\r\n }\r\n }\r\n p = this._var.wrapper;\r\n if (p !== parent) {\r\n while ((p = p.offsetParent) != null && p !== parent) {\r\n top += p.offsetTop;\r\n left += p.offsetLeft;\r\n }\r\n }\r\n const slideUp = top - parent.scrollTop + panel.offsetHeight >= parent.offsetHeight;\r\n if (options.wrapper instanceof HTMLElement) {\r\n if (slideUp) {\r\n panel.style.top = '';\r\n panel.style.bottom = `${parent.offsetHeight - top + headerHeight - 4}px`;\r\n } else {\r\n panel.style.top = `${top}px`;\r\n panel.style.bottom = '';\r\n }\r\n panel.style.left = `${left}px`;\r\n }\r\n if (slideUp) {\r\n panel.classList.add('slide-up');\r\n } else {\r\n panel.classList.remove('slide-up');\r\n }\r\n }\r\n panel.classList.add('active');\r\n } else {\r\n panel.classList.remove('active');\r\n }\r\n }\r\n\r\n _filllist(source) {\r\n const list = this._var.container.querySelector('.ui-drop-list');\r\n list.replaceChildren();\r\n const multiselect = this.multiSelect;\r\n const allchecked = this._var.allChecked;\r\n if (multiselect) {\r\n list.appendChild(\r\n createElement('li', null,\r\n createCheckbox({\r\n label: r('allItem', '( All )'),\r\n checked: allchecked,\r\n customAttributes: { 'isall': '1' },\r\n onchange: e => this._triggerselect(e.target)\r\n })\r\n )\r\n );\r\n }\r\n // TODO: virtual mode\r\n const valuekey = this._var.options.valueKey;\r\n const textkey = this._var.options.textKey;\r\n const htmlkey = this._var.options.htmlKey;\r\n const selected = this.selected;\r\n const selectedlist = this.selectedList;\r\n let scrolled;\r\n source.slice(0, 200).forEach((item, i) => {\r\n let val = item[valuekey];\r\n if (typeof val !== 'string') {\r\n val = String(val);\r\n }\r\n const li = createElement('li');\r\n li.dataset.value = val;\r\n li.setAttribute('title', item[textkey]);\r\n let label;\r\n const html = item[htmlkey];\r\n if (html instanceof HTMLElement) {\r\n label = html;\r\n } else if (typeof html === 'string') {\r\n label = createElement('span');\r\n label.innerHTML = html;\r\n }\r\n if (multiselect) {\r\n const selected = selectedlist.some(s => String(s[valuekey]) === val);\r\n if (label == null) {\r\n label = createElement('span');\r\n label.innerText = item[textkey];\r\n }\r\n const box = createCheckbox({\r\n label,\r\n checked: allchecked || selected,\r\n customAttributes: {\r\n 'class': 'dataitem',\r\n 'data-value': val\r\n },\r\n onchange: e => this._triggerselect(e.target)\r\n });\r\n li.appendChild(box);\r\n } else {\r\n if (label == null) {\r\n li.innerText = item[textkey];\r\n } else {\r\n li.appendChild(label);\r\n }\r\n if (selected != null && String(selected[valuekey]) === val) {\r\n scrolled = DropdownItemHeight * i;\r\n li.classList.add('selected');\r\n }\r\n }\r\n list.appendChild(li);\r\n });\r\n if (scrolled != null) {\r\n setTimeout(() => list.scrollTop = scrolled, 10);\r\n }\r\n }\r\n\r\n _triggerselect(checkbox) {\r\n let list;\r\n const valuekey = this._var.options.valueKey;\r\n const textkey = this._var.options.textKey;\r\n const htmlkey = this._var.options.htmlKey;\r\n if (checkbox.getAttribute('isall') === '1') {\r\n const allchecked = this._var.allChecked = checkbox.checked;\r\n const boxes = this._var.container.querySelectorAll('input.dataitem');\r\n boxes.forEach(box => box.checked = allchecked);\r\n list = [];\r\n } else if (checkbox.checked) {\r\n if (this._var.container.querySelectorAll('input.dataitem:not(:checked)').length === 0) {\r\n this._var.allChecked = true;\r\n this._var.container.querySelector('input[isall=\"1\"]').checked = true;\r\n list = [];\r\n } else {\r\n const source = this.source;\r\n list = [...this._var.container.querySelectorAll('input.dataitem:checked')]\r\n .map(c => {\r\n const v = c.dataset.value;\r\n return source.find(it => String(it[valuekey]) === v);\r\n })\r\n .filter(it => it != null);\r\n }\r\n } else {\r\n const val = checkbox.dataset.value;\r\n if (this._var.allChecked) {\r\n this._var.allChecked = false;\r\n this._var.container.querySelector('input[isall=\"1\"]').checked = false;\r\n list = this.source.filter(it => String(it[valuekey]) !== val);\r\n } else {\r\n list = this.selectedList.filter(it => String(it[valuekey]) !== val);\r\n }\r\n }\r\n if (this._var.allChecked) {\r\n this._var.label.innerText = r('allItem', '( All )');\r\n } else {\r\n selectItems(this._var.label, list, htmlkey, textkey);\r\n }\r\n this._var.selectedList = list;\r\n if (typeof this.onSelectedList === 'function') {\r\n this.onSelectedList(itemlist);\r\n }\r\n }\r\n\r\n static resolve(dom = document.body, trigger) {\r\n const selects = dom.querySelectorAll('select');\r\n for (let sel of selects) {\r\n const source = [...sel.children].map(it => {\r\n return { value: it.value, text: it.innerText }\r\n });\r\n const drop = new Dropdown({\r\n selected: sel.value,\r\n disabled: sel.disabled,\r\n tabIndex: sel.tabIndex\r\n });\r\n drop.source = source;\r\n if (typeof trigger === 'function') {\r\n drop.onSelected = item => trigger.call(drop, item);\r\n }\r\n sel.parentElement.replaceChild(drop.create(), sel);\r\n }\r\n return dom;\r\n }\r\n}","import \"./css/popup.scss\";\r\nimport { r } from \"../utility/lgres\";\r\nimport { nullOrEmpty } from \"../utility/strings\";\r\nimport { global } from \"../utility\";\r\nimport { createElement } from \"../functions\";\r\nimport { createIcon, changeIcon } from \"./icon\";\r\n\r\nconst ResizeMods = {\r\n right: 1,\r\n bottom: 2,\r\n left: 4,\r\n top: 8,\r\n bottomRight: 2 | 1,\r\n bottomLeft: 2 | 4,\r\n topRight: 8 | 1,\r\n topLeft: 8 | 4\r\n}\r\n\r\n// const Cursors = {\r\n// [ResizeMods.right]: 'ew-resize',\r\n// [ResizeMods.bottom]: 'ns-resize',\r\n// [ResizeMods.bottomRight]: 'nwse-resize',\r\n// [ResizeMods.left]: 'ew-resize',\r\n// [ResizeMods.bottomLeft]: 'nesw-resize',\r\n// [ResizeMods.top]: 'ns-resize',\r\n// [ResizeMods.topRight]: 'nesw-resize',\r\n// [ResizeMods.topLeft]: 'nwse-resize'\r\n// }\r\n\r\nfunction trimPx(px) {\r\n if (typeof px !== 'string') {\r\n return px;\r\n }\r\n if (px.endsWith('px')) {\r\n const size = Number(px.substring(0, px.length - 2));\r\n return isNaN(size) ? px : size;\r\n }\r\n return px;\r\n}\r\n\r\nexport class Popup {\r\n _var = {};\r\n // _var.mask;\r\n // _var.option;\r\n // _var.bounds;\r\n // _var.cursor;\r\n\r\n constructor(opts = {}) {\r\n this._var.option = opts;\r\n }\r\n\r\n get container() { return this._var.mask.querySelector('.ui-popup-container') }\r\n\r\n get rect() {\r\n const container = this.container;\r\n if (container == null) {\r\n return null;\r\n }\r\n const style = global.getComputedStyle(container);\r\n const collapsed = container.classList.contains('ui-popup-collapse');\r\n const bounds = this._var.bounds;\r\n return {\r\n collapsed,\r\n left: trimPx(style.left),\r\n top: trimPx(style.top),\r\n width: collapsed === true && bounds != null ? bounds.width : trimPx(style.width),\r\n height: collapsed === true && bounds != null ? bounds.height : trimPx(style.height)\r\n };\r\n }\r\n set rect(r) {\r\n const container = this.container;\r\n if (container == null) {\r\n return;\r\n }\r\n const css = [];\r\n if (!isNaN(r.left)) {\r\n css.push(`left: ${r.left}px`);\r\n }\r\n if (!isNaN(r.top)) {\r\n css.push(`top: ${r.top}px`);\r\n }\r\n const collapse = container.querySelector('.ui-popup-header-icons>.icon-expand');\r\n if (r.collapsed === true) {\r\n css.push('width: 160px', 'height: 40px');\r\n this._var.bounds = r;\r\n container.classList.add('ui-popup-collapse');\r\n if (collapse != null) {\r\n changeIcon(collapse, 'fa-regular', 'expand-alt');\r\n }\r\n } else {\r\n if (!isNaN(r.width) && r.width > 0) {\r\n css.push(`width: ${r.width}px`);\r\n }\r\n if (!isNaN(r.height) && r.height > 0) {\r\n css.push(`height: ${r.height}px`);\r\n }\r\n container.classList.remove('ui-popup-collapse');\r\n this._var.bounds = null;\r\n if (collapse != null) {\r\n changeIcon(collapse, 'fa-regular', 'compress-alt');\r\n }\r\n }\r\n if (css.length > 0) {\r\n container.style.cssText += css.join('; ');\r\n }\r\n }\r\n\r\n close(animation = true) {\r\n const mask = this._var.mask;\r\n if (animation) {\r\n mask.classList.add('ui-popup-active');\r\n mask.style.opacity = 0;\r\n setTimeout(() => { mask.remove(); }, 120);\r\n } else {\r\n mask.remove();\r\n }\r\n if (typeof this._var.option.onMasking === 'function') {\r\n this._var.option.onMasking.call(this, false);\r\n }\r\n if (typeof this._var.option.resolve === 'function') {\r\n this._var.option.resolve();\r\n }\r\n }\r\n\r\n create() {\r\n const mask = createElement('div', 'ui-popup-mask');\r\n const option = this._var.option;\r\n if (option.mask === false) {\r\n mask.classList.add('ui-popup-transparent');\r\n } else if (typeof option.onMasking === 'function') {\r\n option.onMasking.call(this, true);\r\n }\r\n if (!isNaN(option.zIndex)) {\r\n mask.style.zIndex = String(option.zIndex);\r\n }\r\n const container = createElement('div', 'ui-popup-container');\r\n if (option.changeZIndex === true) {\r\n container.addEventListener('mousedown', () => {\r\n const masks = [...this._var.mask.parentElement.children].filter(e => e.classList.contains('ui-popup-mask'));\r\n let max = 200;\r\n masks.forEach(m => {\r\n let index;\r\n if (m.dataset.zindex != null) {\r\n index = parseInt(m.dataset.zindex);\r\n m.style.zIndex = isNaN(index) ? '' : String(index);\r\n delete m.dataset.zindex;\r\n } else {\r\n index = parseInt(m.style.zIndex);\r\n }\r\n if (index > max) {\r\n max = index;\r\n }\r\n });\r\n mask.dataset.zindex = mask.style.zIndex;\r\n mask.style.zIndex = max + 1;\r\n });\r\n } else {\r\n\r\n }\r\n let tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0));\r\n if (tabIndex < 0) {\r\n tabIndex = 0;\r\n }\r\n container.tabIndex = tabIndex + 1;\r\n let content = option.content;\r\n if (!(content instanceof HTMLElement)) {\r\n content = createElement('div', d => d.innerText = content);\r\n }\r\n container.append(\r\n createElement('div', header => {\r\n header.className = 'ui-popup-header';\r\n let title = option.title;\r\n if (!(title instanceof HTMLElement)) {\r\n title = createElement('div', t => {\r\n if (option.movable === false) {\r\n t.className = 'ui-popup-header-title no-move';\r\n } else {\r\n t.className = 'ui-popup-header-title';\r\n }\r\n t.innerText = title;\r\n });\r\n }\r\n header.appendChild(title);\r\n if (option.movable !== false) {\r\n const move = header; // title.querySelector('.ui-popup-move') ?? title;\r\n move.addEventListener('mousedown', e => {\r\n if (['svg', 'use'].includes(e.target?.tagName)) {\r\n return;\r\n }\r\n if (e.buttons !== 1) {\r\n return;\r\n }\r\n const parent = option.mask === false ? mask.parentElement : mask;\r\n const x = e.clientX - container.offsetLeft;\r\n const y = e.clientY - container.offsetTop;\r\n let moved;\r\n const move = e => {\r\n if (e.buttons === 1) {\r\n container.style.left = `${e.clientX - x}px`;\r\n container.style.top = `${e.clientY - y}px`;\r\n moved = true;\r\n } else {\r\n parent.dispatchEvent(new MouseEvent('mouseup'));\r\n }\r\n };\r\n parent.addEventListener('mousemove', move, { passive: false });\r\n const up = () => {\r\n parent.removeEventListener('mousemove', move, { passive: false });\r\n parent.removeEventListener('mouseup', up);\r\n if (moved === true && typeof option.onMoveEnded === 'function') {\r\n option.onMoveEnded.call(this);\r\n }\r\n moved = false;\r\n };\r\n parent.addEventListener('mouseup', up);\r\n });\r\n }\r\n const icons = createElement('div', icons => {\r\n icons.className = 'ui-popup-header-icons';\r\n if (option.collapsable === true) {\r\n const collapse = createIcon('fa-regular', 'compress-alt');\r\n collapse.tabIndex = tabIndex + 2;\r\n collapse.classList.add('icon-expand');\r\n collapse.addEventListener('keypress', e => {\r\n if (e.key === ' ' || e.key === 'Enter') {\r\n collapse.dispatchEvent(new MouseEvent('click'));\r\n }\r\n });\r\n collapse.addEventListener('click', () => {\r\n if (container.classList.contains('ui-popup-collapse')) {\r\n const bounds = this._var.bounds;\r\n if (bounds != null) {\r\n container.style.cssText += `width: ${bounds.width}px; height: ${bounds.height}px`;\r\n this._var.bounds = null;\r\n }\r\n container.classList.remove('ui-popup-collapse');\r\n changeIcon(collapse, 'fa-regular', 'compress-alt');\r\n } else {\r\n const rect = this.rect;\r\n this._var.bounds = rect;\r\n container.style.cssText += `width: 160px; height: 40px`;\r\n container.classList.add('ui-popup-collapse');\r\n changeIcon(collapse, 'fa-regular', 'expand-alt');\r\n }\r\n if (typeof option.onResizeEnded === 'function') {\r\n option.onResizeEnded.call(this);\r\n }\r\n });\r\n icons.appendChild(collapse);\r\n }\r\n if (option.closable !== false) {\r\n const cancel = createIcon('fa-regular', 'times');\r\n cancel.tabIndex = tabIndex + 3;\r\n cancel.addEventListener('keypress', e => {\r\n if (e.key === ' ' || e.key === 'Enter') {\r\n this.close();\r\n }\r\n });\r\n cancel.addEventListener('click', () => this.close());\r\n icons.appendChild(cancel);\r\n }\r\n });\r\n header.appendChild(icons);\r\n }),\r\n createElement('div', 'ui-popup-body', content, createElement('div', 'ui-popup-loading',\r\n createElement('div', null, createIcon('fa-regular', 'spinner-third'))\r\n ))\r\n );\r\n if (Array.isArray(option.buttons) && option.buttons.length > 0) {\r\n tabIndex = Math.max.apply(null, [...container.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0));\r\n container.appendChild(\r\n createElement('div', 'ui-popup-footer', ...option.buttons.map((b, i) => {\r\n const button = createElement('button', 'ui-popup-button');\r\n if (b.tabIndex > 0) {\r\n button.tabIndex = b.tabIndex;\r\n } else {\r\n button.tabIndex = tabIndex + i + 1;\r\n }\r\n button.innerText = b.text;\r\n button.addEventListener('click', () => {\r\n if (typeof b.trigger === 'function') {\r\n const result = b.trigger(this);\r\n if (typeof result?.then === 'function') {\r\n result.then(r => {\r\n if (r !== false) {\r\n this.close();\r\n }\r\n }).catch(reason => console.warn(reason));\r\n } else if (result !== false) {\r\n this.close();\r\n }\r\n } else {\r\n this.close();\r\n }\r\n });\r\n return button;\r\n }))\r\n );\r\n const tabs = [...container.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0);\r\n const tabMin = Math.min.apply(null, tabs);\r\n const tabMax = Math.max.apply(null, tabs);\r\n const last = container.querySelector(`[tabindex=\"${tabMax}\"]`);\r\n if (last != null) {\r\n last.addEventListener('keydown', e => {\r\n if (e.key === 'Tab') {\r\n const first = container.querySelector(`[tabindex=\"${tabMin}\"]`);\r\n first?.focus();\r\n e.preventDefault();\r\n }\r\n });\r\n }\r\n } else {\r\n container.querySelector('.ui-popup-body>.ui-popup-loading').classList.add('ui-popup-loading-content');\r\n }\r\n // resizable\r\n if (option.resizable === true) {\r\n container.append(\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-right';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.right, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-bottom';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.bottom, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-left';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.left, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-top';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.top, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-bottom-right';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.bottomRight, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-bottom-left';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.bottomLeft, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-top-left';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.topLeft, e));\r\n }),\r\n createElement('layer', layer => {\r\n layer.className = 'ui-popup-border ui-popup-border-top-right';\r\n layer.addEventListener('mousedown', e => this._resize(ResizeMods.topRight, e));\r\n })\r\n )\r\n }\r\n mask.appendChild(container);\r\n this._var.mask = mask;\r\n return mask;\r\n }\r\n\r\n show(parent = document.body) {\r\n if (parent == null) {\r\n return;\r\n }\r\n let mask = this._var.mask ?? this.create();\r\n // const exists = [...parent.children].filter(e => e.classList.contains('ui-popup-mask'));\r\n const exists = parent.querySelectorAll('.ui-popup-mask');\r\n let zindex = 0;\r\n for (let ex of exists) {\r\n let z = parseInt(ex.style.zIndex);\r\n if (!isNaN(z) && z > zindex) {\r\n zindex = z;\r\n }\r\n }\r\n if (zindex > 0) {\r\n mask.style.zIndex = String(zindex + 1);\r\n }\r\n parent.appendChild(mask);\r\n if (this._var.option.mask === false) {\r\n // calculator position\r\n const container = this.container;\r\n container.style.left = String((parent.offsetWidth - container.offsetWidth) / 2) + 'px';\r\n container.style.top = String((parent.offsetHeight - container.offsetHeight) / 2) + 'px';\r\n }\r\n return new Promise(resolve => {\r\n setTimeout(() => {\r\n mask.style.opacity = 1;\r\n this.container.focus();\r\n resolve(mask);\r\n }, 0);\r\n });\r\n }\r\n\r\n get loading() { return this._var.mask?.querySelector('.ui-popup-body>.ui-popup-loading')?.style?.visibility === 'visible' }\r\n set loading(flag) {\r\n let loading = this._var.mask?.querySelector('.ui-popup-body>.ui-popup-loading');\r\n if (loading == null) {\r\n return;\r\n }\r\n if (flag === false) {\r\n loading.style.visibility = 'hidden';\r\n loading.style.opacity = 0;\r\n } else {\r\n loading.style.visibility = 'visible';\r\n loading.style.opacity = 1;\r\n }\r\n }\r\n\r\n _resize(mod, e) {\r\n if (e.buttons !== 1) {\r\n return;\r\n }\r\n const container = this.container;\r\n const option = this._var.option;\r\n if (typeof option.onResizeStarted === 'function') {\r\n option.onResizeStarted.call(this);\r\n }\r\n const mask = this._var.mask;\r\n // this._var.cursor = mask.style.cursor;\r\n // mask.style.cursor = Cursors[mod];\r\n const originalX = e.clientX;\r\n const originalY = e.clientY;\r\n const original = {\r\n width: container.offsetWidth,\r\n height: container.offsetHeight,\r\n left: container.offsetLeft,\r\n top: container.offsetTop\r\n };\r\n const minWidth = option.minWidth ?? 200;\r\n const minHeight = option.minHeight ?? 200;\r\n let resized;\r\n const parent = option.mask === false ? mask.parentElement : mask;\r\n const move = e => {\r\n if (e.buttons !== 1) {\r\n parent.dispatchEvent(new MouseEvent('mouseup'));\r\n return;\r\n }\r\n const offsetX = e.clientX - originalX;\r\n const offsetY = e.clientY - originalY;\r\n let width = original.width;\r\n let height = original.height;\r\n let x = original.left;\r\n let y = original.top;\r\n if ((mod & ResizeMods.right) === ResizeMods.right) {\r\n width += offsetX;\r\n if (width < minWidth) {\r\n width = minWidth;\r\n }\r\n }\r\n if ((mod & ResizeMods.bottom) === ResizeMods.bottom) {\r\n height += offsetY;\r\n if (height < minHeight) {\r\n height = minHeight;\r\n }\r\n }\r\n if ((mod & ResizeMods.left) === ResizeMods.left) {\r\n width -= offsetX;\r\n if (width < minWidth) {\r\n width = minWidth;\r\n x = originalX + original.width - minWidth;\r\n } else {\r\n x += offsetX;\r\n }\r\n }\r\n if ((mod & ResizeMods.top) === ResizeMods.top) {\r\n height -= offsetY;\r\n if (height < minHeight) {\r\n height = minHeight;\r\n y = originalY + original.height - minHeight;\r\n } else {\r\n y += offsetY;\r\n }\r\n }\r\n if (typeof option.onResizing === 'function') {\r\n option.onResizing.call(this, x, y, width, height);\r\n } else {\r\n container.style.cssText += `left: ${x}px; top: ${y}px; width: ${width}px; height: ${height}px`;\r\n }\r\n resized = true;\r\n }\r\n parent.addEventListener('mousemove', move, { passive: false });\r\n const up = () => {\r\n parent.removeEventListener('mousemove', move, { passive: false });\r\n parent.removeEventListener('mouseup', up);\r\n // mask.style.cursor = this._var.cursor;\r\n if (resized === true && typeof option.onResizeEnded === 'function') {\r\n option.onResizeEnded.call(this);\r\n }\r\n resized = false;\r\n };\r\n parent.addEventListener('mouseup', up);\r\n }\r\n}\r\n\r\nexport function createPopup(title, content, ...buttons) {\r\n const popup = new Popup({\r\n title,\r\n content,\r\n buttons\r\n });\r\n return popup;\r\n}\r\n\r\nconst iconTypes = {\r\n 'info': 'info-circle',\r\n 'information': 'info-circle',\r\n 'warn': 'exclamation-triangle',\r\n 'warning': 'exclamation-triangle',\r\n 'question': 'question-circle',\r\n 'error': 'times-circle'\r\n}\r\n\r\nexport function showAlert(title, message, iconType = 'info', parent = document.body) {\r\n return new Promise(resolve => {\r\n const popup = new Popup({\r\n title,\r\n content: createElement('div', 'message-wrapper',\r\n createIcon('fa-solid', iconTypes[iconType] ?? 'info-circle'),\r\n createElement('span', span => span.innerText = message)\r\n ),\r\n resolve,\r\n buttons: [\r\n { text: r('ok', 'OK'), trigger: resolve }\r\n ]\r\n });\r\n popup.show(parent).then(mask => {\r\n const button = mask.querySelector('.ui-popup-container .ui-popup-footer .ui-popup-button:last-child');\r\n button?.focus();\r\n });\r\n });\r\n}\r\n\r\nexport function showConfirm(title, content, buttons, iconType = 'question', parent = document.body) {\r\n return new Promise(resolve => {\r\n const wrapper = createElement('div', 'message-wrapper');\r\n if (!nullOrEmpty(iconType)) {\r\n wrapper.appendChild(createIcon('fa-solid', iconTypes[iconType] ?? 'question-circle'));\r\n }\r\n wrapper.appendChild(content instanceof HTMLElement ?\r\n content :\r\n createElement('span', span => span.innerText = content));\r\n const popup = new Popup({\r\n title,\r\n content: wrapper,\r\n resolve,\r\n buttons: buttons?.map(b => {\r\n return {\r\n text: b.text,\r\n trigger: p => {\r\n let result;\r\n if (typeof b.trigger === 'function') {\r\n result = b.trigger(p, b);\r\n if (typeof result?.then === 'function') {\r\n return result.then(r => {\r\n r !== false && resolve(r);\r\n return r;\r\n });\r\n }\r\n result !== false && resolve(result);\r\n } else {\r\n result = {\r\n key: b.key,\r\n popup: p\r\n };\r\n resolve(result);\r\n }\r\n return result;\r\n }\r\n };\r\n }) ??\r\n [\r\n { text: r('yes', 'Yes'), trigger: p => resolve({ key: 'yes', popup: p }) },\r\n { text: r('no', 'No'), trigger: p => resolve({ key: 'no', popup: p }) }\r\n ]\r\n });\r\n popup.show(parent).then(mask => {\r\n const button = mask.querySelector('.ui-popup-container .ui-popup-footer .ui-popup-button:last-child');\r\n button?.focus();\r\n });\r\n });\r\n}","export function validation(element, regex) {\r\n if (element instanceof HTMLElement && regex instanceof RegExp) {\r\n element.addEventListener('change', e => {\r\n if (regex.test(e.target.value)) {\r\n e.target.classList.remove('validation-error');\r\n } else {\r\n e.target.classList.add('validation-error');\r\n }\r\n })\r\n }\r\n return element;\r\n}\r\n\r\nexport function convertCssStyle(style) {\r\n return Object.entries(style).map(s => `${s[0]}: ${s[1]}`).join('; ');\r\n}","import { createElement } from \"../functions\";\r\n\r\n/**\r\n * 创建或转换日期选择框\r\n * @param {string} [min] - 最小可选日期\r\n * @param {string} [max] - 最大可选日期\r\n * @param {HTMLInputElement | string} [element] - 转换该元素为日期选择框\r\n * @returns {HTMLInputElement} 返回创建或转换的日期选择框\r\n */\r\nexport function createDateInput(min, max, element) {\r\n let date;\r\n if (typeof element === 'string') {\r\n element = document.querySelector(element);\r\n }\r\n if (element instanceof HTMLInputElement) {\r\n date = element;\r\n date.classList.add('ui-date-cell');\r\n } else {\r\n date = createElement('input', 'ui-date-cell');\r\n }\r\n date.required = true;\r\n date.type = 'date';\r\n if (min != null) {\r\n date.min = min;\r\n }\r\n if (max != null) {\r\n date.max = max;\r\n }\r\n return date;\r\n}\r\n\r\n/**\r\n * 将日期转换为 `yyyy-MM-dd` 格式的字符串\r\n * @param {Date} dt 要转换的日期值\r\n * @returns 返回 `yyyy-MM-dd` 格式的字符串\r\n */\r\nexport function toDateValue(dt) {\r\n if (isNaN(dt)) {\r\n return '';\r\n }\r\n const month = String(dt.getMonth() + 1).padStart(2, '0');\r\n const date = String(dt.getDate()).padStart(2, '0');\r\n return `${dt.getFullYear()}-${month}-${date}`;\r\n}\r\n\r\nfunction resolveDate(s) {\r\n if (s instanceof Date) {\r\n return s;\r\n }\r\n const ticks = Number(s);\r\n if (!isNaN(ticks) && ticks > 0) {\r\n return new Date((ticks - 621355968e9) / 1e4);\r\n }\r\n return new Date(s);\r\n}\r\n\r\n/**\r\n * 格式化日期为 M/d/yyyy 格式的字符串\r\n * @param {Date | number | string} date - 需要格式化的日期值,支持的格式如下:\r\n * \r\n * * `\"2024-01-26\"`\r\n * * `\"2024-01-26T00:00:00\"`\r\n * * `\"1/26/2024\"`\r\n * * `\"638418240000000000\"`\r\n * * `new Date('2024-01-26')`\r\n * @returns {string} 返回格式化后的日期字符串\r\n */\r\nexport function formatDate(date) {\r\n date = resolveDate(date);\r\n if (date instanceof Date && !isNaN(date)) {\r\n return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;\r\n }\r\n return '';\r\n}\r\n\r\n/**\r\n * 设置显示日期\r\n * @param {HTMLElement} element - 要设置显示日期的元素\r\n * @param {Date | number | string} val - 日期值,支持格式参见 {@linkcode formatDate}\r\n */\r\nexport function setDateValue(element, val) {\r\n if (element.tagName === 'INPUT') {\r\n if (val === '') {\r\n element.value = '';\r\n } else if (isNaN(val)) {\r\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(val)) {\r\n element.value = String(val).substring(0, 10);\r\n } else if (/^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/.test(val)) {\r\n element.value = toDateValue(new Date(val));\r\n } else {\r\n element.value = '';\r\n }\r\n } else {\r\n if (!(val instanceof Date)) {\r\n val = new Date((val - 621355968e9) / 1e4);\r\n }\r\n element.value = toDateValue(val);\r\n }\r\n } else {\r\n element.innerText = formatDate(val);\r\n }\r\n}\r\n\r\n/**\r\n * 自定义日期格式化回调函数\r\n * @callback DateFormatterCallback\r\n * @param {Date} date - 日期值\r\n * @returns {any} 返回格式化后的结果\r\n */\r\n\r\n/**\r\n * 从日期选择框获取日期值\r\n * @param {HTMLInputElement} element - 要获取的日期选择框\r\n * @param {DateFormatterCallback} [formatter] - 自定义格式化函数,传入参数为 `Date` 类型\r\n * @returns {string | any} 默认返回日期 `ticks` 的字符串\r\n */\r\nexport function getDateValue(element, formatter) {\r\n const date = element?.valueAsDate;\r\n if (date instanceof Date && !isNaN(date)) {\r\n const year = date.getFullYear();\r\n if (year < 1900 || year > 9999) {\r\n return '';\r\n }\r\n if (typeof formatter === 'function') {\r\n return formatter(date);\r\n }\r\n return String(date.getTime() * 1e4 + 621355968e9);\r\n }\r\n return '';\r\n}\r\n\r\n/**\r\n * 日期选择框类\r\n * @class\r\n */\r\nexport class DateSelector {\r\n _var = {\r\n options: null\r\n };\r\n\r\n /**\r\n * 日期发生变化时触发的事件\r\n * @event\r\n * @param {Date} date - 修改后的日期值\r\n * @this DateSelector\r\n */\r\n onDateChanged;\r\n\r\n /**\r\n * 日期选择框构造函数\r\n * @constructor\r\n * @param {object} [opts] - 日期选择框初始化参数\r\n * @param {boolean} [opts.enabled] - 是否可用\r\n * @param {string} [opts.minDate] - 最小可选择日期\r\n * @param {string} [opts.maxDate] - 最大可选择日期\r\n * @param {DateFormatterCallback} [opts.valueFormatter] - 自定义格式化函数\r\n * @example