@topvisor/ui 1.4.0 → 1.4.1-projectSelector.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.chunks/core-BgoBbm_5.es.js +242 -0
- package/.chunks/core-BgoBbm_5.es.js.map +1 -0
- package/.chunks/core-D1KnwO7l.amd.js +2 -0
- package/.chunks/core-D1KnwO7l.amd.js.map +1 -0
- package/.chunks/{datepicker-D1Hw3a3o.es.js → datepicker-BPTUHd97.es.js} +2 -2
- package/.chunks/datepicker-BPTUHd97.es.js.map +1 -0
- package/.chunks/{datepicker-3coUsFW2.amd.js → datepicker-O_SK-Dz4.amd.js} +2 -2
- package/.chunks/datepicker-O_SK-Dz4.amd.js.map +1 -0
- package/.chunks/{dialog_regionSelectorRegions-CZ8IX7la.amd.js → dialog_regionSelectorRegions-Ba-Eypgv.amd.js} +2 -2
- package/.chunks/dialog_regionSelectorRegions-Ba-Eypgv.amd.js.map +1 -0
- package/.chunks/{dialog_regionSelectorRegions-1UVhgK2f.es.js → dialog_regionSelectorRegions-DA38RsiW.es.js} +4 -4
- package/.chunks/dialog_regionSelectorRegions-DA38RsiW.es.js.map +1 -0
- package/.chunks/{dialogs.vue_vue_type_script_setup_true_lang-Dq9kWWMg.amd.js → dialogs.vue_vue_type_script_setup_true_lang-CWprVs8d.amd.js} +2 -2
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-CWprVs8d.amd.js.map +1 -0
- package/.chunks/{dialogs.vue_vue_type_script_setup_true_lang-DRbTG0vh.es.js → dialogs.vue_vue_type_script_setup_true_lang-CzFMOjlE.es.js} +2 -2
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-CzFMOjlE.es.js.map +1 -0
- package/.chunks/field-Cvv0SRcJ.amd.js.map +1 -1
- package/.chunks/field-CyyFzM-Y.es.js.map +1 -1
- package/.chunks/{forms-CUSCBQu3.amd.js → forms-4D_EVI46.amd.js} +3 -3
- package/.chunks/forms-4D_EVI46.amd.js.map +1 -0
- package/.chunks/{forms-BseC3Ftz.es.js → forms-xkXHvvah.es.js} +565 -551
- package/.chunks/forms-xkXHvvah.es.js.map +1 -0
- package/.chunks/index-DLUtoTUg.amd.js.map +1 -1
- package/.chunks/index-DkQWJkMc.es.js.map +1 -1
- package/.chunks/lazy-40pjr8cZ.es.js.map +1 -1
- package/.chunks/lazy-DSFLxvj4.amd.js.map +1 -1
- package/.chunks/{notice-DwjipV21.amd.js → notice-hF3z8ewG.amd.js} +2 -2
- package/.chunks/notice-hF3z8ewG.amd.js.map +1 -0
- package/.chunks/{notice-Cl3ZgiHm.es.js → notice-wqZxmsUH.es.js} +2 -2
- package/.chunks/notice-wqZxmsUH.es.js.map +1 -0
- package/.chunks/{page.vue_vue_type_script_setup_true_lang-CpRJQFD1.es.js → page.vue_vue_type_script_setup_true_lang-rW3w9LMh.es.js} +4 -4
- package/.chunks/page.vue_vue_type_script_setup_true_lang-rW3w9LMh.es.js.map +1 -0
- package/.chunks/{page.vue_vue_type_script_setup_true_lang-CjIiZU-D.amd.js → page.vue_vue_type_script_setup_true_lang-tiWuQ_ZK.amd.js} +2 -2
- package/.chunks/page.vue_vue_type_script_setup_true_lang-tiWuQ_ZK.amd.js.map +1 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-C9A--uWd.es.js +503 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-C9A--uWd.es.js.map +1 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DABqSSXw.amd.js +2 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DABqSSXw.amd.js.map +1 -0
- package/.chunks/{popup-Jw_Yyg3U.es.js → popup-BeLPdHWv.es.js} +2 -2
- package/.chunks/popup-BeLPdHWv.es.js.map +1 -0
- package/.chunks/{popup-DRuyYFGB.amd.js → popup-Bwmu8rOb.amd.js} +2 -2
- package/.chunks/popup-Bwmu8rOb.amd.js.map +1 -0
- package/.chunks/{popupHint.vue_vue_type_style_index_0_lang-DtiT6NE4.amd.js → popupHint.vue_vue_type_style_index_0_lang-B0BWXhHK.amd.js} +2 -2
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-B0BWXhHK.amd.js.map +1 -0
- package/.chunks/{popupHint.vue_vue_type_style_index_0_lang-DD59yF6H.es.js → popupHint.vue_vue_type_style_index_0_lang-fnjq0yg1.es.js} +2 -2
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-fnjq0yg1.es.js.map +1 -0
- package/.chunks/store-CX_6ZXhO.es.js.map +1 -1
- package/.chunks/store-YRW59xEF.amd.js.map +1 -1
- package/.chunks/{utils-D9nYQabE.amd.js → utils-BRJvuqe_.amd.js} +2 -2
- package/.chunks/utils-BRJvuqe_.amd.js.map +1 -0
- package/.chunks/{utils-YrUExsH7.es.js → utils-ByqQkftW.es.js} +2 -2
- package/.chunks/utils-ByqQkftW.es.js.map +1 -0
- package/.chunks/{utils-Q69SXlnV.es.js → utils-YVlPlqDK.es.js} +3 -3
- package/.chunks/utils-YVlPlqDK.es.js.map +1 -0
- package/.chunks/{utils-CzHUG_xz.amd.js → utils-cAJahDml.amd.js} +2 -2
- package/.chunks/utils-cAJahDml.amd.js.map +1 -0
- package/.chunks/{widgetInput.vue_vue_type_script_setup_true_lang-CkE912ll.amd.js → widgetInput.vue_vue_type_script_setup_true_lang-D7lVLE3D.amd.js} +2 -2
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-D7lVLE3D.amd.js.map +1 -0
- package/.chunks/{widgetInput.vue_vue_type_script_setup_true_lang-CDkeKVqY.es.js → widgetInput.vue_vue_type_script_setup_true_lang-UUovJzhL.es.js} +2 -2
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-UUovJzhL.es.js.map +1 -0
- package/README.md +82 -82
- package/api/additional.amd.js.map +1 -1
- package/api/additional.js.map +1 -1
- package/api/index.amd.js +1 -1
- package/api/index.amd.js.map +1 -1
- package/api/index.js +1 -1
- package/api/index.js.map +1 -1
- package/assets/core.css +1 -1
- package/assets/forms.css +1 -1
- package/assets/policy.css +1 -1
- package/assets/project.css +1 -1
- package/charts/charts.amd.js +1 -1
- package/charts/charts.amd.js.map +1 -1
- package/charts/charts.js +1 -1
- package/charts/charts.js.map +1 -1
- package/core/app.amd.js +1 -1
- package/core/app.amd.js.map +1 -1
- package/core/app.js +5 -5
- package/core/app.js.map +1 -1
- package/dialog/dialog.amd.js +1 -1
- package/dialog/dialog.amd.js.map +1 -1
- package/dialog/dialog.js +2 -2
- package/dialog/dialog.js.map +1 -1
- package/extra/extra.amd.js.map +1 -1
- package/extra/extra.js.map +1 -1
- package/forms/forms.amd.js +1 -1
- package/forms/forms.js +3 -3
- package/formsExt/formsExt.amd.js +1 -1
- package/formsExt/formsExt.amd.js.map +1 -1
- package/formsExt/formsExt.js +123 -111
- package/formsExt/formsExt.js.map +1 -1
- package/icomoon/Read Me.txt +7 -7
- package/icomoon/Topvisor icons.json +6658 -0
- package/icomoon/demo-files/demo.css +158 -158
- package/icomoon/demo-files/demo.js +30 -30
- package/icomoon/demo.css +158 -158
- package/icomoon/demo.html +15 -1
- package/icomoon/demo.js +30 -30
- package/icomoon/fonts/Topvisor-2.eot +0 -0
- package/icomoon/fonts/Topvisor-2.svg +1 -0
- package/icomoon/fonts/Topvisor-2.ttf +0 -0
- package/icomoon/fonts/Topvisor-2.woff +0 -0
- package/icomoon/selection.json +1 -1
- package/icomoon/style.css +8 -5
- package/jquery-ui.min.css +5 -5
- package/layout/layout.amd.js +1 -1
- package/layout/layout.amd.js.map +1 -1
- package/layout/layout.js +1 -1
- package/layout/layout.js.map +1 -1
- package/package.json +1 -1
- package/popup/popup.amd.js +1 -1
- package/popup/popup.amd.js.map +1 -1
- package/popup/popup.js +6 -6
- package/popup/popup.js.map +1 -1
- package/popup/worker.amd.js +1 -1
- package/popup/worker.amd.js.map +1 -1
- package/popup/worker.js +2 -2
- package/popup/worker.js.map +1 -1
- package/project/project.amd.js +1 -1
- package/project/project.amd.js.map +1 -1
- package/project/project.js +896 -614
- package/project/project.js.map +1 -1
- package/require/css.amd.js +12 -12
- package/src/api/api/types/client/request-options.d.ts +8 -3
- package/src/components/forms/caption/types.d.ts +5 -1
- package/src/components/forms/input/input.vue.d.ts +2 -4
- package/src/components/forms/input/types.d.ts +15 -0
- package/src/components/forms/select/select.vue.d.ts +15 -2
- package/src/components/forms/select/types.d.ts +6 -0
- package/src/components/formsExt/editArea/editArea.vue.d.ts +15 -2
- package/src/components/formsExt/editArea/types.d.ts +6 -0
- package/src/components/formsExt/editInput/editInput.vue.d.ts +16 -1
- package/src/components/formsExt/selector2/composables/useAPI.d.ts +2 -0
- package/src/components/formsExt/selector2/composables/useMenu.d.ts +3 -1
- package/src/components/formsExt/selector2/types.d.ts +14 -0
- package/src/components/popup/popup/listItem.vue.d.ts +24 -4
- package/src/components/popup/popup/types.d.ts +1 -0
- package/src/components/project/groupSelector/groups/groups.vue.d.ts +2 -0
- package/src/components/project/groupSelector/groups/utils.d.ts +1 -1
- package/src/components/project/project.d.ts +1 -0
- package/src/components/project/projectSelector/projectSelector.vue.d.ts +121 -0
- package/src/components/project/projectSelector/stories/mocks/projects.d.ts +10 -0
- package/src/components/project/projectSelector/submenu/submenu.vue.d.ts +4 -0
- package/src/components/project/projectSelector/submenu/types.d.ts +17 -0
- package/src/components/project/projectSelector/types.d.ts +57 -0
- package/src/components/project/projectSelector/utils.d.ts +206 -0
- package/src/core/directives/shortcut.d.ts +12 -0
- package/src/core/utils/string.d.ts +1 -1
- package/tabs/tabs.amd.js.map +1 -1
- package/tabs/tabs.js.map +1 -1
- package/tabsView/tabsView.amd.js +1 -1
- package/tabsView/tabsView.amd.js.map +1 -1
- package/tabsView/tabsView.js +2 -2
- package/tabsView/tabsView.js.map +1 -1
- package/utils/check.amd.js.map +1 -1
- package/utils/check.js.map +1 -1
- package/utils/clipboard.amd.js +1 -1
- package/utils/clipboard.amd.js.map +1 -1
- package/utils/clipboard.js +1 -1
- package/utils/clipboard.js.map +1 -1
- package/utils/date.amd.js +1 -1
- package/utils/date.js +1 -1
- package/utils/device.amd.js +1 -1
- package/utils/device.js +1 -1
- package/utils/dom.amd.js.map +1 -1
- package/utils/dom.js.map +1 -1
- package/utils/image.amd.js.map +1 -1
- package/utils/image.js.map +1 -1
- package/utils/keyboard.amd.js.map +1 -1
- package/utils/keyboard.js.map +1 -1
- package/utils/lodash.amd.js +1 -1
- package/utils/lodash.js +1 -1
- package/utils/number.amd.js.map +1 -1
- package/utils/number.js.map +1 -1
- package/utils/price.amd.js +1 -1
- package/utils/price.amd.js.map +1 -1
- package/utils/price.js +1 -1
- package/utils/price.js.map +1 -1
- package/utils/route.amd.js.map +1 -1
- package/utils/route.js.map +1 -1
- package/utils/scroll.amd.js.map +1 -1
- package/utils/scroll.js.map +1 -1
- package/utils/searchers.amd.js +1 -1
- package/utils/searchers.amd.js.map +1 -1
- package/utils/searchers.js +3 -3
- package/utils/searchers.js.map +1 -1
- package/utils/string.amd.js +1 -1
- package/utils/string.amd.js.map +1 -1
- package/utils/string.js +1 -1
- package/utils/string.js.map +1 -1
- package/utils/system.amd.js.map +1 -1
- package/utils/system.js.map +1 -1
- package/utils/url.amd.js.map +1 -1
- package/utils/url.js.map +1 -1
- package/web-types.json +31 -0
- package/.chunks/core-BL-38XF7.es.js +0 -196
- package/.chunks/core-BL-38XF7.es.js.map +0 -1
- package/.chunks/core-BsPx05H9.amd.js +0 -2
- package/.chunks/core-BsPx05H9.amd.js.map +0 -1
- package/.chunks/datepicker-3coUsFW2.amd.js.map +0 -1
- package/.chunks/datepicker-D1Hw3a3o.es.js.map +0 -1
- package/.chunks/dialog_regionSelectorRegions-1UVhgK2f.es.js.map +0 -1
- package/.chunks/dialog_regionSelectorRegions-CZ8IX7la.amd.js.map +0 -1
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-DRbTG0vh.es.js.map +0 -1
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-Dq9kWWMg.amd.js.map +0 -1
- package/.chunks/forms-BseC3Ftz.es.js.map +0 -1
- package/.chunks/forms-CUSCBQu3.amd.js.map +0 -1
- package/.chunks/notice-Cl3ZgiHm.es.js.map +0 -1
- package/.chunks/notice-DwjipV21.amd.js.map +0 -1
- package/.chunks/page.vue_vue_type_script_setup_true_lang-CjIiZU-D.amd.js.map +0 -1
- package/.chunks/page.vue_vue_type_script_setup_true_lang-CpRJQFD1.es.js.map +0 -1
- package/.chunks/policy.vue_vue_type_style_index_0_lang-BBDJEs5Q.es.js +0 -496
- package/.chunks/policy.vue_vue_type_style_index_0_lang-BBDJEs5Q.es.js.map +0 -1
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DJOaMdBm.amd.js +0 -2
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DJOaMdBm.amd.js.map +0 -1
- package/.chunks/popup-DRuyYFGB.amd.js.map +0 -1
- package/.chunks/popup-Jw_Yyg3U.es.js.map +0 -1
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-DD59yF6H.es.js.map +0 -1
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-DtiT6NE4.amd.js.map +0 -1
- package/.chunks/utils-CzHUG_xz.amd.js.map +0 -1
- package/.chunks/utils-D9nYQabE.amd.js.map +0 -1
- package/.chunks/utils-Q69SXlnV.es.js.map +0 -1
- package/.chunks/utils-YrUExsH7.es.js.map +0 -1
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CDkeKVqY.es.js.map +0 -1
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CkE912ll.amd.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"policy.vue_vue_type_style_index_0_lang-BBDJEs5Q.es.js","sources":["../../src/components/formsExt/menu/menu.vue","../../src/components/formsExt/selector2/itemMulti.vue","../../src/components/formsExt/selector2/cache.ts","../../src/components/formsExt/selector2/composables/useAPI.ts","../../src/components/formsExt/selector2/utils.ts","../../src/components/formsExt/selector2/composables/useMenu.ts","../../src/components/formsExt/selector2/selector2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, onUpdated, ref } from 'vue';\nimport type { Item, Props } from './types';\nimport Core from '@/core/core/core';\nimport { isSafari } from '@/core/utils/device';\nimport TopButton from '@/components/forms/button/button.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tstyling: 'default',\n});\n\nconst model = defineModel({\n\trequired: true,\n});\n\nconst el = ref();\n\n// валидация типа modelValue без возможности выбора нескольких значений (ожидается строка или число)\nif (!props.isMultiple && typeof (model.value) !== 'string' && typeof (model.value) !== 'number') {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected String: ' + typeof (model.value));\n}\n\n// валидация типа modelValue с возможностью выбора нескольких значений (ожидается массив)\nif (props.isMultiple && !Array.isArray(model.value)) {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected Array: ' + typeof (model.value));\n}\n\n/**\n * Для множественного выбора без пустого множества\n *\n * Если ничего не выбрано, присваиваем 1-ое значение\n */\nif (props.isMultiple && !props.canBeEmptyMultiple && Array.isArray(model.value) && !model.value.length && props.items[0]) {\n\tmodel.value = [props.items[0]?.href ?? props.items[0]?.value];\n}\n\nconst itemIsActive = (item: Item) => {\n\tif (!Array.isArray(model.value)) {\n\t\treturn item.value === model.value;\n\t}\n\n\treturn model.value.includes(item.value);\n};\n\n/**\n * Выбрать элемент\n * @param item\n * @param toggle - добавить или исключить элемент, для isMultiple\n */\nconst select = (item: Item, toggle = false) => {\n\tif (Array.isArray(model.value)) {\n\t\tlet modelNew = model.value.slice();\n\n\t\tif (toggle) {\n\t\t\tif (!modelNew.length) modelNew = props.items.map(item => item.value);\n\n\t\t\tconst index = modelNew.indexOf(item.value);\n\t\t\tif (index === -1) {\n\t\t\t\tmodelNew.push(item.value);\n\t\t\t} else {\n\t\t\t\tmodelNew.splice(index, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (modelNew.length === 1 && modelNew[0] === item.value) {\n\t\t\t\tmodelNew = [];\n\t\t\t} else {\n\t\t\t\tmodelNew = [item.value];\n\t\t\t}\n\t\t}\n\n\t\tif (!props.canBeEmptyMultiple && !modelNew.length) modelNew = [item.value];\n\n\t\tmodel.value = modelNew;\n\n\t\treturn;\n\t}\n\n\tmodel.value = item.value;\n};\n\n// вертикальный скролл в горизонтальный скролл\nconst onWheel = (event: WheelEvent) => {\n\tif (el.value.scrollWidth <= el.value.offsetWidth) return;\n\tif (event.shiftKey) return;\n\tif (Math.abs(event.deltaY) < 50) return; // устройство с высокой точностью, например тачпад\n\n\tevent.preventDefault();\n\n\tconst delta = event.deltaY > 0 ? 30 : -30;\n\tel.value.scrollLeft = el.value.scrollLeft + delta;\n};\n\n/**\n * Замена стандартному scrollIntoView, который меняет скролл документа\n *\n * Выравнивание по ближнему краю элемента\n *\n * Выравнивается таким образом, чтобы был виден соседний элемент\n */\nconst scrollIntoView = (isSmooth = true) => {\n\tconst elBtn = el.value.querySelector('.top-active');\n\tif (!elBtn) return;\n\n\tconst gap = 24;\n\n\t// левая и правая координаты элемента\n\tconst leftMargin = elBtn.offsetLeft - el.value.offsetLeft - gap;\n\tconst rightMargin = elBtn.offsetLeft - el.value.offsetLeft + elBtn.clientWidth + gap;\n\n\t// левая и правая границы видимой части меню\n\tconst leftMarginParent = el.value.scrollLeft;\n\tconst rightMarginParent = el.value.clientWidth + el.value.scrollLeft;\n\n\tlet scrollLeft: number | undefined = undefined;\n\n\t// левую границу элемента к левой границе меню\n\tif (leftMargin < leftMarginParent) scrollLeft = leftMargin;\n\n\t// правую границу элемента к правой границе меню\n\tif (rightMargin > rightMarginParent) scrollLeft = rightMargin - el.value.clientWidth;\n\n\tif (scrollLeft !== undefined) {\n\t\tif (isSafari()) {\n\t\t\tCore.$?.(el.value).animate({ scrollLeft: scrollLeft }, isSmooth ? 200 : 0);\n\t\t} else {\n\t\t\tel.value.scrollTo({ left: scrollLeft, behavior: isSmooth ? 'smooth' : 'auto' });\n\t\t}\n\t}\n};\n\n/**\n * Выбрать все элементы в меню\n */\nconst selectAll = () => {\n\tif (!Array.isArray(model.value)) return;\n\n\tif (model.value.length === props.items.length) {\n\t\tmodel.value = [props.items[0].href ?? props.items[0].value];\n\t\treturn;\n\t}\n\n\tmodel.value = props.items.map(item => item.href ?? item.value);\n};\n\nonMounted(() => scrollIntoView(false));\nonUpdated(() => scrollIntoView(true));\n\n</script>\n\n<template>\n\t<div\n\t\tref=\"el\"\n\t\t:class=\"{\n\t\t\t'top-menu': true,\n\t\t\t['top-style_' + styling]: true,\n\t\t\t// ['top-unwrap-x']: styling === 'default',\n\t\t}\"\n\t\t@wheel=\"onWheel\"\n\t>\n\t\t<TopButton\n\t\t\tv-for=\"item in items\"\n\t\t\t:=\"item\"\n\t\t\tclass=\"top-menu_item\"\n\t\t\tcolor=\"theme\"\n\t\t\t@click=\"select(item, $event.ctrlKey || $event.metaKey)\"\n\t\t\t:isActive=\"itemIsActive(item)\"\n\t\t>\n\t\t\t<template #default v-if=\"item.content\">\n\t\t\t\t{{ item.content }}\n\t\t\t</template>\n\t\t</TopButton>\n\n\t\t<div\n\t\t\tv-if=\"Array.isArray(model) && selectAllItem\"\n\t\t\tclass=\"top-menu_selectAll\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\t:=\"selectAllItem\"\n\t\t\t\tclass=\"top-menu_item\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\tstyling=\"\"\n\t\t\t\t@click=\"selectAll()\"\n\t\t\t\t:isActive=\"model.length === items.length\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"selectAllItem.content\">\n\t\t\t\t\t{{ selectAllItem.content }}\n\t\t\t\t</template>\n\t\t\t</TopButton>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n.top-menu {\n\t--scroll-thumb-color: var(--color-line-1);\n\t--scroll-thumb-color-hover: var(--color-line-2);\n\t--scroll-thumb-color-active: var(--color-line-3);\n\n\tmax-width: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: var(--top-gap-2);\n\toverflow-x: auto;\n\tscrollbar-width: none; /* firefox */\n\n\t/* предотвратить натинвые события браузера (назад / вперед) */\n\toverscroll-behavior-x: contain;\n}\n\n.top-menu::-webkit-scrollbar { display: none; }\n\n.top-menu .top-menu_item {\n\t--top-button-color: var(--color-text-2);\n\n\toutline-offset: -2px !important;\n\tmin-width: 0;\n\tmax-width: 200px;\n\tmargin: 0;\n\tflex-shrink: 0;\n}\n\n.top-menu .top-menu_item[data-top-icon] {\n\t--top-icon-color: var(--color-text-2);\n}\n\n.top-menu_selectAll {\n\tposition: sticky;\n\tright: 0;\n\tbackground: var(--color-layout-front-1);\n\tborder-left: 1px solid var(--color-line-1);\n\tpadding-left: var(--top-padding-1);\n\tbox-shadow: var(--color-layout-front-1) var(--top-padding-2) 0px;\n}\n\n/* style default */\n.top-menu.top-style_default .top-menu_item {\n\t--top-forms-radius: 0;\n\t--top-forms-border-color: transparent;\n\t--top-forms-border-width: 2px;\n\n\tfilter: none;\n\tbox-shadow: none;\n\tborder: none;\n\tborder-bottom: var(--top-forms-border-width) solid var(--top-forms-border-color);\n\tbackground: none;\n}\n\n.top-style_default > .top-menu_item > [data-top-badge] {\n\tmargin-top: 0;\n}\n\n.top-menu.top-style_default .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-2);\n}\n\n.top-menu.top-style_default .top-menu_item:active,\n.top-menu.top-style_default .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-primary-1);\n}\n\n.top-menu.top-style_default .top-menu_selectAll {\n\tpadding-left: var(--top-padding-2);\n}\n\n/* style bar */\n.top-menu.top-style_bar {\n\tborder-radius: var(--top-radius-3);\n\tborder: 1px solid var(--color-line-2);\n\tpadding: var(--top-padding-1);\n\tgap: 3px;\n}\n.top-menu.top-style_bar .top-menu_item {\n\t--top-button-background-color-hover: var(--color-layer-1);\n\t--top-button-background-color-active: var(--color-layer-2);\n\t--top-button-background-color-selected: var(--color-layer-primary-1);\n\n\tposition: relative;\n}\n\n.top-menu.top-style_bar .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n}\n\n.top-menu.top-style_bar .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-primary);\n}\n\n/* разделители кнопок в баре */\n.top-menu.top-style_bar .top-menu_item:not(:first-child):not(.top-active):not(:hover):after {\n\tcontent: \"\";\n\tbackground: var(--color-line-1-opacity);\n\twidth: 1px;\n\theight: 60%;\n\tdisplay: block;\n\tposition: absolute;\n\tleft: -2px;\n}\n.top-menu.top-style_bar .top-menu_item.top-active + .top-menu_item:after,\n.top-menu.top-style_bar .top-menu_item:hover + .top-menu_item:after {\n\tcontent: none !important;\n}\n\n/*\n.top-style_bar > .top-menu_item > [data-top-badge] {\n\tmargin-top: -3px;\n}\n*/\n\n/** TODO: .top-unwrap-x надо вынести глобально в UI или добавить в стили для storybook */\n/*\n.top-menu.top-unwrap-x {\n\tpadding-right: var(--top-unwrap-x);\n\tpadding-left: var(--top-unwrap-x);\n\tmargin-right: calc(0px - var(--top-unwrap-x));\n\tmargin-left: calc(0px - var(--top-unwrap-x));\n}\n*/\n</style>\n","<script setup lang=\"ts\">\nimport type { EmitsItemMulti, PropsItemMulti } from './types';\n\ndefineProps<PropsItemMulti>();\ndefineEmits<EmitsItemMulti>();\n</script>\n\n<template>\n\t<div class=\"top-selector2_itemMulti top-ellipsis\">\n\t\t{{ name }}\n\n\t\t<span\n\t\t\tclass=\"top-selector2_itemMultiDelete\"\n\t\t\tdata-top-icon=\"\"\n\t\t\t@click=\"$emit('delete', {id, name})\"\n\t\t\t@mousedown.stop\n\t\t></span>\n\t</div>\n</template>\n\n<style>\n.top-selector2_itemMulti {\n\tbox-sizing: border-box;\n\tpadding-left: var(--top-padding-2);\n\tborder-radius: var(--top-radius-1, 4px);\n\tborder: 1px solid var(--color-line-primary-1);\n\tbackground: var(--color-layer-primary-2);\n\tmin-height: 22px;\n\tmax-width: 100%;\n\tcolor: var(--color-text-1);\n\tflex-grow: 0;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: var(--top-gap-1);\n}\n\n.top-selector2_itemMultiDelete {\n\t--top-icon-size: 14px;\n\t--top-icon-width: 18px;\n\t--top-icon-color: var(--color-text-1);\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\tcursor: pointer;\n}\n\n.top-selector2_itemMultiDelete:hover {\n\tbackground: var(--color-layer-primary-2);\n}\n\n@media screen and (min-width: 900px) {\n\t.top-selector2.top-active .top-selector2_itemMultiDelete {\n\t\tz-index: calc(var(--top-popup-z-index) + 1);\n\t}\n}\n</style>\n","import type { Props } from './types';\n\n/**\n * Список кешей для конкретного API метода\n */\nexport const cacheByMethod = new Map<Api.PathAbstract, Map<string, any>>();\n\n/**\n * Сброс кеша конкретного API метода\n */\nexport const clearCache = (apiPath: Api.PathAbstract) => {\n\tcacheByMethod.get(apiPath)?.clear();\n};\n\nexport const genCacheKey = (api: NonNullable<Props['api']>) => {\n\tconst userId = window['mo']?.user?.id;\n\n\tconst cacheKey = JSON.stringify(api.params) + ':' + api.url + ':' + userId;\n\n\treturn cacheKey;\n};\n\nexport const getCache = (cacheKey: string, apiPath: Api.PathAbstract) => {\n\treturn cacheByMethod.get(apiPath)?.get(cacheKey);\n};\n\nexport const setCache = (cacheKey: string, apiPath: Api.PathAbstract, data: any) => {\n\tif (!cacheByMethod.has(apiPath)) {\n\t\tcacheByMethod.set(apiPath, new Map());\n\t}\n\n\tcacheByMethod.get(apiPath)?.set(cacheKey, data);\n};\n","import { ref } from 'vue';\nimport { debounce } from '../../../../core/utils/lodash';\nimport type { Item, Props } from '../types';\nimport { genCacheKey, getCache, setCache } from '../cache';\n\nexport type API = ReturnType<typeof useAPI>;\n\nexport const useAPI = (\n\tapi: Props['api'],\n\tapiSetSearchParams: Props['apiSetSearchParams'],\n\tminLength: number,\n\tuseCache: Props['useCache'],\n) => {\n\t/**\n\t * Список, полученный через API\n\t */\n\tconst items = ref<Item[]>([]);\n\n\t/**\n\t * Флаг - идет загрузка\n\t */\n\tconst isLoading = ref(false);\n\n\tconst countLoading = ref(0);\n\n\tlet searchText = '';\n\tlet nextOffset: number | null | undefined;\n\n\tif (api && !api.params.limit) {\n\t\tapi.params.limit = 100;\n\t}\n\n\t/**\n\t * Выполнить обращение к API\n\t *\n\t * При ошибке вернет undefined\n\t */\n\tconst callAPI = async (): Promise<Api.ResponseSuccess<any, 'get'> | undefined> => {\n\t\tif (!api) return;\n\n\t\tconst cacheKey = useCache ? genCacheKey(api) : undefined;\n\n\t\tif (cacheKey) {\n\t\t\tconst cache = getCache(cacheKey, api.path);\n\t\t\tif (cache) {\n\t\t\t\t// остановить запущенные api запросы\n\t\t\t\tapi.abortByFingerprint();\n\n\t\t\t\treturn cache;\n\t\t\t}\n\t\t}\n\n\t\tconst res = await api.call();\n\n\t\tif (res.errors) return;\n\n\t\tif (!Array.isArray(res.result)) {\n\t\t\tconsole.warn('Array expected in `res.result`');\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst indexWithError = (res.result as Array<Item | any>).findIndex(item => item.id === undefined || item.name === undefined);\n\t\tif (indexWithError !== -1) {\n\t\t\tconsole.warn(`В result[${indexWithError}] нет id или name`);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (cacheKey) {\n\t\t\tsetCache(cacheKey, api.path, res);\n\t\t}\n\n\t\treturn res as Api.ResponseSuccess<any, 'get'>;\n\t};\n\n\t/**\n\t * Загрузить items\n\t */\n\tconst load = async (append: boolean) => {\n\t\tif (!api) return;\n\n\t\tif (append) {\n\t\t\t// данных о следующих страницах не обнаружено\n\t\t\tif (!nextOffset) return;\n\n\t\t\t// дозагружать нельзя, если не завершена предыдущая загрузка\n\t\t\tif (isLoading.value) return;\n\n\t\t\tapi.params.offset = nextOffset;\n\t\t} else {\n\t\t\tapi.params.offset = 0;\n\t\t}\n\n\t\tapiSetSearchParams?.(api, searchText);\n\n\t\tisLoading.value = true;\n\t\tconst res = await callAPI();\n\t\tisLoading.value = false;\n\n\t\tcountLoading.value++;\n\n\t\tif (!res) return;\n\n\t\tnextOffset = res.nextOffset;\n\n\t\tif (append) {\n\t\t\titems.value = items.value.concat(res.result);\n\t\t} else {\n\t\t\titems.value = res.result;\n\t\t}\n\t};\n\n\tconst loadDebounce = debounce(() => load(false), 200);\n\n\t/**\n\t * Выполнить поиск по указанному тексту\n\t *\n\t * Если длина текста меньше minLength, поиск не будет произведен\n\t *\n\t * Если текст не изменился, поиск не будет произведен\n\t *\n\t * @param newSearchText - текст поиска\n\t * @param useDebounce - дедупликация загрузки списка\n\t */\n\tconst setSearchTextAndLoad = (newSearchText: string, useDebounce = true) => {\n\t\tif (!api) return;\n\n\t\t// остановить начатый поиск и сбросить результаты\n\t\tif (newSearchText.length < minLength) {\n\t\t\tapi.abortByFingerprint();\n\n\t\t\titems.value = [];\n\n\t\t\treturn;\n\t\t}\n\n\t\t// условия поиска не поменялись, данные загружены\n\t\tif (newSearchText === searchText && items.value.length) return;\n\n\t\tsearchText = newSearchText;\n\n\t\tif (useDebounce) {\n\t\t\tvoid loadDebounce();\n\t\t} else {\n\t\t\tvoid load(false);\n\t\t}\n\t};\n\n\treturn {\n\t\tapiRequest: api,\n\t\titems,\n\t\tisLoading,\n\t\tcountLoading,\n\t\tload,\n\t\tsetSearchTextAndLoad,\n\t};\n};\n","import type { Item, Props } from './types';\nimport { genFieldFilter } from '@/api/api';\n\n/**\n * Универсальный id для всех элементов \"Все элементы\" / \"Без фильтра\" в `TopSelector`\n */\nexport const ITEM_ID_ALL = 0;\n\n/**\n * Универсальный id для всех добавляемых элементов через `TopSelector`\n */\nexport const ITEM_ID_NEW = null;\n\n/**\n * Выбран ли элемент\n */\nexport const isSelected = (modelValue: Props['modelValue'], item: Item, checkNameForNullId = true) => {\n\tif (checkNameForNullId && item.id === ITEM_ID_NEW) {\n\t\tif (Array.isArray(modelValue)) {\n\t\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id && itemSelected.name === item.name);\n\t\t} else {\n\t\t\treturn item.name === modelValue.name;\n\t\t}\n\t}\n\n\tif (Array.isArray(modelValue)) {\n\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id);\n\t} else {\n\t\treturn item.id === modelValue.id;\n\t}\n};\n\n/**\n * Вспомогательная утилита для создания `callback` функции на добавление фильтра по полю в api запрос\n *\n * Другие фильтры по указанному полю будут удалены\n *\n * @param api - api, которое используется в `TopSelector`\n * @param search - введенная строка поиска\n * @param fieldName - имя поля, по которому надо добавить фильтр на поиск по нестрогому соответствию\n */\nexport const apiSetSearchParamsFilter = (api: NonNullable<Props['api']>, search: string, fieldName: string) => {\n\tlet filters = api.params.filters ?? [];\n\n\t// удаление других фильтров по этому полю\n\tfilters = filters.filter((filter) => filter.name !== fieldName);\n\n\tif (search) {\n\t\tfilters.push(genFieldFilter(fieldName, 'CONTAINS', [search]));\n\t}\n\n\tapi.changeParams({ filters });\n};\n","import { computed, type ComputedRef, ref, type Ref, watch } from 'vue';\nimport { invertKeyboardLayout } from '@/core/utils/keyboard';\nimport type { Item, Props } from '../types';\nimport { type API } from './useAPI';\nimport { isSelected, ITEM_ID_ALL, ITEM_ID_NEW } from '../utils';\nimport { useI18n } from '@/core/plugins/i18n';\n\n/**\n * Функционал поиска\n */\nexport const useMenu = (\n\tmodel: Ref<Props['modelValue']>,\n\temits: ReturnType<typeof defineEmits>,\n\titems: Ref<Props['items']>,\n\tmultiselect: Props['multiselect'],\n\tuseAllItem: Ref<Props['useAllItem']>,\n\tappendSearchToResult: Ref<Props['appendSearchToResult']>,\n\tsearchType: Ref<Props['searchType']>,\n\tminLength: number,\n\tapi: API,\n) => {\n\t/**\n\t * Текст поиска по результатам\n\t */\n\tconst searchText = ref('');\n\n\t/**\n\t * Объект, представляющий опцию \"Все\"\n\t */\n\tconst itemAll = {\n\t\tid: ITEM_ID_ALL,\n\t\tname: useI18n().Common.All as string,\n\t};\n\n\t/**\n\t * Сброс поиска\n\t */\n\tconst resetSearch = () => {\n\t\tsearchText.value = '';\n\t};\n\n\t/**\n\t * Является ли строка поиска достаточной длины для отображения меню\n\t */\n\tconst genIsShort = () => {\n\t\tif (!api.apiRequest) return false;\n\t\tif (searchText.value.length >= minLength) return false;\n\n\t\treturn true;\n\t};\n\n\t/**\n\t * Варианты выбора: props.items + \"Выбрать все\"\n\t */\n\tconst localItems: ComputedRef<Item[]> = computed(() => {\n\t\tconst localItems: Item[] = [];\n\n\t\tif (!multiselect && useAllItem.value) {\n\t\t\tif (typeof useAllItem.value === 'string') {\n\t\t\t\titemAll.name = useAllItem.value;\n\t\t\t}\n\n\t\t\tlocalItems.push(itemAll);\n\t\t}\n\n\t\titems.value?.forEach(item => localItems.push({ ...item }));\n\n\t\treturn localItems;\n\t});\n\n\t/**\n\t * Не используем `computed` в пользу ручного порядка пересчета значения\n\t */\n\tconst itemsForShow = ref<Item[]>([]);\n\n\tconst recalcItemsForShow = () => {\n\t\titemsForShow.value = genItemsForShow();\n\t};\n\n\t/**\n\t * Подготовленный список меню, который содержит в сумме:\n\t * - prop.items: указанный список с учетом фильтра и опций компонента\n\t * - api.items: результаты api запроса, если используется api\n\t *\n\t * @returns Отфильтрованный массив элементов для отображения\n\t */\n\tconst genItemsForShow = () => {\n\t\tconst searchString = searchText.value.toLowerCase();\n\t\tconst searchStringInvertKeyboard = invertKeyboardLayout(searchString);\n\n\t\tlet items: Item[] = [];\n\n\t\t/**\n\t\t * Элемент текущего разделителя в цикле\n\t\t *\n\t\t * Для скрытия / отображения только нужных заголовков и разделителей при поиске\n\t\t *\n\t\t * Логика для `api.items` должна реализовываться в api или api клиенте при генерации элементов\n\t\t */\n\t\tlet itemTitleCategory: Item | undefined;\n\t\tconst itemsCategory: Item[] = [];\n\n\t\t/**\n\t\t * Добавить элементы в результирующий список\n\t\t */\n\t\tconst flushCategory = () => {\n\t\t\t// крайний разделитель не выводить\n\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') {\n\t\t\t\titemsCategory.pop();\n\t\t\t}\n\n\t\t\tif (itemsCategory.length) {\n\t\t\t\tif (itemTitleCategory) {\n\t\t\t\t\titems.push(itemTitleCategory);\n\t\t\t\t}\n\n\t\t\t\titems.push(...itemsCategory);\n\n\t\t\t\titemsCategory.length = 0;\n\t\t\t}\n\t\t};\n\n\t\tfor (const item of localItems.value) {\n\t\t\tswitch (item.listItemProps?.type) {\n\t\t\t\tcase 'title':\n\t\t\t\t\tflushCategory();\n\n\t\t\t\t\titemTitleCategory = item;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'delimiter':\n\t\t\t\t\t// вставить разделитель один раз и только если категория не пуста\n\t\t\t\t\tif (itemsCategory.length) {\n\t\t\t\t\t\tlet index = itemsCategory.length;\n\t\t\t\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') index--;\n\n\t\t\t\t\t\titemsCategory[index] = item;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tconst name = item.name.toLowerCase();\n\t\t\t\t\tif (\n\t\t\t\t\t\titem.id === Number(searchString) ||\n\t\t\t\t\t\tname.includes(searchString) ||\n\t\t\t\t\t\tname.includes(searchStringInvertKeyboard)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (name === searchString || name === searchStringInvertKeyboard) {\n\t\t\t\t\t\t\t// точные совпадения в начало\n\t\t\t\t\t\t\titemsCategory.unshift(item);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titemsCategory.push(item);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tflushCategory();\n\n\t\titems.push(...api.items.value);\n\n\t\t// ввод произвольного значения\n\t\tif (\n\t\t\tappendSearchToResult.value &&\n\t\t\t!!searchText.value &&\n\n\t\t\t// результаты могут быть найдены, но не точные, тогда предложить добавить элемент\n\t\t\t!items.find((item) => item.name.toLowerCase() === searchString)\n\t\t) {\n\t\t\tconst itemNew = {\n\t\t\t\tid: ITEM_ID_NEW,\n\t\t\t\tname: searchText.value,\n\t\t\t};\n\n\t\t\t// предложение всегда отображается внизу, чтобы не мешать результатам поиска\n\t\t\titems.push(itemNew);\n\t\t}\n\n\t\tif (multiselect) {\n\t\t\titems = items.filter(item => !isSelected(model.value, item));\n\t\t}\n\n\t\treturn items;\n\t};\n\n\t/**\n\t * Выбрать элемент\n\t *\n\t * @param item Элемент для выбора\n\t */\n\tconst selectItem = (item: Item) => {\n\t\t// это невыбираемый элемент\n\t\tif (item.listItemProps?.type === 'title' || item.listItemProps?.type === 'delimiter') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (multiselect && Array.isArray(model.value)) {\n\t\t\tif (!isSelected(model.value, item)) {\n\t\t\t\tmodel.value = [...model.value, item];\n\t\t\t}\n\t\t} else {\n\t\t\tmodel.value = item;\n\t\t}\n\n\t\tif (item.id === ITEM_ID_NEW) {\n\t\t\temits('appendItem', item);\n\t\t}\n\n\t\t/**\n\t\t * Отложить перерисовку\n\t\t *\n\t\t * fix: Перерисовка меню выполняется раньше, чем срабатывает `click`.\n\t\t * Из-за этого обработчик кликов думает, что клик был вне меню и не закрывает окно\n\t\t *\n\t\t * Файл: @/components/popup/lib/popup.globalEvents.ts\n\t\t *\n\t\t * Функция: onclick()\n\t\t *\n\t\t * ```\n\t\t * const elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\t\t * ```\n\t\t */\n\t\tsetTimeout(() => {\n\t\t\t/**\n\t\t\t * Завершить поиск после выбора\n\t\t\t */\n\t\t\tresetSearch();\n\t\t});\n\n\t\t// /**\n\t\t// * При изменении значения модели в режиме inline необходимо очистить поле поиска,\n\t\t// * так как поиск больше не актуален после выбора значения\n\t\t// */\n\t\t// if (searchType.value === 'inline') {\n\t\t// \tresetSearch();\n\t\t// }\n\t};\n\n\tif (api.apiRequest) {\n\t\t// загрузка только при открытии popup\n\t\tconst fieldsForWatch: any = [items, api.items];\n\n\t\t// model нужен только для multiselect, без необходимости не использовать для улучшения UX при работе с API\n\t\tif (multiselect) {\n\t\t\tfieldsForWatch.push(model);\n\t\t}\n\n\t\twatch(fieldsForWatch, () => {\n\t\t\trecalcItemsForShow();\n\t\t});\n\t} else {\n\t\twatch([model, items, searchText], () => {\n\t\t\trecalcItemsForShow();\n\t\t}, {\n\t\t\timmediate: true,\n\n\t\t\t// слежение за изменениями `items`\n\t\t\tdeep: 2,\n\t\t});\n\t}\n\n\t/**\n\t * Выбрать следующее значение\n\t */\n\tconst selectNextItem = () => {\n\t\tif (Array.isArray(model.value)) return;\n\n\t\tconst selectableItems = itemsForShow.value.filter((item) => !['title', 'delimiter'].includes(item.listItemProps?.type ?? ''));\n\n\t\tconst currentIndex = selectableItems.findIndex(item => item.id === (model.value as Item).id);\n\t\tconst nextIndex = (currentIndex + 1) % selectableItems.length;\n\t\tmodel.value = { ...selectableItems[nextIndex] };\n\t};\n\n\t/**\n\t * Удалить элемент, `id` и `name` которого равны указанному `item`\n\t */\n\tconst deleteItemByItem = async (item: Item) => {\n\t\tif (Array.isArray(model.value)) {\n\t\t\tmodel.value = model.value.filter((itemI) => itemI.id !== item.id || itemI.name !== item.name);\n\t\t}\n\t};\n\n\treturn {\n\t\tsearchText,\n\t\tresetSearch,\n\t\tgenIsShort,\n\t\titemsForShow,\n\t\tselectItem,\n\t\tselectNextItem,\n\t\tdeleteItemByItem,\n\t};\n};\n","<script setup lang=\"ts\">\nimport { computed, ref, toRef, watch } from 'vue';\nimport Core from '@/core/core/core';\nimport { TopPopup, TopPopupListItem, TopPopupWidgetInput } from '@/components/popup/popup';\nimport { TopPreloader } from '@/components/forms/forms';\nimport type { Emits, Item, Props, Slots } from './types';\nimport Selector2ItemMulti from './itemMulti.vue';\nimport { useAPI } from './composables/useAPI';\nimport { useMenu } from './composables/useMenu';\nimport type { TopLibPopup } from '../../popup/lib/popup';\nimport { clearCache } from './cache';\nimport { ITEM_ID_ALL, ITEM_ID_NEW } from './utils';\n\nconst props = withDefaults(defineProps<Props>(), {\n\titems: () => [] as Item[],\n\tsize: 's',\n\tminLength: 0,\n\tsearchType: 'popup',\n\topenByFocusInput: undefined,\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\ndefineSlots<Slots>();\n\nconst emits = defineEmits<Emits>();\n\ndefineExpose({\n\t/**\n\t * Сброс локального кеша и кеша api\n\t *\n\t * @param resetAPICache - Сбросить API кеш, по умолчанию не сбрасывается. Для случаев, когда загруженные данные становятся неактуальными\n\t */\n\tresetCache: (resetAPICache: boolean = false) => {\n\t\tif (!api.apiRequest) return;\n\n\t\t// сброс кеша api\n\t\tif (resetAPICache) {\n\t\t\tclearCache(api.apiRequest.path);\n\t\t}\n\n\t\t// сброс кеша списка\n\t\tapi.items.value = [];\n\n\t\t// сброс флага первичной загрузки\n\t\tapi.countLoading.value = 0;\n\n\t\t// сброс параметров дозагрузки\n\t\tapi.apiRequest.params.offset = 0;\n\n\t\t// сброс кеша локального списка с дополнительными элементами, например `useAllItem`\n\t\trequestAnimationFrame(() => {\n\t\t\tmenu.itemsForShow.value = [];\n\t\t});\n\n\t\t// сразу загрузить данные после сброса, если popup уже открыт\n\t\tif (getPopup()?.elPopup) {\n\t\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t\t}\n\t},\n});\n\nconst searchTypeLocal = computed(() => {\n\t// multiselect не поддерживает inline ввода\n\tif (props.searchType === 'inline' && props.multiselect) return 'popup';\n\n\t// В мобильной версии popup работает в полноэкранном режиме\n\tif (props.searchType === 'inline' && Core.state.isMobile) return 'popup';\n\n\treturn props.searchType;\n});\n\n/**\n * Объект для работы с API\n */\nconst api = useAPI(props.api, props.apiSetSearchParams, props.minLength, props.useCache);\n\n/**\n * Объект для работы с меню\n */\nconst menu = useMenu(\n\tmodel,\n\temits,\n\ttoRef(props, 'items'),\n\tprops.multiselect,\n\ttoRef(props, 'useAllItem'),\n\ttoRef(props, 'appendSearchToResult'),\n\tsearchTypeLocal,\n\tprops.minLength,\n\tapi,\n);\n\nconst component = computed(() => {\n\tif (props.buttonProps) return 'TopButton';\n\tif (searchTypeLocal.value === 'inline') return 'TopInput';\n\n\treturn 'div';\n});\n\n/**\n * Экземпляр компонента Popup\n */\nconst popupRef = ref<any>(null);\n\n/**\n * Получить доступ к объекту popup\n */\nconst getPopup = (): TopLibPopup | undefined => {\n\treturn popupRef.value?.popup;\n};\n\nif (api.apiRequest) {\n\t// отложенный поиск при вводе текста\n\twatch(menu.searchText, () => {\n\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t});\n}\n\nconst placeholder = computed(() => {\n\tif (Array.isArray(model.value) || props.multiselect || !props.selectedAsPlaceholder && searchTypeLocal.value !== 'inline') {\n\t\treturn props.placeholder;\n\t}\n\n\treturn model.value?.name || props.placeholder;\n});\n\n/**\n * Обработчик ввода клавиш на кнопке или поле ввода\n */\nconst onOpenerKeydown = (e: KeyboardEvent) => {\n\tlet needOpen = false;\n\n\tswitch (e.key) {\n\t\tcase 'Delete':\n\t\tcase 'Backspace':\n\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\n\t\t\t\tmodel.value.pop();\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'ArrowUp':\n\t\tcase 'ArrowRight':\n\t\tcase 'ArrowDown':\n\t\tcase 'ArrowLeft':\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\t\tneedOpen = true;\n\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\tif (searchTypeLocal.value === 'inline') {\n\t\t\t\t// очистка введенного текста\n\t\t\t\tmenu.resetSearch();\n\t\t\t}\n\n\t\t\tbreak;\n\t}\n\n\t// введен символ\n\tconst symbolPressed = e.key.length === 1 && !e.ctrlKey && !e.metaKey;\n\n\t// введен символ\n\tif (searchTypeLocal.value === 'popup' || searchTypeLocal.value === 'inline') {\n\t\tif (symbolPressed) {\n\t\t\tneedOpen = true;\n\t\t}\n\t}\n\n\t// popup уже открыт\n\tif (getPopup()?.elPopup) {\n\t\tneedOpen = false;\n\t}\n\n\tif (needOpen) {\n\t\tif (searchTypeLocal.value === 'popup') {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// введен символ\n\t\t\tif (symbolPressed) {\n\t\t\t\t// начало ввода, сразу ввести первый символ вместе с открытием popup\n\t\t\t\tif (!menu.searchText.value) {\n\t\t\t\t\tmenu.searchText.value = e.key;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t(e.currentTarget as HTMLElement)?.click();\n\t}\n};\n\nconst onClickChanger = (e: MouseEvent) => {\n\te.preventDefault();\n\n\tmenu.selectNextItem();\n};\n\n/**\n * Обработчик открытия попапа\n */\nconst onOpen = () => {\n\tif (api.apiRequest) {\n\t\t// при открытии сразу выполнить поиск\n\t\tapi.setSearchTextAndLoad(menu.searchText.value, false);\n\t}\n};\n\n/**\n * Обработчик закрытия попапа\n */\nconst onClose = () => {\n\t// очистка введенного текста, в режиме `inline` input вызывается при `blur`\n\tif (searchTypeLocal.value === 'popup') {\n\t\tif (menu.searchText.value) menu.resetSearch();\n\t}\n};\n\n/**\n * Обработчик прокрутки списка контента\n *\n * Для дозагрузки элеменов через api\n *\n * @param {Event} e - Событие прокрутки\n */\nconst onScrollContentList = (e: Event) => {\n\tconst el = e.target as HTMLElement;\n\n\tif (el.scrollTop / (el.scrollHeight - el.offsetHeight) > 0.8) {\n\t\tapi.load(true);\n\t}\n};\n\nif (import.meta.env.STORYBOOK) {\n\twatch(\n\t\t() => props.multiselect,\n\t\t() => {\n\t\t\tif (props.multiselect) {\n\t\t\t\tif (!Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tname: 'Выбери меня',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = {\n\t\t\t\t\t\tid: null,\n\t\t\t\t\t\tname: '',\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ immediate: true },\n\t);\n\n\twatch(\n\t\t() => props.searchType,\n\t\t() => {\n\t\t\t// пауза для установки props в адресной строке\n\t\t\tsetTimeout(() => {\n\t\t\t\tlocation.reload();\n\t\t\t}, 500);\n\t\t},\n\t);\n}\n</script>\n\n<template>\n\t<TopPopup\n\t\tref=\"popupRef\"\n\t\t@open=\"onOpen()\"\n\t\t@close=\"onClose()\"\n\t\t@scrollContentList=\"api ? onScrollContentList($event) : undefined\"\n\t\t:notch=\"false\"\n\t\t:transitionDuration=\"0\"\n\t\t:openByFocusInput=\"searchTypeLocal === 'inline' && (openByFocusInput ?? true)\"\n\t\t:disabled=\"searchTypeLocal === 'inline' && menu.genIsShort()\"\n\t>\n\t\t<template #opener>\n\t\t\t<component\n\t\t\t\t:is=\"component\"\n\n\t\t\t\t:=\"buttonProps\"\n\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-selector2': true,\n\t\t\t\t\t'top-selector2-multiselect': multiselect,\n\t\t\t\t\t['top-selector2-' + modificator]: !!modificator,\n\t\t\t\t\t'top-as-input': !buttonProps && searchTypeLocal !== 'inline',\n\t\t\t\t\t'top-as-selector': true,\n\t\t\t\t\t['top-size_' + size]: true,\n\t\t\t\t\t['top-disabled']: disabled,\n\t\t\t\t\t['top-forms-focusable']: !disabled,\n\t\t\t\t\t['top-error']: isError,\n\t\t\t\t}\"\n\t\t\t\t:icon\n\t\t\t\ttabindex=\"0\"\n\t\t\t\t@keydown=\"onOpenerKeydown\"\n\t\t\t\t@blur=\"searchTypeLocal === 'inline' && menu.resetSearch()\"\n\t\t\t\tv-top-focus.onupdate=\"isError\"\n\n\t\t\t\t:placeholder\n\t\t\t\t:title\n\t\t\t\t:captionType=\"searchTypeLocal === 'inline' && title !== undefined ? 'top' : undefined\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t>\n\t\t\t\t<template v-if=\"multiselect\">\n\t\t\t\t\t<div class=\"top-selector2_activeItems\">\n\t\t\t\t\t\t<Selector2ItemMulti\n\t\t\t\t\t\t\tv-for=\"item of model as Item[]\"\n\t\t\t\t\t\t\t:id=\"item.id\"\n\t\t\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t\t\t\t@delete=\"menu.deleteItemByItem\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<span v-if=\"searchTypeLocal !== 'inline' && !multiselect\" class=\"top-selector2_activeName top-ellipsis\">\n\t\t\t\t\t{{ !Array.isArray(model) ? model.name : '' }}\n\t\t\t\t</span>\n\n\t\t\t\t<span v-if=\"multiselect && !model.length\" class=\"top-selector2_placeholder top-ellipsis\">\n\t\t\t\t\t{{ placeholder }}\n\t\t\t\t</span>\n\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"addChanger && !buttonProps && !multiselect && menu.itemsForShow.value.length > 1 && !disabled\"\n\t\t\t\t\tclass=\"top-changer top-changer-selector\"\n\t\t\t\t\tdata-top-popup-disabled=\"true\"\n\t\t\t\t\t@click=\"onClickChanger\"\n\t\t\t\t></span>\n\t\t\t</component>\n\t\t</template>\n\n\t\t<template #widget v-if=\"searchTypeLocal === 'popup'\">\n\t\t\t<TopPopupWidgetInput\n\t\t\t\ttitle=\"Поиск\"\n\t\t\t\ticon=\"\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t\tv-top-focus.onupdate=\"model\"\n\t\t\t\t:isLoading=\"!!api.countLoading.value && api.isLoading.value\"\n\t\t\t\t:placeholder\n\t\t\t/>\n\t\t</template>\n\n\t\t<template #contentList>\n\t\t\t<TopPopupListItem\n\t\t\t\tv-for=\"item of menu.itemsForShow.value\"\n\t\t\t\t:key=\"item.id ?? undefined\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-active': !Array.isArray(model) && !multiselect && model.id === item.id && model.name === item.name,\n\t\t\t\t\t'top-selector2_item-all':item.id === ITEM_ID_ALL,\n\t\t\t\t\t'top-selector2_item-new':item.id === ITEM_ID_NEW,\n\t\t\t\t}\"\n\t\t\t\t:=\"item.listItemProps\"\n\t\t\t\t:closeByClick=\"!multiselect || Core.state.isMobile\"\n\t\t\t\t@click=\"menu.selectItem(item)\"\n\t\t\t>\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"$slots.item\"\n\t\t\t\t\tname=\"item\"\n\t\t\t\t\t:item\n\t\t\t\t></slot>\n\n\t\t\t\t<template\n\t\t\t\t\tv-else\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</template>\n\t\t\t</TopPopupListItem>\n\n\t\t\t<!-- Элементов для отображения нет -->\n\t\t\t<template v-if=\"!menu.itemsForShow.value.length && !menu.genIsShort()\">\n\t\t\t\t<TopPopupListItem type=\"regular\">\n\t\t\t\t\t<template v-if=\"!api.isLoading.value || api.countLoading.value\">\n\t\t\t\t\t\t{{ $i18n.Common.No_results }}\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<!-- Индикатор первичной загрузки -->\n\t\t\t\t\t<TopPreloader\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"circles\"\n\t\t\t\t\t/>\n\t\t\t\t</TopPopupListItem>\n\t\t\t</template>\n\n\t\t\t<!-- Индикатор повторной загрузки -->\n\t\t\t<TopLoadbar v-if=\"!!api.countLoading.value && api.isLoading.value && searchTypeLocal === 'inline'\"/>\n\t\t</template>\n\t</TopPopup>\n</template>\n\n<style>\n.top-selector2 {\n\twidth: 180px;\n}\n\n.top-selector2::placeholder,\n.top-selector2_placeholder {\n\tcolor: var(--color-text-2);\n}\n\n.top-selector2_placeholder {\n\tpadding-left: var(--top-padding-1);\n}\n\n.top-selector2.top-as-input {\n\tpadding: var(--top-padding-1) var(--top-forms-padding);\n}\n\n.top-selector2.top-selector2-multiselect {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tflex-grow: 1;\n}\n\n.top-selector2.top-active {\n\t--top-forms-border-color: var(--top-forms-border-color-hover);\n}\n\n.top-selector2_activeItems {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--top-padding-1);\n\tmax-width: 100%;\n}\n\n.top-selector2_activeName {\n\twhite-space: nowrap;\n}\n\n.top-changer-selector {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tmargin: calc(0px - var(--top-padding-1));\n\ttransform: translateX(0);\n}\n\n.top-selector2.top-button {\n\tjustify-content: start;\n}\n\n.top-selector2.top-input_input ~ .top-changer-selector {\n\ttransform: translateX(-52px);\n}\n\n.top-selector2.top-as-selector {\n\tpadding-right: calc(var(--top-selector-arrow-width) + var(--top-padding-2));\n}\n</style>\n"],"names":["props","__props","model","_useModel","el","ref","itemIsActive","item","select","toggle","modelNew","index","onWheel","event","delta","scrollIntoView","isSmooth","elBtn","gap","leftMargin","rightMargin","leftMarginParent","rightMarginParent","scrollLeft","isSafari","Core","selectAll","onMounted","onUpdated","_createElementBlock","_normalizeClass","_Fragment","_renderList","_createBlock","TopButton","_mergeProps","$event","_createTextVNode","_toDisplayString","_openBlock","_hoisted_1","_createVNode","_createElementVNode","_cache","$emit","cacheByMethod","clearCache","apiPath","genCacheKey","api","userId","getCache","cacheKey","setCache","data","useAPI","apiSetSearchParams","minLength","useCache","items","isLoading","countLoading","searchText","nextOffset","callAPI","cache","res","indexWithError","load","append","loadDebounce","debounce","newSearchText","useDebounce","ITEM_ID_ALL","ITEM_ID_NEW","isSelected","modelValue","checkNameForNullId","itemSelected","apiSetSearchParamsFilter","search","fieldName","filters","filter","genFieldFilter","useMenu","emits","multiselect","useAllItem","appendSearchToResult","searchType","itemAll","useI18n","resetSearch","genIsShort","localItems","computed","itemsForShow","recalcItemsForShow","genItemsForShow","searchString","searchStringInvertKeyboard","invertKeyboardLayout","itemTitleCategory","itemsCategory","flushCategory","name","itemNew","selectItem","fieldsForWatch","watch","selectableItems","nextIndex","itemI","__emit","__expose","resetAPICache","menu","getPopup","searchTypeLocal","toRef","component","popupRef","placeholder","onOpenerKeydown","e","needOpen","symbolPressed","onClickChanger","onOpen","onClose","onScrollContentList","_unref","TopPopup","_withDirectives","_resolveDynamicComponent","Selector2ItemMulti","_hoisted_2","_hoisted_3","$slots","_renderSlot","_ctx","TopPopupListItem","$i18n","TopPreloader","_component_TopLoadbar","TopPopupWidgetInput"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,UAAMA,IAAQC,GAIRC,IAAQC,kBAEb,GAEKC,IAAKC,EAAA;AAGX,IAAI,CAACL,EAAM,cAAc,OAAQE,EAAM,SAAW,YAAY,OAAQA,EAAM,SAAW,YACtF,QAAQ,KAAK,+DAA+D,OAAQA,EAAM,KAAM,GAI7FF,EAAM,cAAc,CAAC,MAAM,QAAQE,EAAM,KAAK,KACjD,QAAQ,KAAK,8DAA8D,OAAQA,EAAM,KAAM,GAQ5FF,EAAM,cAAc,CAACA,EAAM,sBAAsB,MAAM,QAAQE,EAAM,KAAK,KAAK,CAACA,EAAM,MAAM,UAAUF,EAAM,MAAM,CAAC,MACtHE,EAAM,QAAQ,CAACF,EAAM,MAAM,CAAC,GAAG,QAAQA,EAAM,MAAM,CAAC,GAAG,KAAK;AAG7D,UAAMM,IAAe,CAACC,MAChB,MAAM,QAAQL,EAAM,KAAK,IAIvBA,EAAM,MAAM,SAASK,EAAK,KAAK,IAH9BA,EAAK,UAAUL,EAAM,OAWxBM,IAAS,CAACD,GAAYE,IAAS,OAAU;AAC9C,UAAI,MAAM,QAAQP,EAAM,KAAK,GAAG;AAC/B,YAAIQ,IAAWR,EAAM,MAAM,MAAA;AAE3B,YAAIO,GAAQ;AACX,UAAKC,EAAS,WAAQA,IAAWV,EAAM,MAAM,IAAI,CAAAO,MAAQA,EAAK,KAAK;AAEnE,gBAAMI,IAAQD,EAAS,QAAQH,EAAK,KAAK;AACzC,UAAII,MAAU,KACbD,EAAS,KAAKH,EAAK,KAAK,IAExBG,EAAS,OAAOC,GAAO,CAAC;AAAA,QAE1B;AACC,UAAID,EAAS,WAAW,KAAKA,EAAS,CAAC,MAAMH,EAAK,QACjDG,IAAW,CAAA,IAEXA,IAAW,CAACH,EAAK,KAAK;AAIxB,QAAI,CAACP,EAAM,sBAAsB,CAACU,EAAS,WAAQA,IAAW,CAACH,EAAK,KAAK,IAEzEL,EAAM,QAAQQ;AAEd;AAAA,MACD;AAEA,MAAAR,EAAM,QAAQK,EAAK;AAAA,IACpB,GAGMK,IAAU,CAACC,MAAsB;AAGtC,UAFIT,EAAG,MAAM,eAAeA,EAAG,MAAM,eACjCS,EAAM,YACN,KAAK,IAAIA,EAAM,MAAM,IAAI,GAAI;AAEjC,MAAAA,EAAM,eAAA;AAEN,YAAMC,IAAQD,EAAM,SAAS,IAAI,KAAK;AACtC,MAAAT,EAAG,MAAM,aAAaA,EAAG,MAAM,aAAaU;AAAA,IAC7C,GASMC,IAAiB,CAACC,IAAW,OAAS;AAC3C,YAAMC,IAAQb,EAAG,MAAM,cAAc,aAAa;AAClD,UAAI,CAACa,EAAO;AAEZ,YAAMC,IAAM,IAGNC,IAAaF,EAAM,aAAab,EAAG,MAAM,aAAac,GACtDE,IAAcH,EAAM,aAAab,EAAG,MAAM,aAAaa,EAAM,cAAcC,GAG3EG,IAAmBjB,EAAG,MAAM,YAC5BkB,IAAoBlB,EAAG,MAAM,cAAcA,EAAG,MAAM;AAE1D,UAAImB;AAGJ,MAAIJ,IAAaE,MAAkBE,IAAaJ,IAG5CC,IAAcE,MAAmBC,IAAaH,IAAchB,EAAG,MAAM,cAErEmB,MAAe,WACdC,OACHC,EAAK,IAAIrB,EAAG,KAAK,EAAE,QAAQ,EAAE,YAAAmB,KAA0BP,IAAW,MAAM,CAAC,IAEzEZ,EAAG,MAAM,SAAS,EAAE,MAAMmB,GAAY,UAAUP,IAAW,WAAW,QAAQ;AAAA,IAGjF,GAKMU,IAAY,MAAM;AACvB,UAAK,MAAM,QAAQxB,EAAM,KAAK,GAE9B;AAAA,YAAIA,EAAM,MAAM,WAAWF,EAAM,MAAM,QAAQ;AAC9C,UAAAE,EAAM,QAAQ,CAACF,EAAM,MAAM,CAAC,EAAE,QAAQA,EAAM,MAAM,CAAC,EAAE,KAAK;AAC1D;AAAA,QACD;AAEA,QAAAE,EAAM,QAAQF,EAAM,MAAM,IAAI,OAAQO,EAAK,QAAQA,EAAK,KAAK;AAAA;AAAA,IAC9D;AAEA,WAAAoB,GAAU,MAAMZ,EAAe,EAAK,CAAC,GACrCa,GAAU,MAAMb,EAAe,EAAI,CAAC,mBAKnCc,EAuCM,OAAA;AAAA,eAtCD;AAAA,MAAJ,KAAIzB;AAAA,MACH,OAAK0B,GAAA;AAAA;wBAA4C7B,EAAA,OAAO,GAAA;AAAA;AAAA,MAAA;MAKxD,SAAAW;AAAA,IAAA;cAEDiB,EAWYE,GAAA,MAAAC,EAVI/B,EAAA,OAAK,CAAbM,YADR0B,EAWYC,GAXZC,EAWY,EAAA,SAAA,GAAA,GATR5B,GAAI;AAAA,QACP,OAAM;AAAA,QACN,OAAM;AAAA,QACL,SAAK,CAAA6B,MAAE5B,EAAOD,GAAM6B,EAAO,WAAWA,EAAO,OAAO;AAAA,QACpD,UAAU9B,EAAaC,CAAI;AAAA,MAAA;QAEHA,EAAK;gBAAnB;AAAA,gBACV,MAAkB;AAAA,YAAf8B,EAAAC,EAAA/B,EAAK,OAAO,GAAA,CAAA;AAAA,UAAA;;;;MAKV,MAAM,QAAQL,EAAA,KAAK,KAAKD,EAAA,iBAD/BsC,EAAA,GAAAV,EAgBM,OAhBNW,IAgBM;AAAA,QAZLC,GAWYP,GAXZC,EAWYlC,EAAA,eAVK;AAAA,UAChB,OAAM;AAAA,UACN,OAAM;AAAA,UACN,SAAQ;AAAA,UACP,gCAAOyB;UACP,UAAUxB,EAAA,MAAM,WAAWD,EAAA,MAAM;AAAA,QAAA;UAETA,EAAA,cAAc;kBAA5B;AAAA,kBACV,MAA2B;AAAA,cAAxBoC,EAAAC,EAAArC,EAAA,cAAc,OAAO,GAAA,CAAA;AAAA,YAAA;;;;;;;;;;;;;;;sBCjL5BsC,EAAA,GAAAV,EASM,OATNW,IASM;AAAA,MARFH,EAAAC,EAAArC,EAAA,IAAI,IAAG,KAEV,CAAA;AAAA,MAAAyC,GAKQ,QAAA;AAAA,QAJP,OAAM;AAAA,QACN,iBAAc;AAAA,QACb,SAAKC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAP,MAAEQ,EAAAA,MAAK,UAAA,EAAA,IAAY3C,EAAA,UAAIA,EAAA,MAAI;AAAA,QAChC,gCAAD,MAAA;AAAA,QAAA,GAAe,CAAA,MAAA,CAAA;AAAA,MAAA;;;ICVL4C,wBAAoB,IAAA,GAKpBC,KAAa,CAACC,MAA8B;AACxD,EAAAF,EAAc,IAAIE,CAAO,GAAG,MAAA;AAC7B,GAEaC,KAAc,CAACC,MAAmC;AAC9D,QAAMC,IAAS,OAAO,IAAO,MAAM;AAInC,SAFiB,KAAK,UAAUD,EAAI,MAAM,IAAI,MAAMA,EAAI,MAAM,MAAMC;AAGrE,GAEaC,KAAW,CAACC,GAAkBL,MACnCF,EAAc,IAAIE,CAAO,GAAG,IAAIK,CAAQ,GAGnCC,KAAW,CAACD,GAAkBL,GAA2BO,MAAc;AACnF,EAAKT,EAAc,IAAIE,CAAO,KAC7BF,EAAc,IAAIE,GAAS,oBAAI,IAAA,CAAK,GAGrCF,EAAc,IAAIE,CAAO,GAAG,IAAIK,GAAUE,CAAI;AAC/C,GCzBaC,KAAS,CACrBN,GACAO,GACAC,GACAC,MACI;AAIJ,QAAMC,IAAQtD,EAAY,EAAE,GAKtBuD,IAAYvD,EAAI,EAAK,GAErBwD,IAAexD,EAAI,CAAC;AAE1B,MAAIyD,IAAa,IACbC;AAEJ,EAAId,KAAO,CAACA,EAAI,OAAO,UACtBA,EAAI,OAAO,QAAQ;AAQpB,QAAMe,IAAU,YAAkE;AACjF,QAAI,CAACf,EAAK;AAEV,UAAMG,IAAWM,IAAWV,GAAYC,CAAG,IAAI;AAE/C,QAAIG,GAAU;AACb,YAAMa,IAAQd,GAASC,GAAUH,EAAI,IAAI;AACzC,UAAIgB;AAEH,eAAAhB,EAAI,mBAAA,GAEGgB;AAAA,IAET;AAEA,UAAMC,IAAM,MAAMjB,EAAI,KAAA;AAEtB,QAAIiB,EAAI,OAAQ;AAEhB,QAAI,CAAC,MAAM,QAAQA,EAAI,MAAM,GAAG;AAC/B,cAAQ,KAAK,gCAAgC;AAE7C;AAAA,IACD;AAEA,UAAMC,IAAkBD,EAAI,OAA6B,UAAU,CAAA3D,MAAQA,EAAK,OAAO,UAAaA,EAAK,SAAS,MAAS;AAC3H,QAAI4D,MAAmB,IAAI;AAC1B,cAAQ,KAAK,YAAYA,CAAc,mBAAmB;AAE1D;AAAA,IACD;AAEA,WAAIf,KACHC,GAASD,GAAUH,EAAI,MAAMiB,CAAG,GAG1BA;AAAA,EACR,GAKME,IAAO,OAAOC,MAAoB;AACvC,QAAI,CAACpB,EAAK;AAEV,QAAIoB,GAAQ;AAKX,UAHI,CAACN,KAGDH,EAAU,MAAO;AAErB,MAAAX,EAAI,OAAO,SAASc;AAAA,IACrB;AACC,MAAAd,EAAI,OAAO,SAAS;AAGrB,IAAAO,IAAqBP,GAAKa,CAAU,GAEpCF,EAAU,QAAQ;AAClB,UAAMM,IAAM,MAAMF,EAAA;AAKlB,IAJAJ,EAAU,QAAQ,IAElBC,EAAa,SAERK,MAELH,IAAaG,EAAI,YAEbG,IACHV,EAAM,QAAQA,EAAM,MAAM,OAAOO,EAAI,MAAM,IAE3CP,EAAM,QAAQO,EAAI;AAAA,EAEpB,GAEMI,IAAeC,GAAS,MAAMH,EAAK,EAAK,GAAG,GAAG;AAoCpD,SAAO;AAAA,IACN,YAAYnB;AAAA,IACZ,OAAAU;AAAA,IACA,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,MAAAO;AAAA,IACA,sBA9B4B,CAACI,GAAuBC,IAAc,OAAS;AAC3E,UAAKxB,GAGL;AAAA,YAAIuB,EAAc,SAASf,GAAW;AACrC,UAAAR,EAAI,mBAAA,GAEJU,EAAM,QAAQ,CAAA;AAEd;AAAA,QACD;AAGA,QAAIa,MAAkBV,KAAcH,EAAM,MAAM,WAEhDG,IAAaU,GAETC,IACEH,EAAA,IAEAF,EAAK,EAAK;AAAA;AAAA,IAEjB;AAAA,EAQC;AAEF,GCvJaM,KAAc,GAKdC,IAAc,MAKdC,IAAa,CAACC,GAAiCtE,GAAYuE,IAAqB,OACxFA,KAAsBvE,EAAK,OAAOoE,IACjC,MAAM,QAAQE,CAAU,IACpBA,EAAW,KAAK,CAAAE,MAAgBA,EAAa,OAAOxE,EAAK,MAAMwE,EAAa,SAASxE,EAAK,IAAI,IAE9FA,EAAK,SAASsE,EAAW,OAI9B,MAAM,QAAQA,CAAU,IACpBA,EAAW,KAAK,CAAAE,MAAgBA,EAAa,OAAOxE,EAAK,EAAE,IAE3DA,EAAK,OAAOsE,EAAW,IAanBG,KAA2B,CAAC/B,GAAgCgC,GAAgBC,MAAsB;AAC9G,MAAIC,IAAUlC,EAAI,OAAO,WAAW,CAAA;AAGpC,EAAAkC,IAAUA,EAAQ,OAAO,CAACC,MAAWA,EAAO,SAASF,CAAS,GAE1DD,KACHE,EAAQ,KAAKE,GAAeH,GAAW,YAAY,CAACD,CAAM,CAAC,CAAC,GAG7DhC,EAAI,aAAa,EAAE,SAAAkC,GAAS;AAC7B,GC1CaG,KAAU,CACtBpF,GACAqF,GACA5B,GACA6B,GACAC,GACAC,GACAC,GACAlC,GACAR,MACI;AAIJ,QAAMa,IAAazD,EAAI,EAAE,GAKnBuF,IAAU;AAAA,IACf,IAAIlB;AAAA,IACJ,MAAMmB,GAAA,EAAU,OAAO;AAAA,EAAA,GAMlBC,IAAc,MAAM;AACzB,IAAAhC,EAAW,QAAQ;AAAA,EACpB,GAKMiC,IAAa,MACd,GAAC9C,EAAI,cACLa,EAAW,MAAM,UAAUL,IAQ1BuC,IAAkCC,EAAS,MAAM;AACtD,UAAMD,IAAqB,CAAA;AAE3B,WAAI,CAACR,KAAeC,EAAW,UAC1B,OAAOA,EAAW,SAAU,aAC/BG,EAAQ,OAAOH,EAAW,QAG3BO,EAAW,KAAKJ,CAAO,IAGxBjC,EAAM,OAAO,QAAQ,CAAApD,MAAQyF,EAAW,KAAK,EAAE,GAAGzF,EAAA,CAAM,CAAC,GAElDyF;AAAAA,EACR,CAAC,GAKKE,IAAe7F,EAAY,EAAE,GAE7B8F,IAAqB,MAAM;AAChC,IAAAD,EAAa,QAAQE,EAAA;AAAA,EACtB,GASMA,IAAkB,MAAM;AAC7B,UAAMC,IAAevC,EAAW,MAAM,YAAA,GAChCwC,IAA6BC,GAAqBF,CAAY;AAEpE,QAAI1C,IAAgB,CAAA,GAShB6C;AACJ,UAAMC,IAAwB,CAAA,GAKxBC,IAAgB,MAAM;AAE3B,MAAID,EAAc,GAAG,EAAE,GAAG,eAAe,SAAS,eACjDA,EAAc,IAAA,GAGXA,EAAc,WACbD,KACH7C,EAAM,KAAK6C,CAAiB,GAG7B7C,EAAM,KAAK,GAAG8C,CAAa,GAE3BA,EAAc,SAAS;AAAA,IAEzB;AAEA,eAAWlG,KAAQyF,EAAW;AAC7B,cAAQzF,EAAK,eAAe,MAAA;AAAA,QAC3B,KAAK;AACJ,UAAAmG,EAAA,GAEAF,IAAoBjG;AAEpB;AAAA,QAED,KAAK;AAEJ,cAAIkG,EAAc,QAAQ;AACzB,gBAAI9F,IAAQ8F,EAAc;AAC1B,YAAIA,EAAc,GAAG,EAAE,GAAG,eAAe,SAAS,eAAa9F,KAE/D8F,EAAc9F,CAAK,IAAIJ;AAAA,UACxB;AAEA;AAAA,QACD;AACC,gBAAMoG,IAAOpG,EAAK,KAAK,YAAA;AACvB,WACCA,EAAK,OAAO,OAAO8F,CAAY,KAC/BM,EAAK,SAASN,CAAY,KAC1BM,EAAK,SAASL,CAA0B,OAEpCK,MAASN,KAAgBM,MAASL,IAErCG,EAAc,QAAQlG,CAAI,IAE1BkG,EAAc,KAAKlG,CAAI;AAAA,MAEzB;AASH,QALAmG,EAAA,GAEA/C,EAAM,KAAK,GAAGV,EAAI,MAAM,KAAK,GAI5ByC,EAAqB,SACnB5B,EAAW;AAAA,IAGb,CAACH,EAAM,KAAK,CAACpD,MAASA,EAAK,KAAK,kBAAkB8F,CAAY,GAC7D;AACD,YAAMO,IAAU;AAAA,QACf,IAAIjC;AAAA,QACJ,MAAMb,EAAW;AAAA,MAAA;AAIlBH,MAAAA,EAAM,KAAKiD,CAAO;AAAA,IACnB;AAEA,WAAIpB,MACH7B,IAAQA,EAAM,OAAO,CAAApD,MAAQ,CAACqE,EAAW1E,EAAM,OAAOK,CAAI,CAAC,IAGrDoD;AAAAA,EACR,GAOMkD,IAAa,CAACtG,MAAe;AAElC,IAAIA,EAAK,eAAe,SAAS,WAAWA,EAAK,eAAe,SAAS,gBAIrEiF,KAAe,MAAM,QAAQtF,EAAM,KAAK,IACtC0E,EAAW1E,EAAM,OAAOK,CAAI,MAChCL,EAAM,QAAQ,CAAC,GAAGA,EAAM,OAAOK,CAAI,KAGpCL,EAAM,QAAQK,GAGXA,EAAK,OAAOoE,KACfY,EAAM,cAAchF,CAAI,GAiBzB,WAAW,MAAM;AAIhB,MAAAuF,EAAA;AAAA,IACD,CAAC;AAAA,EASF;AAEA,MAAI7C,EAAI,YAAY;AAEnB,UAAM6D,IAAsB,CAACnD,GAAOV,EAAI,KAAK;AAG7C,IAAIuC,KACHsB,EAAe,KAAK5G,CAAK,GAG1B6G,EAAMD,GAAgB,MAAM;AAC3B,MAAAX,EAAA;AAAA,IACD,CAAC;AAAA,EACF;AACC,IAAAY,EAAM,CAAC7G,GAAOyD,GAAOG,CAAU,GAAG,MAAM;AACvC,MAAAqC,EAAA;AAAA,IACD,GAAG;AAAA,MACF,WAAW;AAAA;AAAA,MAGX,MAAM;AAAA,IAAA,CACN;AAyBF,SAAO;AAAA,IACN,YAAArC;AAAA,IACA,aAAAgC;AAAA,IACA,YAAAC;AAAA,IACA,cAAAG;AAAA,IACA,YAAAW;AAAA,IACA,gBAzBsB,MAAM;AAC5B,UAAI,MAAM,QAAQ3G,EAAM,KAAK,EAAG;AAEhC,YAAM8G,IAAkBd,EAAa,MAAM,OAAO,CAAC3F,MAAS,CAAC,CAAC,SAAS,WAAW,EAAE,SAASA,EAAK,eAAe,QAAQ,EAAE,CAAC,GAGtH0G,KADeD,EAAgB,UAAU,CAAAzG,MAAQA,EAAK,OAAQL,EAAM,MAAe,EAAE,IACzD,KAAK8G,EAAgB;AACvD,MAAA9G,EAAM,QAAQ,EAAE,GAAG8G,EAAgBC,CAAS,EAAA;AAAA,IAC7C;AAAA,IAkBC,kBAbwB,OAAO1G,MAAe;AAC9C,MAAI,MAAM,QAAQL,EAAM,KAAK,MAC5BA,EAAM,QAAQA,EAAM,MAAM,OAAO,CAACgH,MAAUA,EAAM,OAAO3G,EAAK,MAAM2G,EAAM,SAAS3G,EAAK,IAAI;AAAA,IAE9F;AAAA,EASC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxRA,UAAMP,IAAQC,GAQRC,IAAQC,kBAAmD,GAI3DoF,IAAQ4B;AAEd,IAAAC,EAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMZ,YAAY,CAACC,IAAyB,OAAU;AAC/C,QAAKpE,EAAI,eAGLoE,KACHvE,GAAWG,EAAI,WAAW,IAAI,GAI/BA,EAAI,MAAM,QAAQ,CAAA,GAGlBA,EAAI,aAAa,QAAQ,GAGzBA,EAAI,WAAW,OAAO,SAAS,GAG/B,sBAAsB,MAAM;AAC3B,UAAAqE,EAAK,aAAa,QAAQ,CAAA;AAAA,QAC3B,CAAC,GAGGC,EAAA,GAAY,WACftE,EAAI,qBAAqBqE,EAAK,WAAW,KAAK;AAAA,MAEhD;AAAA,IAAA,CACA;AAED,UAAME,IAAkBvB,EAAS,MAE5BjG,EAAM,eAAe,YAAYA,EAAM,eAGvCA,EAAM,eAAe,YAAYyB,EAAK,MAAM,WAAiB,UAE1DzB,EAAM,UACb,GAKKiD,IAAMM,GAAOvD,EAAM,KAAKA,EAAM,oBAAoBA,EAAM,WAAWA,EAAM,QAAQ,GAKjFsH,IAAOhC;AAAA,MACZpF;AAAA,MACAqF;AAAA,MACAkC,EAAMzH,GAAO,OAAO;AAAA,MACpBA,EAAM;AAAA,MACNyH,EAAMzH,GAAO,YAAY;AAAA,MACzByH,EAAMzH,GAAO,sBAAsB;AAAA,MACnCwH;AAAA,MACAxH,EAAM;AAAA,MACNiD;AAAA,IAAA,GAGKyE,IAAYzB,EAAS,MACtBjG,EAAM,cAAoB,cAC1BwH,EAAgB,UAAU,WAAiB,aAExC,KACP,GAKKG,IAAWtH,EAAS,IAAI,GAKxBkH,IAAW,MACTI,EAAS,OAAO;AAGxB,IAAI1E,EAAI,cAEP8D,EAAMO,EAAK,YAAY,MAAM;AAC5B,MAAArE,EAAI,qBAAqBqE,EAAK,WAAW,KAAK;AAAA,IAC/C,CAAC;AAGF,UAAMM,IAAc3B,EAAS,MACxB,MAAM,QAAQ/F,EAAM,KAAK,KAAKF,EAAM,eAAe,CAACA,EAAM,yBAAyBwH,EAAgB,UAAU,WACzGxH,EAAM,cAGPE,EAAM,OAAO,QAAQF,EAAM,WAClC,GAKK6H,IAAkB,CAACC,MAAqB;AAC7C,UAAIC,IAAW;AAEf,cAAQD,EAAE,KAAA;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AACJ,UAAI,MAAM,QAAQ5H,EAAM,KAAK,MAC5B4H,EAAE,eAAA,GACFA,EAAE,gBAAA,GAEF5H,EAAM,MAAM,IAAA;AAGb;AAAA,QACD,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACJ,UAAA6H,IAAW;AAEX;AAAA,QACD,KAAK;AACJ,UAAIP,EAAgB,UAAU,YAE7BF,EAAK,YAAA;AAGN;AAAA,MAAA;AAIF,YAAMU,IAAgBF,EAAE,IAAI,WAAW,KAAK,CAACA,EAAE,WAAW,CAACA,EAAE;AAG7D,OAAIN,EAAgB,UAAU,WAAWA,EAAgB,UAAU,aAC9DQ,MACHD,IAAW,KAKTR,EAAA,GAAY,YACfQ,IAAW,KAGRA,MACCP,EAAgB,UAAU,YAC7BM,EAAE,eAAA,GACFA,EAAE,gBAAA,GAGEE,MAEEV,EAAK,WAAW,UACpBA,EAAK,WAAW,QAAQQ,EAAE,QAK5BA,EAAE,eAA+B,MAAA;AAAA,IAEpC,GAEMG,IAAiB,CAACH,MAAkB;AACzC,MAAAA,EAAE,eAAA,GAEFR,EAAK,eAAA;AAAA,IACN,GAKMY,IAAS,MAAM;AACpB,MAAIjF,EAAI,cAEPA,EAAI,qBAAqBqE,EAAK,WAAW,OAAO,EAAK;AAAA,IAEvD,GAKMa,IAAU,MAAM;AAErB,MAAIX,EAAgB,UAAU,WACzBF,EAAK,WAAW,SAAOA,EAAK,YAAA;AAAA,IAElC,GASMc,IAAsB,CAACN,MAAa;AACzC,YAAM1H,IAAK0H,EAAE;AAEb,MAAI1H,EAAG,aAAaA,EAAG,eAAeA,EAAG,gBAAgB,OACxD6C,EAAI,KAAK,EAAI;AAAA,IAEf;;;kBAwCChB,EAyHWoG,EAAAC,EAAA,GAAA;AAAA,iBAxHN;AAAA,QAAJ,KAAIX;AAAA,QACH,+BAAMO;QACN,gCAAOC;QACP,4CAAmBE,EAAApF,CAAA,IAAMmF,EAAoBhG,CAAM,IAAI;AAAA,QACvD,OAAO;AAAA,QACP,oBAAoB;AAAA,QACpB,kBAAkBoF,EAAA,UAAe,aAAkBvH,EAAA,oBAAgB;AAAA,QACnE,UAAUuH,EAAA,UAAe,YAAiBa,EAAAf,CAAA,EAAK,WAAA;AAAA,MAAU;QAE/C,UACV,MAoDY;AAAA,UApDZiB,GAAAhG,KAAAN,EAoDYuG,GAnDNd,EAAA,KAAS,GADfvF,EAGIlC,EAiDQ,aAjDG;AAAA,YAEb,OAAK;AAAA;2CAAkEA,EAAA;AAAA,cAAsC,CAAA,mBAAAA,EAAA,WAAW,KAAKA,EAAA;AAAA,cAAmC,gBAAA,CAAAA,EAAA,eAAeuH,EAAA,UAAe;AAAA;6BAAiEvH,EAAA,IAAI,GAAA;AAAA,8BAAgCA,EAAA;AAAA,sCAAyCA,EAAA;AAAA,2BAA8BA,EAAA;AAAA,YAAA;AAAA,YAW1W,MAAAA,EAAA;AAAA,YACD,UAAS;AAAA,YACR,WAAS4H;AAAA,YACT,QAAIlF,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAP,MAAEoF,EAAA,UAAe,YAAiBa,EAAAf,CAAA,EAAK,YAAA;AAAA,YAG3C,aAAAM,EAAA;AAAA,YACA,OAAA3H,EAAA;AAAA,YACA,aAAauH,EAAA,UAAe,YAAiBvH,YAAU,iBAAoB;AAAA,wBACnEoI,EAAAf,CAAA,EAAK,WAAW;AAAA,0DAAhBe,EAAAf,CAAA,EAAK,WAAW,QAAKlF;AAAA,UAAA;uBAE9B,MASW;AAAA,cATKnC,EAAA,eACfsC,EAAA,GAAAV,EAOM,OAPNW,IAOM;AAAA,wBANLX,EAKEE,GAAA,MAAAC,EAJc9B,EAAA,OAAK,CAAbK,YADR0B,EAKEwG,IAAA;AAAA,kBAHA,IAAIlI,EAAK;AAAA,kBACT,MAAMA,EAAK;AAAA,kBACX,UAAQ8H,EAAAf,CAAA,EAAK;AAAA,gBAAA;;cAKLE,EAAA,uBAAiCvH,EAAA,oBAA7C4B,EAEO,QAFP6G,IAEOpG,EADF,MAAM,QAAQpC,EAAA,KAAK,IAAc,KAAVA,EAAA,MAAM,IAAI,GAAA,CAAA;cAG1BD,EAAA,eAAW,CAAKC,EAAA,MAAM,eAAlC2B,EAEO,QAFP8G,IAEOrG,EADHsF,EAAA,KAAW,GAAA,CAAA;cAIR3H,EAAA,cAAU,CAAKA,EAAA,eAAW,CAAKA,EAAA,eAAeoI,EAAAf,CAAA,EAAK,aAAa,MAAM,eAAerH,EAAA,iBAD5F4B,EAKQ,QAAA;AAAA;gBAHP,OAAM;AAAA,gBACN,2BAAwB;AAAA,gBACvB,SAAOoG;AAAA,cAAA;;;;;;cA9BahI,EAAA;AAAA;cAAV,EAAA,UAAZ,GAAA;AAAA,YAA8B;AAAA;;QA8CrB,eAET,MAAuC;AAAA,WADxCsC,EAAA,EAAA,GAAAV,EAuBmBE,WAtBHsG,EAAAf,CAAA,EAAK,aAAa,QAA1B/G,OADRgC,KAAAN,EAuBmBoG,MAvBnBlG,EAuBmB;AAAA,YArBjB,KAAK5B,EAAK,MAAM;AAAA,YAChB,OAAK;AAAA,6BAAwB,MAAM,QAAQL,EAAA,KAAK,MAAMD,EAAA,eAAeC,QAAM,OAAOK,EAAK,MAAML,EAAA,MAAM,SAASK,EAAK;AAAA,wCAAoCA,EAAK,OAAO8H,EAAA3D,EAAA;AAAA,wCAA2CnE,EAAK,OAAO8H,EAAA1D,CAAA;AAAA,YAAA;AAAA,aAKtN,EAAA,SAAA,MAAApE,EAAK,eAAa;AAAA,YACpB,eAAeN,EAAA,eAAeoI,KAAK,MAAM;AAAA,YACzC,SAAK,CAAAjG,MAAEiG,EAAAf,CAAA,EAAK,WAAW/G,CAAI;AAAA,UAAA;uBAE5B,MAIQ;AAAA,cAHDqI,EAAAA,OAAO,OADdC,GAIQC,EAAA,QAAA,QAAA;AAAA;gBADN,MAAAvI;AAAA,cAAA,WAGFsB,EAIWE,GAAA,EAAA,KAAA,KAAA;AAAA,gBADPM,EAAAC,EAAA/B,EAAK,IAAI,GAAA,CAAA;AAAA,cAAA;;;;WAKG8H,EAAAf,CAAA,EAAK,aAAa,MAAM,UAAM,CAAKe,EAAAf,CAAA,EAAK,qBACxDrF,EAUmBoG,EAAAU,CAAA,GAAA;AAAA;YAVD,MAAK;AAAA,UAAA;uBACtB,MAEW;AAAA,eAFMV,EAAApF,CAAA,EAAI,UAAU,SAASoF,EAAApF,CAAA,EAAI,aAAa,cAAzDpB,EAEWE,GAAA,EAAA,KAAA,KAAA;AAAA,oBADPiH,EAAAA,MAAM,OAAO,UAAU,GAAA,CAAA;AAAA,cAAA,gBAI3B/G,EAGEoG,EAAAY,EAAA,GAAA;AAAA;gBADD,MAAK;AAAA,cAAA;;;;UAMYZ,EAAApF,CAAA,EAAI,aAAa,SAASoF,EAAApF,CAAA,EAAI,UAAU,SAASuE,EAAA,UAAe,iBAApFvF,EAAoGiH,GAAA,EAAA,KAAA,GAAA;;;;QArD7E1B,EAAA,UAAe;gBAA5B;AAAA,gBACV,MAOE;AAAA,cAPF/E,GAOE4F,EAAAc,EAAA,GAAA;AAAA,cAND,OAAM;AAAA,cACN,MAAK;AAAA,0BACId,EAAAf,CAAA,EAAK,WAAW;AAAA,4DAAhBe,EAAAf,CAAA,EAAK,WAAW,QAAKlF;AAAA,cAE7B,WAAS,CAAA,CAAIiG,EAAApF,CAAA,EAAI,aAAa,SAASoF,EAAApF,CAAA,EAAI,UAAU;AAAA,cACrD,aAAA2E,EAAA;AAAA,YAAA;;;gBAFqB1H,EAAA;AAAA;gBAAV,EAAA,UAAZ,GAAA;AAAA,cAA4B;AAAA;;;;;;;;"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
define(["require","exports","vue","./forms-CUSCBQu3.amd","./popupHint.vue_vue_type_style_index_0_lang-DtiT6NE4.amd","./widgetInput.vue_vue_type_script_setup_true_lang-CkE912ll.amd","../utils/keyboard.amd","./field-Cvv0SRcJ.amd","../require/css.amd!../assets/policy.css"],(function(te,L,e,w,E,$,R,q){"use strict";if(typeof e>"u")var e=window.Vue;const K={key:0,class:"top-menu_selectAll"},W=e.defineComponent({__name:"menu",props:e.mergeModels({modelValue:{},items:{},isMultiple:{type:Boolean},canBeEmptyMultiple:{type:Boolean},styling:{default:"default"},selectAllItem:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(t){const r=t,n=e.useModel(t,"modelValue"),l=e.ref();!r.isMultiple&&typeof n.value!="string"&&typeof n.value!="number"&&console.warn('Type check failed for prop "modelValue". Expected String: '+typeof n.value),r.isMultiple&&!Array.isArray(n.value)&&console.warn('Type check failed for prop "modelValue". Expected Array: '+typeof n.value),r.isMultiple&&!r.canBeEmptyMultiple&&Array.isArray(n.value)&&!n.value.length&&r.items[0]&&(n.value=[r.items[0]?.href??r.items[0]?.value]);const c=o=>Array.isArray(n.value)?n.value.includes(o.value):o.value===n.value,C=(o,m=!1)=>{if(Array.isArray(n.value)){let u=n.value.slice();if(m){u.length||(u=r.items.map(h=>h.value));const g=u.indexOf(o.value);g===-1?u.push(o.value):u.splice(g,1)}else u.length===1&&u[0]===o.value?u=[]:u=[o.value];!r.canBeEmptyMultiple&&!u.length&&(u=[o.value]),n.value=u;return}n.value=o.value},d=o=>{if(l.value.scrollWidth<=l.value.offsetWidth||o.shiftKey||Math.abs(o.deltaY)<50)return;o.preventDefault();const m=o.deltaY>0?30:-30;l.value.scrollLeft=l.value.scrollLeft+m},f=(o=!0)=>{const m=l.value.querySelector(".top-active");if(!m)return;const u=24,g=m.offsetLeft-l.value.offsetLeft-u,h=m.offsetLeft-l.value.offsetLeft+m.clientWidth+u,y=l.value.scrollLeft,S=l.value.clientWidth+l.value.scrollLeft;let k;g<y&&(k=g),h>S&&(k=h-l.value.clientWidth),k!==void 0&&(w.isSafari()?w.Core.$?.(l.value).animate({scrollLeft:k},o?200:0):l.value.scrollTo({left:k,behavior:o?"smooth":"auto"}))},a=()=>{if(Array.isArray(n.value)){if(n.value.length===r.items.length){n.value=[r.items[0].href??r.items[0].value];return}n.value=r.items.map(o=>o.href??o.value)}};return e.onMounted(()=>f(!1)),e.onUpdated(()=>f(!0)),(o,m)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"el",ref:l,class:e.normalizeClass({"top-menu":!0,["top-style_"+t.styling]:!0}),onWheel:d},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.items,u=>(e.openBlock(),e.createBlock(w._sfc_main$1,e.mergeProps({ref_for:!0},u,{class:"top-menu_item",color:"theme",onClick:g=>C(u,g.ctrlKey||g.metaKey),isActive:c(u)}),e.createSlots({_:2},[u.content?{name:"default",fn:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(u.content),1)]),key:"0"}:void 0]),1040,["onClick","isActive"]))),256)),Array.isArray(n.value)&&t.selectAllItem?(e.openBlock(),e.createElementBlock("div",K,[e.createVNode(w._sfc_main$1,e.mergeProps(t.selectAllItem,{class:"top-menu_item",color:"theme",styling:"",onClick:m[0]||(m[0]=u=>a()),isActive:n.value.length===t.items.length}),e.createSlots({_:2},[t.selectAllItem.content?{name:"default",fn:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.selectAllItem.content),1)]),key:"0"}:void 0]),1040,["isActive"])])):e.createCommentVNode("",!0)],34))}}),O={class:"top-selector2_itemMulti top-ellipsis"},z=e.defineComponent({__name:"itemMulti",props:{id:{},name:{}},emits:["delete"],setup(t){return(r,n)=>(e.openBlock(),e.createElementBlock("div",O,[e.createTextVNode(e.toDisplayString(t.name)+" ",1),e.createElementVNode("span",{class:"top-selector2_itemMultiDelete","data-top-icon":"",onClick:n[0]||(n[0]=l=>r.$emit("delete",{id:t.id,name:t.name})),onMousedown:n[1]||(n[1]=e.withModifiers(()=>{},["stop"]))},null,32)]))}}),x=new Map,U=t=>{x.get(t)?.clear()},Y=t=>{const r=window.mo?.user?.id;return JSON.stringify(t.params)+":"+t.url+":"+r},H=(t,r)=>x.get(r)?.get(t),J=(t,r,n)=>{x.has(r)||x.set(r,new Map),x.get(r)?.set(t,n)},j=(t,r,n,l)=>{const c=e.ref([]),C=e.ref(!1),d=e.ref(0);let f="",a;t&&!t.params.limit&&(t.params.limit=100);const o=async()=>{if(!t)return;const h=l?Y(t):void 0;if(h){const k=H(h,t.path);if(k)return t.abortByFingerprint(),k}const y=await t.call();if(y.errors)return;if(!Array.isArray(y.result)){console.warn("Array expected in `res.result`");return}const S=y.result.findIndex(k=>k.id===void 0||k.name===void 0);if(S!==-1){console.warn(`В result[${S}] нет id или name`);return}return h&&J(h,t.path,y),y},m=async h=>{if(!t)return;if(h){if(!a||C.value)return;t.params.offset=a}else t.params.offset=0;r?.(t,f),C.value=!0;const y=await o();C.value=!1,d.value++,y&&(a=y.nextOffset,h?c.value=c.value.concat(y.result):c.value=y.result)},u=w.debounce(()=>m(!1),200);return{apiRequest:t,items:c,isLoading:C,countLoading:d,load:m,setSearchTextAndLoad:(h,y=!0)=>{if(t){if(h.length<n){t.abortByFingerprint(),c.value=[];return}h===f&&c.value.length||(f=h,y?u():m(!1))}}}},P=0,b=null,N=(t,r,n=!0)=>n&&r.id===b?Array.isArray(t)?t.some(l=>l.id===r.id&&l.name===r.name):r.name===t.name:Array.isArray(t)?t.some(l=>l.id===r.id):r.id===t.id,G=(t,r,n)=>{let l=t.params.filters??[];l=l.filter(c=>c.name!==n),r&&l.push(q.genFieldFilter(n,"CONTAINS",[r])),t.changeParams({filters:l})},Q=(t,r,n,l,c,C,d,f,a)=>{const o=e.ref(""),m={id:P,name:w.useI18n().Common.All},u=()=>{o.value=""},g=()=>!(!a.apiRequest||o.value.length>=f),h=e.computed(()=>{const s=[];return!l&&c.value&&(typeof c.value=="string"&&(m.name=c.value),s.push(m)),n.value?.forEach(A=>s.push({...A})),s}),y=e.ref([]),S=()=>{y.value=k()},k=()=>{const s=o.value.toLowerCase(),A=R.invertKeyboardLayout(s);let i=[],T;const I=[],D=()=>{I.at(-1)?.listItemProps?.type==="delimiter"&&I.pop(),I.length&&(T&&i.push(T),i.push(...I),I.length=0)};for(const B of h.value)switch(B.listItemProps?.type){case"title":D(),T=B;break;case"delimiter":if(I.length){let F=I.length;I.at(-1)?.listItemProps?.type==="delimiter"&&F--,I[F]=B}break;default:const M=B.name.toLowerCase();(B.id===Number(s)||M.includes(s)||M.includes(A))&&(M===s||M===A?I.unshift(B):I.push(B))}if(D(),i.push(...a.items.value),C.value&&o.value&&!i.find(B=>B.name.toLowerCase()===s)){const B={id:b,name:o.value};i.push(B)}return l&&(i=i.filter(B=>!N(t.value,B))),i},V=s=>{s.listItemProps?.type==="title"||s.listItemProps?.type==="delimiter"||(l&&Array.isArray(t.value)?N(t.value,s)||(t.value=[...t.value,s]):t.value=s,s.id===b&&r("appendItem",s),setTimeout(()=>{u()}))};if(a.apiRequest){const s=[n,a.items];l&&s.push(t),e.watch(s,()=>{S()})}else e.watch([t,n,o],()=>{S()},{immediate:!0,deep:2});return{searchText:o,resetSearch:u,genIsShort:g,itemsForShow:y,selectItem:V,selectNextItem:()=>{if(Array.isArray(t.value))return;const s=y.value.filter(T=>!["title","delimiter"].includes(T.listItemProps?.type??"")),i=(s.findIndex(T=>T.id===t.value.id)+1)%s.length;t.value={...s[i]}},deleteItemByItem:async s=>{Array.isArray(t.value)&&(t.value=t.value.filter(A=>A.id!==s.id||A.name!==s.name))}}},X={key:0,class:"top-selector2_activeItems"},Z={key:1,class:"top-selector2_activeName top-ellipsis"},_={key:2,class:"top-selector2_placeholder top-ellipsis"},ee=e.defineComponent({__name:"selector2",props:e.mergeModels({modelValue:{},items:{default:()=>[]},title:{},disabled:{type:Boolean},icon:{},modificator:{},size:{default:"s"},isError:{type:Boolean},openByFocusInput:{type:Boolean,default:void 0},searchType:{default:"popup"},placeholder:{},api:{},apiSetSearchParams:{},minLength:{default:0},useCache:{type:Boolean},appendSearchToResult:{type:Boolean},multiselect:{type:Boolean},useAllItem:{type:[Boolean,String]},addChanger:{type:Boolean},buttonProps:{},selectedAsPlaceholder:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:e.mergeModels(["appendItem"],["update:modelValue"]),setup(t,{expose:r,emit:n}){const l=t,c=e.useModel(t,"modelValue"),C=n;r({resetCache:(v=!1)=>{f.apiRequest&&(v&&U(f.apiRequest.path),f.items.value=[],f.countLoading.value=0,f.apiRequest.params.offset=0,requestAnimationFrame(()=>{a.itemsForShow.value=[]}),u()?.elPopup&&f.setSearchTextAndLoad(a.searchText.value))}});const d=e.computed(()=>l.searchType==="inline"&&l.multiselect||l.searchType==="inline"&&w.Core.state.isMobile?"popup":l.searchType),f=j(l.api,l.apiSetSearchParams,l.minLength,l.useCache),a=Q(c,C,e.toRef(l,"items"),l.multiselect,e.toRef(l,"useAllItem"),e.toRef(l,"appendSearchToResult"),d,l.minLength,f),o=e.computed(()=>l.buttonProps?"TopButton":d.value==="inline"?"TopInput":"div"),m=e.ref(null),u=()=>m.value?.popup;f.apiRequest&&e.watch(a.searchText,()=>{f.setSearchTextAndLoad(a.searchText.value)});const g=e.computed(()=>Array.isArray(c.value)||l.multiselect||!l.selectedAsPlaceholder&&d.value!=="inline"?l.placeholder:c.value?.name||l.placeholder),h=v=>{let p=!1;switch(v.key){case"Delete":case"Backspace":Array.isArray(c.value)&&(v.preventDefault(),v.stopPropagation(),c.value.pop());break;case"ArrowUp":case"ArrowRight":case"ArrowDown":case"ArrowLeft":case"Enter":case" ":p=!0;break;case"Escape":d.value==="inline"&&a.resetSearch();break}const s=v.key.length===1&&!v.ctrlKey&&!v.metaKey;(d.value==="popup"||d.value==="inline")&&s&&(p=!0),u()?.elPopup&&(p=!1),p&&(d.value==="popup"&&(v.preventDefault(),v.stopPropagation(),s&&(a.searchText.value||(a.searchText.value=v.key))),v.currentTarget?.click())},y=v=>{v.preventDefault(),a.selectNextItem()},S=()=>{f.apiRequest&&f.setSearchTextAndLoad(a.searchText.value,!1)},k=()=>{d.value==="popup"&&a.searchText.value&&a.resetSearch()},V=v=>{const p=v.target;p.scrollTop/(p.scrollHeight-p.offsetHeight)>.8&&f.load(!0)};return(v,p)=>{const s=e.resolveComponent("TopLoadbar"),A=e.resolveDirective("top-focus");return e.openBlock(),e.createBlock(e.unref(E._sfc_main),{ref_key:"popupRef",ref:m,onOpen:p[3]||(p[3]=i=>S()),onClose:p[4]||(p[4]=i=>k()),onScrollContentList:p[5]||(p[5]=i=>e.unref(f)?V(i):void 0),notch:!1,transitionDuration:0,openByFocusInput:d.value==="inline"&&(t.openByFocusInput??!0),disabled:d.value==="inline"&&e.unref(a).genIsShort()},e.createSlots({opener:e.withCtx(()=>[e.withDirectives((e.openBlock(),e.createBlock(e.resolveDynamicComponent(o.value),e.mergeProps(t.buttonProps,{class:{"top-selector2":!0,"top-selector2-multiselect":t.multiselect,["top-selector2-"+t.modificator]:!!t.modificator,"top-as-input":!t.buttonProps&&d.value!=="inline","top-as-selector":!0,["top-size_"+t.size]:!0,"top-disabled":t.disabled,"top-forms-focusable":!t.disabled,"top-error":t.isError},icon:t.icon,tabindex:"0",onKeydown:h,onBlur:p[0]||(p[0]=i=>d.value==="inline"&&e.unref(a).resetSearch()),placeholder:g.value,title:t.title,captionType:d.value==="inline"&&t.title!==void 0?"top":void 0,modelValue:e.unref(a).searchText.value,"onUpdate:modelValue":p[1]||(p[1]=i=>e.unref(a).searchText.value=i)}),{default:e.withCtx(()=>[t.multiselect?(e.openBlock(),e.createElementBlock("div",X,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(c.value,i=>(e.openBlock(),e.createBlock(z,{id:i.id,name:i.name,onDelete:e.unref(a).deleteItemByItem},null,8,["id","name","onDelete"]))),256))])):e.createCommentVNode("",!0),d.value!=="inline"&&!t.multiselect?(e.openBlock(),e.createElementBlock("span",Z,e.toDisplayString(Array.isArray(c.value)?"":c.value.name),1)):e.createCommentVNode("",!0),t.multiselect&&!c.value.length?(e.openBlock(),e.createElementBlock("span",_,e.toDisplayString(g.value),1)):e.createCommentVNode("",!0),t.addChanger&&!t.buttonProps&&!t.multiselect&&e.unref(a).itemsForShow.value.length>1&&!t.disabled?(e.openBlock(),e.createElementBlock("span",{key:3,class:"top-changer top-changer-selector","data-top-popup-disabled":"true",onClick:y})):e.createCommentVNode("",!0)]),_:1},16,["class","icon","placeholder","title","captionType","modelValue"])),[[A,t.isError,void 0,{onupdate:!0}]])]),contentList:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(a).itemsForShow.value,i=>(e.openBlock(),e.createBlock(e.unref(E._sfc_main$2),e.mergeProps({key:i.id??void 0,class:{"top-active":!Array.isArray(c.value)&&!t.multiselect&&c.value.id===i.id&&c.value.name===i.name,"top-selector2_item-all":i.id===e.unref(P),"top-selector2_item-new":i.id===e.unref(b)}},{ref_for:!0},i.listItemProps,{closeByClick:!t.multiselect||e.unref(w.Core).state.isMobile,onClick:T=>e.unref(a).selectItem(i)}),{default:e.withCtx(()=>[v.$slots.item?e.renderSlot(v.$slots,"item",{key:0,item:i}):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createTextVNode(e.toDisplayString(i.name),1)],64))]),_:2},1040,["class","closeByClick","onClick"]))),128)),!e.unref(a).itemsForShow.value.length&&!e.unref(a).genIsShort()?(e.openBlock(),e.createBlock(e.unref(E._sfc_main$2),{key:0,type:"regular"},{default:e.withCtx(()=>[!e.unref(f).isLoading.value||e.unref(f).countLoading.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(e.toDisplayString(v.$i18n.Common.No_results),1)],64)):(e.openBlock(),e.createBlock(e.unref(w._sfc_main$12),{key:1,type:"circles"}))]),_:1})):e.createCommentVNode("",!0),e.unref(f).countLoading.value&&e.unref(f).isLoading.value&&d.value==="inline"?(e.openBlock(),e.createBlock(s,{key:1})):e.createCommentVNode("",!0)]),_:2},[d.value==="popup"?{name:"widget",fn:e.withCtx(()=>[e.withDirectives(e.createVNode(e.unref($._sfc_main),{title:"Поиск",icon:"",modelValue:e.unref(a).searchText.value,"onUpdate:modelValue":p[2]||(p[2]=i=>e.unref(a).searchText.value=i),isLoading:!!e.unref(f).countLoading.value&&e.unref(f).isLoading.value,placeholder:g.value},null,8,["modelValue","isLoading","placeholder"]),[[A,c.value,void 0,{onupdate:!0}]])]),key:"0"}:void 0]),1032,["openByFocusInput","disabled"])}}});L.ITEM_ID_ALL=P,L.ITEM_ID_NEW=b,L._sfc_main=ee,L._sfc_main$1=W,L.apiSetSearchParamsFilter=G}));
|
|
2
|
-
//# sourceMappingURL=policy.vue_vue_type_style_index_0_lang-DJOaMdBm.amd.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"policy.vue_vue_type_style_index_0_lang-DJOaMdBm.amd.js","sources":["../../src/components/formsExt/menu/menu.vue","../../src/components/formsExt/selector2/itemMulti.vue","../../src/components/formsExt/selector2/cache.ts","../../src/components/formsExt/selector2/composables/useAPI.ts","../../src/components/formsExt/selector2/utils.ts","../../src/components/formsExt/selector2/composables/useMenu.ts","../../src/components/formsExt/selector2/selector2.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, onUpdated, ref } from 'vue';\nimport type { Item, Props } from './types';\nimport Core from '@/core/core/core';\nimport { isSafari } from '@/core/utils/device';\nimport TopButton from '@/components/forms/button/button.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tstyling: 'default',\n});\n\nconst model = defineModel({\n\trequired: true,\n});\n\nconst el = ref();\n\n// валидация типа modelValue без возможности выбора нескольких значений (ожидается строка или число)\nif (!props.isMultiple && typeof (model.value) !== 'string' && typeof (model.value) !== 'number') {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected String: ' + typeof (model.value));\n}\n\n// валидация типа modelValue с возможностью выбора нескольких значений (ожидается массив)\nif (props.isMultiple && !Array.isArray(model.value)) {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected Array: ' + typeof (model.value));\n}\n\n/**\n * Для множественного выбора без пустого множества\n *\n * Если ничего не выбрано, присваиваем 1-ое значение\n */\nif (props.isMultiple && !props.canBeEmptyMultiple && Array.isArray(model.value) && !model.value.length && props.items[0]) {\n\tmodel.value = [props.items[0]?.href ?? props.items[0]?.value];\n}\n\nconst itemIsActive = (item: Item) => {\n\tif (!Array.isArray(model.value)) {\n\t\treturn item.value === model.value;\n\t}\n\n\treturn model.value.includes(item.value);\n};\n\n/**\n * Выбрать элемент\n * @param item\n * @param toggle - добавить или исключить элемент, для isMultiple\n */\nconst select = (item: Item, toggle = false) => {\n\tif (Array.isArray(model.value)) {\n\t\tlet modelNew = model.value.slice();\n\n\t\tif (toggle) {\n\t\t\tif (!modelNew.length) modelNew = props.items.map(item => item.value);\n\n\t\t\tconst index = modelNew.indexOf(item.value);\n\t\t\tif (index === -1) {\n\t\t\t\tmodelNew.push(item.value);\n\t\t\t} else {\n\t\t\t\tmodelNew.splice(index, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (modelNew.length === 1 && modelNew[0] === item.value) {\n\t\t\t\tmodelNew = [];\n\t\t\t} else {\n\t\t\t\tmodelNew = [item.value];\n\t\t\t}\n\t\t}\n\n\t\tif (!props.canBeEmptyMultiple && !modelNew.length) modelNew = [item.value];\n\n\t\tmodel.value = modelNew;\n\n\t\treturn;\n\t}\n\n\tmodel.value = item.value;\n};\n\n// вертикальный скролл в горизонтальный скролл\nconst onWheel = (event: WheelEvent) => {\n\tif (el.value.scrollWidth <= el.value.offsetWidth) return;\n\tif (event.shiftKey) return;\n\tif (Math.abs(event.deltaY) < 50) return; // устройство с высокой точностью, например тачпад\n\n\tevent.preventDefault();\n\n\tconst delta = event.deltaY > 0 ? 30 : -30;\n\tel.value.scrollLeft = el.value.scrollLeft + delta;\n};\n\n/**\n * Замена стандартному scrollIntoView, который меняет скролл документа\n *\n * Выравнивание по ближнему краю элемента\n *\n * Выравнивается таким образом, чтобы был виден соседний элемент\n */\nconst scrollIntoView = (isSmooth = true) => {\n\tconst elBtn = el.value.querySelector('.top-active');\n\tif (!elBtn) return;\n\n\tconst gap = 24;\n\n\t// левая и правая координаты элемента\n\tconst leftMargin = elBtn.offsetLeft - el.value.offsetLeft - gap;\n\tconst rightMargin = elBtn.offsetLeft - el.value.offsetLeft + elBtn.clientWidth + gap;\n\n\t// левая и правая границы видимой части меню\n\tconst leftMarginParent = el.value.scrollLeft;\n\tconst rightMarginParent = el.value.clientWidth + el.value.scrollLeft;\n\n\tlet scrollLeft: number | undefined = undefined;\n\n\t// левую границу элемента к левой границе меню\n\tif (leftMargin < leftMarginParent) scrollLeft = leftMargin;\n\n\t// правую границу элемента к правой границе меню\n\tif (rightMargin > rightMarginParent) scrollLeft = rightMargin - el.value.clientWidth;\n\n\tif (scrollLeft !== undefined) {\n\t\tif (isSafari()) {\n\t\t\tCore.$?.(el.value).animate({ scrollLeft: scrollLeft }, isSmooth ? 200 : 0);\n\t\t} else {\n\t\t\tel.value.scrollTo({ left: scrollLeft, behavior: isSmooth ? 'smooth' : 'auto' });\n\t\t}\n\t}\n};\n\n/**\n * Выбрать все элементы в меню\n */\nconst selectAll = () => {\n\tif (!Array.isArray(model.value)) return;\n\n\tif (model.value.length === props.items.length) {\n\t\tmodel.value = [props.items[0].href ?? props.items[0].value];\n\t\treturn;\n\t}\n\n\tmodel.value = props.items.map(item => item.href ?? item.value);\n};\n\nonMounted(() => scrollIntoView(false));\nonUpdated(() => scrollIntoView(true));\n\n</script>\n\n<template>\n\t<div\n\t\tref=\"el\"\n\t\t:class=\"{\n\t\t\t'top-menu': true,\n\t\t\t['top-style_' + styling]: true,\n\t\t\t// ['top-unwrap-x']: styling === 'default',\n\t\t}\"\n\t\t@wheel=\"onWheel\"\n\t>\n\t\t<TopButton\n\t\t\tv-for=\"item in items\"\n\t\t\t:=\"item\"\n\t\t\tclass=\"top-menu_item\"\n\t\t\tcolor=\"theme\"\n\t\t\t@click=\"select(item, $event.ctrlKey || $event.metaKey)\"\n\t\t\t:isActive=\"itemIsActive(item)\"\n\t\t>\n\t\t\t<template #default v-if=\"item.content\">\n\t\t\t\t{{ item.content }}\n\t\t\t</template>\n\t\t</TopButton>\n\n\t\t<div\n\t\t\tv-if=\"Array.isArray(model) && selectAllItem\"\n\t\t\tclass=\"top-menu_selectAll\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\t:=\"selectAllItem\"\n\t\t\t\tclass=\"top-menu_item\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\tstyling=\"\"\n\t\t\t\t@click=\"selectAll()\"\n\t\t\t\t:isActive=\"model.length === items.length\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"selectAllItem.content\">\n\t\t\t\t\t{{ selectAllItem.content }}\n\t\t\t\t</template>\n\t\t\t</TopButton>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n.top-menu {\n\t--scroll-thumb-color: var(--color-line-1);\n\t--scroll-thumb-color-hover: var(--color-line-2);\n\t--scroll-thumb-color-active: var(--color-line-3);\n\n\tmax-width: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: var(--top-gap-2);\n\toverflow-x: auto;\n\tscrollbar-width: none; /* firefox */\n\n\t/* предотвратить натинвые события браузера (назад / вперед) */\n\toverscroll-behavior-x: contain;\n}\n\n.top-menu::-webkit-scrollbar { display: none; }\n\n.top-menu .top-menu_item {\n\t--top-button-color: var(--color-text-2);\n\n\toutline-offset: -2px !important;\n\tmin-width: 0;\n\tmax-width: 200px;\n\tmargin: 0;\n\tflex-shrink: 0;\n}\n\n.top-menu .top-menu_item[data-top-icon] {\n\t--top-icon-color: var(--color-text-2);\n}\n\n.top-menu_selectAll {\n\tposition: sticky;\n\tright: 0;\n\tbackground: var(--color-layout-front-1);\n\tborder-left: 1px solid var(--color-line-1);\n\tpadding-left: var(--top-padding-1);\n\tbox-shadow: var(--color-layout-front-1) var(--top-padding-2) 0px;\n}\n\n/* style default */\n.top-menu.top-style_default .top-menu_item {\n\t--top-forms-radius: 0;\n\t--top-forms-border-color: transparent;\n\t--top-forms-border-width: 2px;\n\n\tfilter: none;\n\tbox-shadow: none;\n\tborder: none;\n\tborder-bottom: var(--top-forms-border-width) solid var(--top-forms-border-color);\n\tbackground: none;\n}\n\n.top-style_default > .top-menu_item > [data-top-badge] {\n\tmargin-top: 0;\n}\n\n.top-menu.top-style_default .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-2);\n}\n\n.top-menu.top-style_default .top-menu_item:active,\n.top-menu.top-style_default .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-primary-1);\n}\n\n.top-menu.top-style_default .top-menu_selectAll {\n\tpadding-left: var(--top-padding-2);\n}\n\n/* style bar */\n.top-menu.top-style_bar {\n\tborder-radius: var(--top-radius-3);\n\tborder: 1px solid var(--color-line-2);\n\tpadding: var(--top-padding-1);\n\tgap: 3px;\n}\n.top-menu.top-style_bar .top-menu_item {\n\t--top-button-background-color-hover: var(--color-layer-1);\n\t--top-button-background-color-active: var(--color-layer-2);\n\t--top-button-background-color-selected: var(--color-layer-primary-1);\n\n\tposition: relative;\n}\n\n.top-menu.top-style_bar .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n}\n\n.top-menu.top-style_bar .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-primary);\n}\n\n/* разделители кнопок в баре */\n.top-menu.top-style_bar .top-menu_item:not(:first-child):not(.top-active):not(:hover):after {\n\tcontent: \"\";\n\tbackground: var(--color-line-1-opacity);\n\twidth: 1px;\n\theight: 60%;\n\tdisplay: block;\n\tposition: absolute;\n\tleft: -2px;\n}\n.top-menu.top-style_bar .top-menu_item.top-active + .top-menu_item:after,\n.top-menu.top-style_bar .top-menu_item:hover + .top-menu_item:after {\n\tcontent: none !important;\n}\n\n/*\n.top-style_bar > .top-menu_item > [data-top-badge] {\n\tmargin-top: -3px;\n}\n*/\n\n/** TODO: .top-unwrap-x надо вынести глобально в UI или добавить в стили для storybook */\n/*\n.top-menu.top-unwrap-x {\n\tpadding-right: var(--top-unwrap-x);\n\tpadding-left: var(--top-unwrap-x);\n\tmargin-right: calc(0px - var(--top-unwrap-x));\n\tmargin-left: calc(0px - var(--top-unwrap-x));\n}\n*/\n</style>\n","<script setup lang=\"ts\">\nimport type { EmitsItemMulti, PropsItemMulti } from './types';\n\ndefineProps<PropsItemMulti>();\ndefineEmits<EmitsItemMulti>();\n</script>\n\n<template>\n\t<div class=\"top-selector2_itemMulti top-ellipsis\">\n\t\t{{ name }}\n\n\t\t<span\n\t\t\tclass=\"top-selector2_itemMultiDelete\"\n\t\t\tdata-top-icon=\"\"\n\t\t\t@click=\"$emit('delete', {id, name})\"\n\t\t\t@mousedown.stop\n\t\t></span>\n\t</div>\n</template>\n\n<style>\n.top-selector2_itemMulti {\n\tbox-sizing: border-box;\n\tpadding-left: var(--top-padding-2);\n\tborder-radius: var(--top-radius-1, 4px);\n\tborder: 1px solid var(--color-line-primary-1);\n\tbackground: var(--color-layer-primary-2);\n\tmin-height: 22px;\n\tmax-width: 100%;\n\tcolor: var(--color-text-1);\n\tflex-grow: 0;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: var(--top-gap-1);\n}\n\n.top-selector2_itemMultiDelete {\n\t--top-icon-size: 14px;\n\t--top-icon-width: 18px;\n\t--top-icon-color: var(--color-text-1);\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\tcursor: pointer;\n}\n\n.top-selector2_itemMultiDelete:hover {\n\tbackground: var(--color-layer-primary-2);\n}\n\n@media screen and (min-width: 900px) {\n\t.top-selector2.top-active .top-selector2_itemMultiDelete {\n\t\tz-index: calc(var(--top-popup-z-index) + 1);\n\t}\n}\n</style>\n","import type { Props } from './types';\n\n/**\n * Список кешей для конкретного API метода\n */\nexport const cacheByMethod = new Map<Api.PathAbstract, Map<string, any>>();\n\n/**\n * Сброс кеша конкретного API метода\n */\nexport const clearCache = (apiPath: Api.PathAbstract) => {\n\tcacheByMethod.get(apiPath)?.clear();\n};\n\nexport const genCacheKey = (api: NonNullable<Props['api']>) => {\n\tconst userId = window['mo']?.user?.id;\n\n\tconst cacheKey = JSON.stringify(api.params) + ':' + api.url + ':' + userId;\n\n\treturn cacheKey;\n};\n\nexport const getCache = (cacheKey: string, apiPath: Api.PathAbstract) => {\n\treturn cacheByMethod.get(apiPath)?.get(cacheKey);\n};\n\nexport const setCache = (cacheKey: string, apiPath: Api.PathAbstract, data: any) => {\n\tif (!cacheByMethod.has(apiPath)) {\n\t\tcacheByMethod.set(apiPath, new Map());\n\t}\n\n\tcacheByMethod.get(apiPath)?.set(cacheKey, data);\n};\n","import { ref } from 'vue';\nimport { debounce } from '../../../../core/utils/lodash';\nimport type { Item, Props } from '../types';\nimport { genCacheKey, getCache, setCache } from '../cache';\n\nexport type API = ReturnType<typeof useAPI>;\n\nexport const useAPI = (\n\tapi: Props['api'],\n\tapiSetSearchParams: Props['apiSetSearchParams'],\n\tminLength: number,\n\tuseCache: Props['useCache'],\n) => {\n\t/**\n\t * Список, полученный через API\n\t */\n\tconst items = ref<Item[]>([]);\n\n\t/**\n\t * Флаг - идет загрузка\n\t */\n\tconst isLoading = ref(false);\n\n\tconst countLoading = ref(0);\n\n\tlet searchText = '';\n\tlet nextOffset: number | null | undefined;\n\n\tif (api && !api.params.limit) {\n\t\tapi.params.limit = 100;\n\t}\n\n\t/**\n\t * Выполнить обращение к API\n\t *\n\t * При ошибке вернет undefined\n\t */\n\tconst callAPI = async (): Promise<Api.ResponseSuccess<any, 'get'> | undefined> => {\n\t\tif (!api) return;\n\n\t\tconst cacheKey = useCache ? genCacheKey(api) : undefined;\n\n\t\tif (cacheKey) {\n\t\t\tconst cache = getCache(cacheKey, api.path);\n\t\t\tif (cache) {\n\t\t\t\t// остановить запущенные api запросы\n\t\t\t\tapi.abortByFingerprint();\n\n\t\t\t\treturn cache;\n\t\t\t}\n\t\t}\n\n\t\tconst res = await api.call();\n\n\t\tif (res.errors) return;\n\n\t\tif (!Array.isArray(res.result)) {\n\t\t\tconsole.warn('Array expected in `res.result`');\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst indexWithError = (res.result as Array<Item | any>).findIndex(item => item.id === undefined || item.name === undefined);\n\t\tif (indexWithError !== -1) {\n\t\t\tconsole.warn(`В result[${indexWithError}] нет id или name`);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (cacheKey) {\n\t\t\tsetCache(cacheKey, api.path, res);\n\t\t}\n\n\t\treturn res as Api.ResponseSuccess<any, 'get'>;\n\t};\n\n\t/**\n\t * Загрузить items\n\t */\n\tconst load = async (append: boolean) => {\n\t\tif (!api) return;\n\n\t\tif (append) {\n\t\t\t// данных о следующих страницах не обнаружено\n\t\t\tif (!nextOffset) return;\n\n\t\t\t// дозагружать нельзя, если не завершена предыдущая загрузка\n\t\t\tif (isLoading.value) return;\n\n\t\t\tapi.params.offset = nextOffset;\n\t\t} else {\n\t\t\tapi.params.offset = 0;\n\t\t}\n\n\t\tapiSetSearchParams?.(api, searchText);\n\n\t\tisLoading.value = true;\n\t\tconst res = await callAPI();\n\t\tisLoading.value = false;\n\n\t\tcountLoading.value++;\n\n\t\tif (!res) return;\n\n\t\tnextOffset = res.nextOffset;\n\n\t\tif (append) {\n\t\t\titems.value = items.value.concat(res.result);\n\t\t} else {\n\t\t\titems.value = res.result;\n\t\t}\n\t};\n\n\tconst loadDebounce = debounce(() => load(false), 200);\n\n\t/**\n\t * Выполнить поиск по указанному тексту\n\t *\n\t * Если длина текста меньше minLength, поиск не будет произведен\n\t *\n\t * Если текст не изменился, поиск не будет произведен\n\t *\n\t * @param newSearchText - текст поиска\n\t * @param useDebounce - дедупликация загрузки списка\n\t */\n\tconst setSearchTextAndLoad = (newSearchText: string, useDebounce = true) => {\n\t\tif (!api) return;\n\n\t\t// остановить начатый поиск и сбросить результаты\n\t\tif (newSearchText.length < minLength) {\n\t\t\tapi.abortByFingerprint();\n\n\t\t\titems.value = [];\n\n\t\t\treturn;\n\t\t}\n\n\t\t// условия поиска не поменялись, данные загружены\n\t\tif (newSearchText === searchText && items.value.length) return;\n\n\t\tsearchText = newSearchText;\n\n\t\tif (useDebounce) {\n\t\t\tvoid loadDebounce();\n\t\t} else {\n\t\t\tvoid load(false);\n\t\t}\n\t};\n\n\treturn {\n\t\tapiRequest: api,\n\t\titems,\n\t\tisLoading,\n\t\tcountLoading,\n\t\tload,\n\t\tsetSearchTextAndLoad,\n\t};\n};\n","import type { Item, Props } from './types';\nimport { genFieldFilter } from '@/api/api';\n\n/**\n * Универсальный id для всех элементов \"Все элементы\" / \"Без фильтра\" в `TopSelector`\n */\nexport const ITEM_ID_ALL = 0;\n\n/**\n * Универсальный id для всех добавляемых элементов через `TopSelector`\n */\nexport const ITEM_ID_NEW = null;\n\n/**\n * Выбран ли элемент\n */\nexport const isSelected = (modelValue: Props['modelValue'], item: Item, checkNameForNullId = true) => {\n\tif (checkNameForNullId && item.id === ITEM_ID_NEW) {\n\t\tif (Array.isArray(modelValue)) {\n\t\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id && itemSelected.name === item.name);\n\t\t} else {\n\t\t\treturn item.name === modelValue.name;\n\t\t}\n\t}\n\n\tif (Array.isArray(modelValue)) {\n\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id);\n\t} else {\n\t\treturn item.id === modelValue.id;\n\t}\n};\n\n/**\n * Вспомогательная утилита для создания `callback` функции на добавление фильтра по полю в api запрос\n *\n * Другие фильтры по указанному полю будут удалены\n *\n * @param api - api, которое используется в `TopSelector`\n * @param search - введенная строка поиска\n * @param fieldName - имя поля, по которому надо добавить фильтр на поиск по нестрогому соответствию\n */\nexport const apiSetSearchParamsFilter = (api: NonNullable<Props['api']>, search: string, fieldName: string) => {\n\tlet filters = api.params.filters ?? [];\n\n\t// удаление других фильтров по этому полю\n\tfilters = filters.filter((filter) => filter.name !== fieldName);\n\n\tif (search) {\n\t\tfilters.push(genFieldFilter(fieldName, 'CONTAINS', [search]));\n\t}\n\n\tapi.changeParams({ filters });\n};\n","import { computed, type ComputedRef, ref, type Ref, watch } from 'vue';\nimport { invertKeyboardLayout } from '@/core/utils/keyboard';\nimport type { Item, Props } from '../types';\nimport { type API } from './useAPI';\nimport { isSelected, ITEM_ID_ALL, ITEM_ID_NEW } from '../utils';\nimport { useI18n } from '@/core/plugins/i18n';\n\n/**\n * Функционал поиска\n */\nexport const useMenu = (\n\tmodel: Ref<Props['modelValue']>,\n\temits: ReturnType<typeof defineEmits>,\n\titems: Ref<Props['items']>,\n\tmultiselect: Props['multiselect'],\n\tuseAllItem: Ref<Props['useAllItem']>,\n\tappendSearchToResult: Ref<Props['appendSearchToResult']>,\n\tsearchType: Ref<Props['searchType']>,\n\tminLength: number,\n\tapi: API,\n) => {\n\t/**\n\t * Текст поиска по результатам\n\t */\n\tconst searchText = ref('');\n\n\t/**\n\t * Объект, представляющий опцию \"Все\"\n\t */\n\tconst itemAll = {\n\t\tid: ITEM_ID_ALL,\n\t\tname: useI18n().Common.All as string,\n\t};\n\n\t/**\n\t * Сброс поиска\n\t */\n\tconst resetSearch = () => {\n\t\tsearchText.value = '';\n\t};\n\n\t/**\n\t * Является ли строка поиска достаточной длины для отображения меню\n\t */\n\tconst genIsShort = () => {\n\t\tif (!api.apiRequest) return false;\n\t\tif (searchText.value.length >= minLength) return false;\n\n\t\treturn true;\n\t};\n\n\t/**\n\t * Варианты выбора: props.items + \"Выбрать все\"\n\t */\n\tconst localItems: ComputedRef<Item[]> = computed(() => {\n\t\tconst localItems: Item[] = [];\n\n\t\tif (!multiselect && useAllItem.value) {\n\t\t\tif (typeof useAllItem.value === 'string') {\n\t\t\t\titemAll.name = useAllItem.value;\n\t\t\t}\n\n\t\t\tlocalItems.push(itemAll);\n\t\t}\n\n\t\titems.value?.forEach(item => localItems.push({ ...item }));\n\n\t\treturn localItems;\n\t});\n\n\t/**\n\t * Не используем `computed` в пользу ручного порядка пересчета значения\n\t */\n\tconst itemsForShow = ref<Item[]>([]);\n\n\tconst recalcItemsForShow = () => {\n\t\titemsForShow.value = genItemsForShow();\n\t};\n\n\t/**\n\t * Подготовленный список меню, который содержит в сумме:\n\t * - prop.items: указанный список с учетом фильтра и опций компонента\n\t * - api.items: результаты api запроса, если используется api\n\t *\n\t * @returns Отфильтрованный массив элементов для отображения\n\t */\n\tconst genItemsForShow = () => {\n\t\tconst searchString = searchText.value.toLowerCase();\n\t\tconst searchStringInvertKeyboard = invertKeyboardLayout(searchString);\n\n\t\tlet items: Item[] = [];\n\n\t\t/**\n\t\t * Элемент текущего разделителя в цикле\n\t\t *\n\t\t * Для скрытия / отображения только нужных заголовков и разделителей при поиске\n\t\t *\n\t\t * Логика для `api.items` должна реализовываться в api или api клиенте при генерации элементов\n\t\t */\n\t\tlet itemTitleCategory: Item | undefined;\n\t\tconst itemsCategory: Item[] = [];\n\n\t\t/**\n\t\t * Добавить элементы в результирующий список\n\t\t */\n\t\tconst flushCategory = () => {\n\t\t\t// крайний разделитель не выводить\n\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') {\n\t\t\t\titemsCategory.pop();\n\t\t\t}\n\n\t\t\tif (itemsCategory.length) {\n\t\t\t\tif (itemTitleCategory) {\n\t\t\t\t\titems.push(itemTitleCategory);\n\t\t\t\t}\n\n\t\t\t\titems.push(...itemsCategory);\n\n\t\t\t\titemsCategory.length = 0;\n\t\t\t}\n\t\t};\n\n\t\tfor (const item of localItems.value) {\n\t\t\tswitch (item.listItemProps?.type) {\n\t\t\t\tcase 'title':\n\t\t\t\t\tflushCategory();\n\n\t\t\t\t\titemTitleCategory = item;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'delimiter':\n\t\t\t\t\t// вставить разделитель один раз и только если категория не пуста\n\t\t\t\t\tif (itemsCategory.length) {\n\t\t\t\t\t\tlet index = itemsCategory.length;\n\t\t\t\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') index--;\n\n\t\t\t\t\t\titemsCategory[index] = item;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tconst name = item.name.toLowerCase();\n\t\t\t\t\tif (\n\t\t\t\t\t\titem.id === Number(searchString) ||\n\t\t\t\t\t\tname.includes(searchString) ||\n\t\t\t\t\t\tname.includes(searchStringInvertKeyboard)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (name === searchString || name === searchStringInvertKeyboard) {\n\t\t\t\t\t\t\t// точные совпадения в начало\n\t\t\t\t\t\t\titemsCategory.unshift(item);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titemsCategory.push(item);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tflushCategory();\n\n\t\titems.push(...api.items.value);\n\n\t\t// ввод произвольного значения\n\t\tif (\n\t\t\tappendSearchToResult.value &&\n\t\t\t!!searchText.value &&\n\n\t\t\t// результаты могут быть найдены, но не точные, тогда предложить добавить элемент\n\t\t\t!items.find((item) => item.name.toLowerCase() === searchString)\n\t\t) {\n\t\t\tconst itemNew = {\n\t\t\t\tid: ITEM_ID_NEW,\n\t\t\t\tname: searchText.value,\n\t\t\t};\n\n\t\t\t// предложение всегда отображается внизу, чтобы не мешать результатам поиска\n\t\t\titems.push(itemNew);\n\t\t}\n\n\t\tif (multiselect) {\n\t\t\titems = items.filter(item => !isSelected(model.value, item));\n\t\t}\n\n\t\treturn items;\n\t};\n\n\t/**\n\t * Выбрать элемент\n\t *\n\t * @param item Элемент для выбора\n\t */\n\tconst selectItem = (item: Item) => {\n\t\t// это невыбираемый элемент\n\t\tif (item.listItemProps?.type === 'title' || item.listItemProps?.type === 'delimiter') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (multiselect && Array.isArray(model.value)) {\n\t\t\tif (!isSelected(model.value, item)) {\n\t\t\t\tmodel.value = [...model.value, item];\n\t\t\t}\n\t\t} else {\n\t\t\tmodel.value = item;\n\t\t}\n\n\t\tif (item.id === ITEM_ID_NEW) {\n\t\t\temits('appendItem', item);\n\t\t}\n\n\t\t/**\n\t\t * Отложить перерисовку\n\t\t *\n\t\t * fix: Перерисовка меню выполняется раньше, чем срабатывает `click`.\n\t\t * Из-за этого обработчик кликов думает, что клик был вне меню и не закрывает окно\n\t\t *\n\t\t * Файл: @/components/popup/lib/popup.globalEvents.ts\n\t\t *\n\t\t * Функция: onclick()\n\t\t *\n\t\t * ```\n\t\t * const elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\t\t * ```\n\t\t */\n\t\tsetTimeout(() => {\n\t\t\t/**\n\t\t\t * Завершить поиск после выбора\n\t\t\t */\n\t\t\tresetSearch();\n\t\t});\n\n\t\t// /**\n\t\t// * При изменении значения модели в режиме inline необходимо очистить поле поиска,\n\t\t// * так как поиск больше не актуален после выбора значения\n\t\t// */\n\t\t// if (searchType.value === 'inline') {\n\t\t// \tresetSearch();\n\t\t// }\n\t};\n\n\tif (api.apiRequest) {\n\t\t// загрузка только при открытии popup\n\t\tconst fieldsForWatch: any = [items, api.items];\n\n\t\t// model нужен только для multiselect, без необходимости не использовать для улучшения UX при работе с API\n\t\tif (multiselect) {\n\t\t\tfieldsForWatch.push(model);\n\t\t}\n\n\t\twatch(fieldsForWatch, () => {\n\t\t\trecalcItemsForShow();\n\t\t});\n\t} else {\n\t\twatch([model, items, searchText], () => {\n\t\t\trecalcItemsForShow();\n\t\t}, {\n\t\t\timmediate: true,\n\n\t\t\t// слежение за изменениями `items`\n\t\t\tdeep: 2,\n\t\t});\n\t}\n\n\t/**\n\t * Выбрать следующее значение\n\t */\n\tconst selectNextItem = () => {\n\t\tif (Array.isArray(model.value)) return;\n\n\t\tconst selectableItems = itemsForShow.value.filter((item) => !['title', 'delimiter'].includes(item.listItemProps?.type ?? ''));\n\n\t\tconst currentIndex = selectableItems.findIndex(item => item.id === (model.value as Item).id);\n\t\tconst nextIndex = (currentIndex + 1) % selectableItems.length;\n\t\tmodel.value = { ...selectableItems[nextIndex] };\n\t};\n\n\t/**\n\t * Удалить элемент, `id` и `name` которого равны указанному `item`\n\t */\n\tconst deleteItemByItem = async (item: Item) => {\n\t\tif (Array.isArray(model.value)) {\n\t\t\tmodel.value = model.value.filter((itemI) => itemI.id !== item.id || itemI.name !== item.name);\n\t\t}\n\t};\n\n\treturn {\n\t\tsearchText,\n\t\tresetSearch,\n\t\tgenIsShort,\n\t\titemsForShow,\n\t\tselectItem,\n\t\tselectNextItem,\n\t\tdeleteItemByItem,\n\t};\n};\n","<script setup lang=\"ts\">\nimport { computed, ref, toRef, watch } from 'vue';\nimport Core from '@/core/core/core';\nimport { TopPopup, TopPopupListItem, TopPopupWidgetInput } from '@/components/popup/popup';\nimport { TopPreloader } from '@/components/forms/forms';\nimport type { Emits, Item, Props, Slots } from './types';\nimport Selector2ItemMulti from './itemMulti.vue';\nimport { useAPI } from './composables/useAPI';\nimport { useMenu } from './composables/useMenu';\nimport type { TopLibPopup } from '../../popup/lib/popup';\nimport { clearCache } from './cache';\nimport { ITEM_ID_ALL, ITEM_ID_NEW } from './utils';\n\nconst props = withDefaults(defineProps<Props>(), {\n\titems: () => [] as Item[],\n\tsize: 's',\n\tminLength: 0,\n\tsearchType: 'popup',\n\topenByFocusInput: undefined,\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\ndefineSlots<Slots>();\n\nconst emits = defineEmits<Emits>();\n\ndefineExpose({\n\t/**\n\t * Сброс локального кеша и кеша api\n\t *\n\t * @param resetAPICache - Сбросить API кеш, по умолчанию не сбрасывается. Для случаев, когда загруженные данные становятся неактуальными\n\t */\n\tresetCache: (resetAPICache: boolean = false) => {\n\t\tif (!api.apiRequest) return;\n\n\t\t// сброс кеша api\n\t\tif (resetAPICache) {\n\t\t\tclearCache(api.apiRequest.path);\n\t\t}\n\n\t\t// сброс кеша списка\n\t\tapi.items.value = [];\n\n\t\t// сброс флага первичной загрузки\n\t\tapi.countLoading.value = 0;\n\n\t\t// сброс параметров дозагрузки\n\t\tapi.apiRequest.params.offset = 0;\n\n\t\t// сброс кеша локального списка с дополнительными элементами, например `useAllItem`\n\t\trequestAnimationFrame(() => {\n\t\t\tmenu.itemsForShow.value = [];\n\t\t});\n\n\t\t// сразу загрузить данные после сброса, если popup уже открыт\n\t\tif (getPopup()?.elPopup) {\n\t\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t\t}\n\t},\n});\n\nconst searchTypeLocal = computed(() => {\n\t// multiselect не поддерживает inline ввода\n\tif (props.searchType === 'inline' && props.multiselect) return 'popup';\n\n\t// В мобильной версии popup работает в полноэкранном режиме\n\tif (props.searchType === 'inline' && Core.state.isMobile) return 'popup';\n\n\treturn props.searchType;\n});\n\n/**\n * Объект для работы с API\n */\nconst api = useAPI(props.api, props.apiSetSearchParams, props.minLength, props.useCache);\n\n/**\n * Объект для работы с меню\n */\nconst menu = useMenu(\n\tmodel,\n\temits,\n\ttoRef(props, 'items'),\n\tprops.multiselect,\n\ttoRef(props, 'useAllItem'),\n\ttoRef(props, 'appendSearchToResult'),\n\tsearchTypeLocal,\n\tprops.minLength,\n\tapi,\n);\n\nconst component = computed(() => {\n\tif (props.buttonProps) return 'TopButton';\n\tif (searchTypeLocal.value === 'inline') return 'TopInput';\n\n\treturn 'div';\n});\n\n/**\n * Экземпляр компонента Popup\n */\nconst popupRef = ref<any>(null);\n\n/**\n * Получить доступ к объекту popup\n */\nconst getPopup = (): TopLibPopup | undefined => {\n\treturn popupRef.value?.popup;\n};\n\nif (api.apiRequest) {\n\t// отложенный поиск при вводе текста\n\twatch(menu.searchText, () => {\n\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t});\n}\n\nconst placeholder = computed(() => {\n\tif (Array.isArray(model.value) || props.multiselect || !props.selectedAsPlaceholder && searchTypeLocal.value !== 'inline') {\n\t\treturn props.placeholder;\n\t}\n\n\treturn model.value?.name || props.placeholder;\n});\n\n/**\n * Обработчик ввода клавиш на кнопке или поле ввода\n */\nconst onOpenerKeydown = (e: KeyboardEvent) => {\n\tlet needOpen = false;\n\n\tswitch (e.key) {\n\t\tcase 'Delete':\n\t\tcase 'Backspace':\n\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\n\t\t\t\tmodel.value.pop();\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'ArrowUp':\n\t\tcase 'ArrowRight':\n\t\tcase 'ArrowDown':\n\t\tcase 'ArrowLeft':\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\t\tneedOpen = true;\n\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\tif (searchTypeLocal.value === 'inline') {\n\t\t\t\t// очистка введенного текста\n\t\t\t\tmenu.resetSearch();\n\t\t\t}\n\n\t\t\tbreak;\n\t}\n\n\t// введен символ\n\tconst symbolPressed = e.key.length === 1 && !e.ctrlKey && !e.metaKey;\n\n\t// введен символ\n\tif (searchTypeLocal.value === 'popup' || searchTypeLocal.value === 'inline') {\n\t\tif (symbolPressed) {\n\t\t\tneedOpen = true;\n\t\t}\n\t}\n\n\t// popup уже открыт\n\tif (getPopup()?.elPopup) {\n\t\tneedOpen = false;\n\t}\n\n\tif (needOpen) {\n\t\tif (searchTypeLocal.value === 'popup') {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// введен символ\n\t\t\tif (symbolPressed) {\n\t\t\t\t// начало ввода, сразу ввести первый символ вместе с открытием popup\n\t\t\t\tif (!menu.searchText.value) {\n\t\t\t\t\tmenu.searchText.value = e.key;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t(e.currentTarget as HTMLElement)?.click();\n\t}\n};\n\nconst onClickChanger = (e: MouseEvent) => {\n\te.preventDefault();\n\n\tmenu.selectNextItem();\n};\n\n/**\n * Обработчик открытия попапа\n */\nconst onOpen = () => {\n\tif (api.apiRequest) {\n\t\t// при открытии сразу выполнить поиск\n\t\tapi.setSearchTextAndLoad(menu.searchText.value, false);\n\t}\n};\n\n/**\n * Обработчик закрытия попапа\n */\nconst onClose = () => {\n\t// очистка введенного текста, в режиме `inline` input вызывается при `blur`\n\tif (searchTypeLocal.value === 'popup') {\n\t\tif (menu.searchText.value) menu.resetSearch();\n\t}\n};\n\n/**\n * Обработчик прокрутки списка контента\n *\n * Для дозагрузки элеменов через api\n *\n * @param {Event} e - Событие прокрутки\n */\nconst onScrollContentList = (e: Event) => {\n\tconst el = e.target as HTMLElement;\n\n\tif (el.scrollTop / (el.scrollHeight - el.offsetHeight) > 0.8) {\n\t\tapi.load(true);\n\t}\n};\n\nif (import.meta.env.STORYBOOK) {\n\twatch(\n\t\t() => props.multiselect,\n\t\t() => {\n\t\t\tif (props.multiselect) {\n\t\t\t\tif (!Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tname: 'Выбери меня',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = {\n\t\t\t\t\t\tid: null,\n\t\t\t\t\t\tname: '',\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ immediate: true },\n\t);\n\n\twatch(\n\t\t() => props.searchType,\n\t\t() => {\n\t\t\t// пауза для установки props в адресной строке\n\t\t\tsetTimeout(() => {\n\t\t\t\tlocation.reload();\n\t\t\t}, 500);\n\t\t},\n\t);\n}\n</script>\n\n<template>\n\t<TopPopup\n\t\tref=\"popupRef\"\n\t\t@open=\"onOpen()\"\n\t\t@close=\"onClose()\"\n\t\t@scrollContentList=\"api ? onScrollContentList($event) : undefined\"\n\t\t:notch=\"false\"\n\t\t:transitionDuration=\"0\"\n\t\t:openByFocusInput=\"searchTypeLocal === 'inline' && (openByFocusInput ?? true)\"\n\t\t:disabled=\"searchTypeLocal === 'inline' && menu.genIsShort()\"\n\t>\n\t\t<template #opener>\n\t\t\t<component\n\t\t\t\t:is=\"component\"\n\n\t\t\t\t:=\"buttonProps\"\n\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-selector2': true,\n\t\t\t\t\t'top-selector2-multiselect': multiselect,\n\t\t\t\t\t['top-selector2-' + modificator]: !!modificator,\n\t\t\t\t\t'top-as-input': !buttonProps && searchTypeLocal !== 'inline',\n\t\t\t\t\t'top-as-selector': true,\n\t\t\t\t\t['top-size_' + size]: true,\n\t\t\t\t\t['top-disabled']: disabled,\n\t\t\t\t\t['top-forms-focusable']: !disabled,\n\t\t\t\t\t['top-error']: isError,\n\t\t\t\t}\"\n\t\t\t\t:icon\n\t\t\t\ttabindex=\"0\"\n\t\t\t\t@keydown=\"onOpenerKeydown\"\n\t\t\t\t@blur=\"searchTypeLocal === 'inline' && menu.resetSearch()\"\n\t\t\t\tv-top-focus.onupdate=\"isError\"\n\n\t\t\t\t:placeholder\n\t\t\t\t:title\n\t\t\t\t:captionType=\"searchTypeLocal === 'inline' && title !== undefined ? 'top' : undefined\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t>\n\t\t\t\t<template v-if=\"multiselect\">\n\t\t\t\t\t<div class=\"top-selector2_activeItems\">\n\t\t\t\t\t\t<Selector2ItemMulti\n\t\t\t\t\t\t\tv-for=\"item of model as Item[]\"\n\t\t\t\t\t\t\t:id=\"item.id\"\n\t\t\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t\t\t\t@delete=\"menu.deleteItemByItem\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<span v-if=\"searchTypeLocal !== 'inline' && !multiselect\" class=\"top-selector2_activeName top-ellipsis\">\n\t\t\t\t\t{{ !Array.isArray(model) ? model.name : '' }}\n\t\t\t\t</span>\n\n\t\t\t\t<span v-if=\"multiselect && !model.length\" class=\"top-selector2_placeholder top-ellipsis\">\n\t\t\t\t\t{{ placeholder }}\n\t\t\t\t</span>\n\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"addChanger && !buttonProps && !multiselect && menu.itemsForShow.value.length > 1 && !disabled\"\n\t\t\t\t\tclass=\"top-changer top-changer-selector\"\n\t\t\t\t\tdata-top-popup-disabled=\"true\"\n\t\t\t\t\t@click=\"onClickChanger\"\n\t\t\t\t></span>\n\t\t\t</component>\n\t\t</template>\n\n\t\t<template #widget v-if=\"searchTypeLocal === 'popup'\">\n\t\t\t<TopPopupWidgetInput\n\t\t\t\ttitle=\"Поиск\"\n\t\t\t\ticon=\"\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t\tv-top-focus.onupdate=\"model\"\n\t\t\t\t:isLoading=\"!!api.countLoading.value && api.isLoading.value\"\n\t\t\t\t:placeholder\n\t\t\t/>\n\t\t</template>\n\n\t\t<template #contentList>\n\t\t\t<TopPopupListItem\n\t\t\t\tv-for=\"item of menu.itemsForShow.value\"\n\t\t\t\t:key=\"item.id ?? undefined\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-active': !Array.isArray(model) && !multiselect && model.id === item.id && model.name === item.name,\n\t\t\t\t\t'top-selector2_item-all':item.id === ITEM_ID_ALL,\n\t\t\t\t\t'top-selector2_item-new':item.id === ITEM_ID_NEW,\n\t\t\t\t}\"\n\t\t\t\t:=\"item.listItemProps\"\n\t\t\t\t:closeByClick=\"!multiselect || Core.state.isMobile\"\n\t\t\t\t@click=\"menu.selectItem(item)\"\n\t\t\t>\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"$slots.item\"\n\t\t\t\t\tname=\"item\"\n\t\t\t\t\t:item\n\t\t\t\t></slot>\n\n\t\t\t\t<template\n\t\t\t\t\tv-else\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</template>\n\t\t\t</TopPopupListItem>\n\n\t\t\t<!-- Элементов для отображения нет -->\n\t\t\t<template v-if=\"!menu.itemsForShow.value.length && !menu.genIsShort()\">\n\t\t\t\t<TopPopupListItem type=\"regular\">\n\t\t\t\t\t<template v-if=\"!api.isLoading.value || api.countLoading.value\">\n\t\t\t\t\t\t{{ $i18n.Common.No_results }}\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<!-- Индикатор первичной загрузки -->\n\t\t\t\t\t<TopPreloader\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"circles\"\n\t\t\t\t\t/>\n\t\t\t\t</TopPopupListItem>\n\t\t\t</template>\n\n\t\t\t<!-- Индикатор повторной загрузки -->\n\t\t\t<TopLoadbar v-if=\"!!api.countLoading.value && api.isLoading.value && searchTypeLocal === 'inline'\"/>\n\t\t</template>\n\t</TopPopup>\n</template>\n\n<style>\n.top-selector2 {\n\twidth: 180px;\n}\n\n.top-selector2::placeholder,\n.top-selector2_placeholder {\n\tcolor: var(--color-text-2);\n}\n\n.top-selector2_placeholder {\n\tpadding-left: var(--top-padding-1);\n}\n\n.top-selector2.top-as-input {\n\tpadding: var(--top-padding-1) var(--top-forms-padding);\n}\n\n.top-selector2.top-selector2-multiselect {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tflex-grow: 1;\n}\n\n.top-selector2.top-active {\n\t--top-forms-border-color: var(--top-forms-border-color-hover);\n}\n\n.top-selector2_activeItems {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--top-padding-1);\n\tmax-width: 100%;\n}\n\n.top-selector2_activeName {\n\twhite-space: nowrap;\n}\n\n.top-changer-selector {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tmargin: calc(0px - var(--top-padding-1));\n\ttransform: translateX(0);\n}\n\n.top-selector2.top-button {\n\tjustify-content: start;\n}\n\n.top-selector2.top-input_input ~ .top-changer-selector {\n\ttransform: translateX(-52px);\n}\n\n.top-selector2.top-as-selector {\n\tpadding-right: calc(var(--top-selector-arrow-width) + var(--top-padding-2));\n}\n</style>\n"],"names":["el","vue","props","model","itemIsActive","item","index","modelNew","onWheel","event","delta","scrollIntoView","isSmooth","leftMargin","elBtn","gap","rightMargin","leftMarginParent","rightMarginParent","scrollLeft","$event","select","_cache","selectAll","__props","_ctx","cacheByMethod","clearCache","apiPath","genCacheKey","api","getCache","cacheKey","data","items","isLoading","countLoading","nextOffset","cache","res","indexWithError","load","append","apiSetSearchParams","searchText","callAPI","loadDebounce","forms","newSearchText","minLength","ITEM_ID_ALL","ITEM_ID_NEW","modelValue","itemSelected","apiSetSearchParamsFilter","search","fieldName","filters","filter","field","localItems","multiselect","useAllItem","itemAll","localItems2","itemsForShow","genItemsForShow","searchStringInvertKeyboard","utils_keyboard","searchString","itemTitleCategory","itemsCategory","items2","flushCategory","itemNew","isSelected","selectItem","emits","resetSearch","fieldsForWatch","recalcItemsForShow","genIsShort","selectableItems","itemI","__expose","resetAPICache","menu","getPopup","searchTypeLocal","component","popupRef","placeholder","onOpenerKeydown","e","symbolPressed","onClickChanger","onScrollContentList","onOpen","onClose","_hoisted_1","popupHint_vue_vue_type_style_index_0_lang"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"popup-DRuyYFGB.amd.js","sources":["../../src/components/component.ts","../../src/components/popup/lib/popup.globalEvents.ts","../../src/components/popup/lib/popup.ts"],"sourcesContent":["import DOM from '@/core/utils/dom';\n\n/**\n * Базовый компонент для js компонентов, не имеет отношения к Vue\n */\nclass Component {\n\n\tstatic componentName = 'Top';\n\n\tcomponentName: string | undefined; // имя класса компонента\n\tclassName: string | undefined; // имя css класса компонента\n\tuid: string | undefined; // уникальный id компонента\n\tel: HTMLElement | undefined; // элемент, связанный с компонентом\n\toptions = {}; // параметры компонента\n\n\tunmountEls: HTMLElement[] = [];\n\tunmountEvents: any[] = [];\n\n\t// переопредлять нельзя\n\t// если компонент инициирован, необходимо сразу его вернуть и выполнить reInit() вместо mount()\n\t// используется init вместо constructor, так как super constructor выполняется до Object.defineProperty() параметров класса\n\tinit(componentName: string, el: HTMLElement, options: object): Component | void {\n\t\tif (!el) {\n\t\t\tthrow componentName + ': el is undefined';\n\t\t}\n\n\t\tconst component = Component.getComponent(el, componentName);\n\n\t\tif (component) {\n\t\t\tcomponent.reInit(options);\n\n\t\t\treturn component;\n\t\t}\n\n\t\tthis.componentName = componentName;\n\t\tthis.className = 'top' + componentName[0].toUpperCase() + componentName.substring(1);\n\t\tthis.uid = this.componentName + (Math.random() + '').replace('.', '');\n\n\t\tthis._setComponent(el);\n\t\tthis.el = el;\n\t\tthis.el.classList.add(this.className);\n\t\tthis.options = Object.assign(this.options, options);\n\n\t\tthis.mount();\n\t}\n\n\t// получить инициированный компонент\n\tstatic getComponent(el: HTMLElement, componentName: string): any {\n\t\treturn DOM.storage(el, '#' + componentName);\n\t}\n\n\t// устанвоить компонент\n\t_setComponent(el: HTMLElement) {\n\t\tDOM.storage(el, '#' + this.componentName, this);\n\t}\n\n\t// функция подключения компонента\n\tmount(): void {\n\t\tthrow 'Please, add method mount() to component: ' + this.componentName;\n\t}\n\n\t// функция отключения компонента\n\tunmount(): void {\n\t\tDOM.storage(this.el, '#' + this.componentName, null);\n\n\t\tthis.unmountEls.forEach((el) => {\n\t\t\tel.remove();\n\t\t});\n\n\t\tthis.unmountEls = [];\n\n\t\tthis.unmountEvents.forEach((eventData) => {\n\t\t\teventData.el.removeEventListener(eventData.type, eventData.listener, eventData.options);\n\t\t});\n\n\t\tthis.unmountEvents = [];\n\t}\n\n\t// указание новые элементы, которые должны будут удалиться после unmount\n\tregisterElForUnmount(el: HTMLElement): void {\n\t\tthis.unmountEls.push(el);\n\t}\n\n\t// указание новые события, которые должны будут удалиться после unmount\n\taddEventListenerWithUnmount(\n\t\tel: HTMLElement | Document | Window,\n\t\ttype: keyof GlobalEventHandlersEventMap,\n\t\tlistener: (this: HTMLElement, e: Event) => any,\n\t\toptions?: any,\n\t): void {\n\t\tel.addEventListener(type, listener, options);\n\n\t\tthis.registerEventForUnmount(el, type, listener, options);\n\t}\n\n\t// указание новые события, которые должны будут удалиться после unmount\n\tregisterEventForUnmount(\n\t\tel: HTMLElement | Document | Window,\n\t\ttype: keyof GlobalEventHandlersEventMap,\n\t\tlistener: (this: HTMLElement, e: Event) => any,\n\t\toptions?: any,\n\t): void {\n\t\tconst eventData = {\n\t\t\tel: el,\n\t\t\ttype: type,\n\t\t\tlistener: listener,\n\t\t\toptions: options,\n\t\t};\n\n\t\tthis.unmountEvents.push(eventData);\n\t}\n\n\t// функция перенастройки уже подключенного компонента\n\treInit(_options: object): void {\n\t\tthrow 'Please, add method reInit() to component: ' + this.componentName;\n\t}\n\n\t// удалить элементы из DOM, но не из памяти\n\tstatic detach(nodes: NodeList | HTMLElement): void {\n\t\tif (nodes instanceof NodeList) {\n\t\t\tnodes.forEach((node) => node.parentElement?.removeChild(node));\n\t\t} else {\n\t\t\tconst el = nodes;\n\t\t\tel.parentElement?.removeChild(el);\n\t\t}\n\t}\n\n}\n\nexport default Component;\n","import Worker from '@/components/popup/lib/worker';\nimport DOM from '@/core/utils/dom';\n\n/**\n * Глобальные события, для реализации Popup\n * Автоматически инициируется при первой загрузке, не является выгружаемым модулем\n *\n * Если в меню встречает класс .preloader, то событие нажатия на кнопку через enter будет остановлено\n */\nclass GlobalEvents {\n\n\tprivate static isInited = false;\n\n\t/**\n\t * Добавить глобальные обработчики\n\t *\n\t * Добавляются на страницу один раз и навсегда\n\t */\n\tstatic init(): void {\n\t\tif (this.isInited) return;\n\n\t\tthis.isInited = true;\n\n\t\tdocument.addEventListener('click', this.onclickCapture, { capture: true });\n\t\tdocument.addEventListener('click', this.onclick);\n\t\tdocument.addEventListener('keydown', this.onkeydown);\n\t}\n\n\t/**\n\t * Глобальный обработчик захватов кликов\n\t *\n\t * Обрабатывает захватов клики внутри Popup\n\t */\n\tprivate static onclickCapture(e: Event): void {\n\t\tif (!(e.target instanceof HTMLElement)) return;\n\n\t\t// меню\n\t\tconst elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\n\t\t// клик вне меню\n\t\tif (!elPopup) {\n\t\t\treturn;\n\t\t}\n\n\t\t// клик по кнопке открытия другого меню\n\t\tif (e.target.matches('[data-top-popup]')) {\n\t\t\t// список меню, в котором был сделан клик\n\t\t\tconst elUl = e.target.closest<HTMLElement>('ul');\n\n\t\t\t// элемент меню, по которому был сделан клик\n\t\t\tconst elItem = e.target.closest<HTMLElement>('a, .a');\n\n\t\t\t// сделать элемент меню, по которому сделан клик активным\n\t\t\tif (elUl) {\n\t\t\t\telUl.querySelector('a.top-active, .a.top-active')?.classList.remove('top-active');\n\t\t\t}\n\n\t\t\tif (elItem) {\n\t\t\t\telItem.classList.add('top-active');\n\t\t\t}\n\n\t\t\te.stopPropagation();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// клик по фону меню\n\t\tif (e.target.matches('.top-popup-wrapper')) {\n\t\t\tconst elPopup = e.target;\n\n\t\t\tWorker.close(elPopup, true);\n\n\t\t\te.stopPropagation();\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/**\n\t * Глобальный обработчик кликов\n\t *\n\t * Обрабатывает клики внутри Popup\n\t */\n\tprivate static onclick(e: Event): void {\n\t\tif (!(e.target instanceof HTMLElement)) return;\n\n\t\t// элементы меню, клик по которым должен его закрыть\n\t\tconst elCloser = e.target.closest<HTMLElement>('.closer, a, .a, .top-button');\n\t\tif (elCloser) {\n\t\t\t// меню\n\t\t\tconst elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\n\t\t\t// клик вне меню\n\t\t\tif (!elPopup) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// элемент имеет модификатор, запрещаюущий закрытие меню по клику на него\n\t\t\tif (elCloser.matches('.top-popup-noCloser')) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// deprecated, ссылки с href=\".\" запрещены, они должны быть заменены на .top-popup_listItem-button\n\t\t\tif (elCloser.getAttribute('href') === '.') {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\n\t\t\t// закрыть меню\n\t\t\tWorker.close(elPopup, true);\n\t\t}\n\t}\n\n\t/**\n\t * Глобальный обработчик нажатия кнопки на клавиатуре\n\t */\n\tprivate static onkeydown(e: KeyboardEvent): void {\n\t\tif (!(e.target instanceof HTMLElement)) return;\n\n\t\tlet elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\n\t\tif (!elPopup) {\n\t\t\telPopup = Worker.getPopupFromOpener(e.target)?.elPopup ?? null;\n\t\t}\n\n\t\t// нажатие не в меню\n\t\tif (!elPopup) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst elUl = elPopup.querySelector<HTMLElement>('ul.top-popup_content');\n\n\t\tswitch (e.key) {\n\t\t\tcase 'Escape':\n\t\t\t\tWorker.close(elPopup, true);\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'Enter':\n\t\t\t\t// атоматическое нажатие кнопок при нажатии Enter\n\t\t\t\tif (!elUl) {\n\t\t\t\t\tif (DOM.querySelectorVisible(elPopup, '.preloader')) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t// deprecated, старый код на сайте\n\t\t\t\t\tconst elBtn = DOM.querySelectorVisible(elPopup, '.top-popup_footer .go, .top-popup_footer [data-action]');\n\t\t\t\t\tif (elBtn instanceof HTMLElement) {\n\t\t\t\t\t\telBtn.click();\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Запуск клика последней кнопки, расположенной в footer'е Popup'а, нажатием клавиши Enter\n\t\t\t\t\tlet elFooterLastBtn = DOM.querySelectorVisibleLast(elPopup, '.top-popup_footer .top-button:focus');\n\t\t\t\t\tif (!elFooterLastBtn) elFooterLastBtn = DOM.querySelectorVisibleLast(elPopup, '.top-popup_footer .top-button');\n\t\t\t\t\tif (elFooterLastBtn instanceof HTMLElement) {\n\t\t\t\t\t\telFooterLastBtn.click();\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// перейти по ссылке по нажатию на Enter\n\t\t\t\t// данный функуционал игнорирует SPA\n\t\t\t\tconst elLink = DOM.querySelectorVisible(elPopup, 'li > a.top-active');\n\t\t\t\tif (elLink && elLink.getAttribute('href')) {\n\t\t\t\t\t// фокус может находиться на другой ссылке\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\tlocation.href = elLink.getAttribute('href')!;\n\t\t\t\t}\n\n\t\t\t\t// кликнуть по элементу меню по нажатию на Enter\n\t\t\t\tconst elItem = elPopup.querySelector<HTMLElement>('li > .top-active');\n\t\t\t\tif (elItem instanceof HTMLElement) {\n\t\t\t\t\telItem.click();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\t// управление стрелками\n\t\t\tcase 'ArrowUp':\n\t\t\tcase 'ArrowRight':\n\t\t\tcase 'ArrowDown':\n\t\t\tcase 'ArrowLeft':\n\t\t\t\tif (!elUl) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {\n\t\t\t\t\tconst elMoreVisible = DOM.querySelectorVisible(\n\t\t\t\t\t\telPopup,\n\t\t\t\t\t\t'ul.top-popup_content > li:not(.top-popup_liNoSelectable) > .top-active > .top-popup_listMore',\n\t\t\t\t\t);\n\n\t\t\t\t\tif (elMoreVisible) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}else if((e.target as HTMLElement).tagName === 'INPUT'){\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\n\t\t\t\tconst elItemActive = elPopup.querySelector<HTMLElement>('ul.top-popup_content > li:not(.top-popup_liNoSelectable) > .top-active')?.parentElement;\n\n\t\t\t\t// есть подменю\n\t\t\t\tif (e.key === 'ArrowRight' && elItemActive) {\n\t\t\t\t\t// const elItemMoreActive = elItemActive.querySelector<HTMLElement>('[data-top-popup].top-active');\n\t\t\t\t\t// if (elItemMoreActive) {\n\t\t\t\t\t// \treturn elItemMoreActive.click();\n\t\t\t\t\t// }\n\n\t\t\t\t\tconst elMore = elItemActive.querySelector<HTMLElement>('.top-active > .top-popup_listMore');\n\t\t\t\t\tif (elMore instanceof HTMLElement) {\n\t\t\t\t\t\treturn elMore.click();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst elsLiVisible = DOM.querySelectorAllVisible(elPopup, 'ul.top-popup_content > li:not(.top-popup_liNoSelectable)');\n\t\t\t\tconst countLi = elsLiVisible.length;\n\n\t\t\t\tif (!countLi) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet index = -1;\n\t\t\t\tif (elItemActive) {\n\t\t\t\t\tindex = elsLiVisible.indexOf(elItemActive);\n\t\t\t\t}\n\n\t\t\t\tif (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {\n\t\t\t\t\tindex--;\n\t\t\t\t} else {\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\n\t\t\t\t// это первый элемен, \"Назад\" должен закрывать окно\n\t\t\t\tif (e.key === 'ArrowLeft' && index === -1) {\n\t\t\t\t\tif (e.target.matches('input')) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Worker.close(elPopup, true);\n\t\t\t\t}\n\n\t\t\t\t// это последний элемен, \"Вперед\" не должен ни чего делать\n\t\t\t\tif (e.key === 'ArrowRight' && index === countLi) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (index < 0) {\n\t\t\t\t\tindex = countLi - 1;\n\t\t\t\t}\n\n\t\t\t\tif (index > countLi - 1) {\n\t\t\t\t\tindex = 0;\n\t\t\t\t}\n\n\t\t\t\telPopup.querySelectorAll('ul.top-popup_content > li > .top-active').forEach(el => el.classList.remove('top-active'));\n\t\t\t\telsLiVisible[index].querySelector(':scope > a, :scope > .a')?.classList.add('top-active');\n\n\t\t\t\tWorker.scrollToActive(elPopup);\n\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n}\n\nexport default GlobalEvents;\n","import Core from '@/core/core/core';\nimport Component from '@/components/component';\nimport DOM from '@/core/utils/dom';\nimport Worker from '@/components/popup/lib/worker';\nimport GlobalEvents from '@/components/popup/lib/popup.globalEvents';\n\nimport css from '@/components/popup/popup/style/popup.css?inline';\nimport cssM from '@/components/popup/popup/style/popup.m.css?inline';\nimport cssPC from '@/components/popup/popup/style/popup.pc.css?inline';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { OpenerProps } from '@/components/popup/popup/opener/types';\n\nCore.insertStyleToPage(css);\nCore.insertStyleToPage(cssM, 'm');\nCore.insertStyleToPage(cssPC, 'pc');\n\nexport interface PopupOptions {\n\tpopup?: string,\n\tid?: string,\n\tp?: number,\n\tnotch?: boolean,\n\tclass?: string,\n\tposBy?: 'left' | 'right' | 'fixed' | Element,\n\tfrontSelector?: string,\n\tinvertX?: boolean,\n\topenByHover?: boolean,\n\tuseOriginal?: boolean,\n\ttransitionDuration?: number,\n\tisFullScreen?: boolean,\n}\n\n/**\n * Основной объект js компонента TopPopup\n *\n * Добавляет jQuery события на this.el, если jQuery загружен:\n *\n * - aftershow.top-menu-popup\n * - afterclose.top-menu-popup\n */\nexport class TopLibPopup<T extends Record<string, any> | undefined = undefined> extends Component {\n\n\tstatic componentName = 'TopPopup';\n\n\tdeclare el: HTMLElement & { __TopPopupOpenerProps: OpenerProps<T> }; // элемент, вызвавший открытие Popup\n\telActiveByDefault: boolean | undefined; // элемент уже имеет класс top-active перед открытием окна\n\telPopup: HTMLElement | undefined; // Popup .top-popup-wrapper\n\telPopupInner: HTMLElement | undefined; // контентная часть Popup .top-popup\n\telPopupHeader: HTMLElement | undefined | null;\n\telPopupWidget: HTMLElement | undefined | null;\n\telPopupBody: HTMLElement | undefined | null;\n\telPopupFooter: HTMLElement | undefined | null;\n\telFront: HTMLElement | undefined | null;\n\n\t/**\n\t * Для openerIsInput фокусировка срабатывает при входе в поле ввода\n\t *\n\t * Фокусировка на сам Popup не производится\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/combobox_role\n\t */\n\topenerIsInput = false;\n\n\tpopupParent: TopLibPopup | undefined;\n\n\t$: JQuery<HTMLElement> | undefined; // только если есть jQuery\n\n\telStartPosition: HTMLElement | undefined | null; // используется для useOriginal\n\tshift = {\n\t\ttop: 0,\n\t\tleft: 0,\n\t};\n\tisClosed = false; // флаг того, что меню закрыто\n\tisFirstClick = true;\n\ttype: string | undefined; // selector или html\n\n\toptions: PopupOptions = {\n\t\tpopup: '', // selector, text\n\t\tp: 0, // положение меню (0 - над элементом, 1 - сверху, 2 - справа, 3 - снизу, 4 слева)\n\t\tnotch: false, // отображать ли клювик\n\n\t\tclass: '', // класс, добавляемый меню\n\n\t\tposBy: 'left', // способ привязки позиционирования меню (left/right - левый/правый край родителя, fixed - по документу)\n\t\tfrontSelector: '',\n\t\tinvertX: false, // базовая ордината - правая граница элемента, а не левая\n\t\topenByHover: false, // открывать при наведении\n\n\t\tuseOriginal: false, // использовать оригинальный шаблон, без клонирвоания (для сохранения состояния меню)\n\n\t\ttransitionDuration: 100, // значение прописано в css\n\n\t\tisFullScreen: false,\n\t};\n\n\tevents = {};\n\n\t/**\n\t * Создать Popup\n\t * @param el - элемент, открывающий меню\n\t * @param options\n\t */\n\tconstructor(el: HTMLElement, options: PopupOptions) {\n\t\tsuper();\n\n\t\tthis.init(TopLibPopup.componentName, el, options);\n\t}\n\n\tasync mount(): Promise<void> {\n\t\tif (!(this.el instanceof HTMLElement)) return;\n\t\tconst vueConnector = this.vueGetComponent();\n\n\t\tif (this.el.closest('.top-popup-wrapper')) this.popupParent = Worker.getPopup(this.el.closest('.top-popup-wrapper')!);\n\n\t\tawait this.mountJQuery();\n\n\t\tif (DOM.css(this.el, 'position') !== 'absolute') {\n\t\t\tthis.el.style.position = 'relative';\n\t\t}\n\n\t\tthis.el.dataset.topPopupOpened = 'opened';\n\t\tthis.elActiveByDefault = this.el.classList.contains('top-active');\n\t\tthis.el.classList.add('top-active');\n\n\t\tthis.openerIsInput = this.el.classList.contains('top-input');\n\n\t\t// todo: удалить после переписать TopProjectSelector на vue\n\t\tif (this.el.classList.contains('top-input-project_name')) {\n\t\t\tthis.openerIsInput = false;\n\t\t}\n\n\t\tif (this.openerIsInput) {\n\t\t\tconst elInput = this.el.querySelector('input');\n\t\t\tif (elInput && !elInput['__popupOnBlur']) {\n\t\t\t\telInput['__popupOnBlur'] = true;\n\n\t\t\t\telInput.addEventListener('blur', e => {\n\t\t\t\t\t// элемент один, экземпляры popup разные\n\t\t\t\t\tWorker.getPopupFromOpener(this.el)?.close();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (vueConnector) {\n\t\t\t// компонент vue Popup\n\t\t\tthis.type = 'vue';\n\n\t\t\tthis.options.popup = '';\n\t\t\tthis.elPopup = DOM.genEl('div', {}, this.options.popup);\n\t\t} else if (this.options.popup?.match(/^[#.]/)) {\n\t\t\t// selector\n\t\t\tthis.type = 'selector';\n\n\t\t\tthis.elPopup = document.querySelector<HTMLElement>(`${this.options.popup}.template`) || undefined;\n\t\t} else {\n\t\t\t// html\n\t\t\tthis.type = 'html';\n\n\t\t\tif (this.options.useOriginal) {\n\t\t\t\tthrow ('Option useOriginal not allowed for text templates');\n\t\t\t}\n\n\t\t\tthis.elPopup = DOM.genEl('div', {}, this.options.popup ?? '');\n\t\t}\n\n\t\tif (!this.elPopup || vueConnector?.opened) {\n\t\t\t// возможно шаблон не найден, так как он используется в уже открытом меню\n\t\t\tif (this.options.useOriginal || vueConnector?.opened) {\n\t\t\t\t// закрыть открытое меню\n\t\t\t\tif (vueConnector?.opened) {\n\t\t\t\t\tthis.elPopup = vueConnector.popup.elPopup;\n\t\t\t\t} else {\n\t\t\t\t\tthis.elPopup = document.querySelector<HTMLElement>(`${this.options.popup}.top-popup-wrapper-shown`) || undefined;\n\t\t\t\t}\n\n\t\t\t\tif (this.elPopup) {\n\t\t\t\t\tthis.el.dataset.topPopupOpened = '';\n\n\t\t\t\t\tif (!this.elActiveByDefault) {\n\t\t\t\t\t\tthis.el.classList.remove('top-active');\n\t\t\t\t\t}\n\n\t\t\t\t\tWorker.close(this.elPopup);\n\n\t\t\t\t\t// повторит попытку открыть меню\n\t\t\t\t\tsetTimeout(() => this.mount(), this.options.transitionDuration);\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthrow ('Option useOriginal state allowed only elements .template');\n\t\t\t}\n\n\t\t\t// возможно вместо шаблона используется другой элемент\n\t\t\tthis.elPopup = document.querySelector<HTMLElement>(`${this.options.popup}:not(.top-popup-wrapper)`) || undefined;\n\t\t}\n\n\t\tif (!this.elPopup) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.options.useOriginal) {\n\t\t\tthis.elStartPosition = this.elPopup.closest<HTMLElement>('.top-popup-el-start-position');\n\t\t\tif (!this.elStartPosition) {\n\t\t\t\tthis.elStartPosition = DOM.wrap(this.elPopup, 'i');\n\t\t\t\tthis.elStartPosition.classList.add('top-popup-el-start-position', 'hidden');\n\t\t\t}\n\t\t} else {\n\t\t\tthis.elPopup = this.elPopup.cloneNode(true) as HTMLElement;\n\n\t\t\t// вывод в меню копии произвольного элемента\n\t\t\tif (this.type === 'selector' && !this.elPopup.matches('.template')) {\n\t\t\t\tthis.elPopup.classList.remove('hidden');\n\n\t\t\t\tif (!this.elPopup.querySelector(':scope > .top-popup_content')) {\n\t\t\t\t\tthis.elPopup.classList.add('top-popup_content');\n\t\t\t\t}\n\n\t\t\t\tthis.elPopup = DOM.wrap(this.elPopup, 'div');\n\t\t\t}\n\n\t\t\tif (this.type === 'html') {\n\t\t\t\tif (!this.elPopup.querySelector(':scope > .top-popup_content')) {\n\t\t\t\t\tthis.elPopup.classList.add('top-popup_content');\n\n\t\t\t\t\tthis.elPopup = DOM.wrap(this.elPopup, 'div');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// вложенный Popup\n\t\t\tif (this.type === 'selector' && !this.elPopup.matches('.template') || this.type === 'html' || this.type === 'vue') {\n\t\t\t\tDOM.querySelectorAllArray(this.elPopup, '[data-top-popup]').forEach(el => {\n\t\t\t\t\tif (el instanceof HTMLElement) el.dataset.topPopupPosBy = 'fixed';\n\t\t\t\t});\n\t\t\t\tDOM.querySelectorAllArray(this.elPopup, '.top-popup-wrapper').forEach(el => el.remove());\n\t\t\t}\n\t\t}\n\n\t\tWorker.decoratorBeforeOpen(this);\n\n\t\tif (vueConnector) {\n\t\t\tthis.options.class = vueConnector.classRef.value;\n\t\t\tif (vueConnector.transitionDurationRef.value !== undefined) {\n\t\t\t\tthis.options.transitionDuration = vueConnector.transitionDurationRef.value;\n\n\t\t\t\tif (this.elPopup instanceof HTMLElement) {\n\t\t\t\t\tthis.elPopup.style.setProperty(\n\t\t\t\t\t\t'--top-popup-transition-delay',\n\t\t\t\t\t\tthis.options.transitionDuration + 'ms',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.elPopupInner = document.createElement('div');\n\t\tthis.elPopupInner.classList.add('top-popupPanel', 'top-popup');\n\n\t\twhile (this.elPopup.firstChild) {\n\t\t\tthis.elPopupInner.appendChild(this.elPopup.firstChild);\n\t\t}\n\n\t\tthis.elPopup.append(this.elPopupInner);\n\n\t\tthis.elPopup.classList.add('top-popup-wrapper');\n\n\t\tif (this.options.class) {\n\t\t\tconst classes = this.options.class.split(' ');\n\n\t\t\tthis.elPopup.classList.add(...classes);\n\t\t}\n\n\t\tif (this.options.notch) {\n\t\t\tthis.elPopup.classList.add('with_notch');\n\n\t\t\tthis.elPopup.insertAdjacentHTML('beforeend', '<i class=\"notch notch-border\"></i><i class=\"notch\"></i>');\n\t\t}\n\n\t\tawait this.vueOpen();\n\n\t\tthis.elPopupHeader = this.elPopupInner.querySelector<HTMLElement>('.top-popup_header');\n\t\tthis.elPopupWidget = this.elPopupInner.querySelector<HTMLElement>('.top-popup_widget');\n\t\tthis.elPopupBody = this.elPopupInner.querySelector<HTMLElement>('.top-popup_content');\n\t\tthis.elPopupFooter = this.elPopupInner.querySelector<HTMLElement>('.top-popup_footer');\n\n\t\tconst existsWidgetSearch = !!this.elPopup.querySelector('[data-widget=\"search\"]');\n\n\t\tif (this.options.isFullScreen && !existsWidgetSearch) {\n\t\t\tconst i18n = useI18n();\n\n\t\t\tif (!this.elPopupHeader && i18n.Common.Close) {\n\t\t\t\tthis.elPopupHeader = DOM.genEl('i', { class: 'top-popup_header' });\n\t\t\t\tthis.elPopupInner.prepend(this.elPopupHeader);\n\n\t\t\t\tthis.elPopupHeader.prepend(DOM.genEl('i', { class: 'a closer' }, i18n.Common.Close));\n\t\t\t\tthis.elPopupHeader.append(DOM.genEl('i', { class: 'top-popup_headerButton' }));\n\t\t\t}\n\t\t}\n\n\t\tDOM.storage(this.elPopup, TopLibPopup.componentName, this);\n\n\t\tif (this.options.frontSelector) {\n\t\t\tthis.elFront = document.querySelector<HTMLElement>(this.options.frontSelector);\n\t\t}\n\t\tif (!this.elFront) {\n\t\t\tthis.elFront = this.el.closest<HTMLElement>('.top-popup-front');\n\t\t}\n\t\tif (!this.elFront) {\n\t\t\tthis.elFront = document.body;\n\t\t}\n\n\t\tif (this.elPopup instanceof HTMLElement) {\n\t\t\tthis.elPopup.style.width = this.el.offsetWidth + 'px';\n\t\t\tthis.elPopup.style.height = this.el.offsetHeight + 'px';\n\t\t\tthis.elPopup.style.top = this.el.offsetTop + 'px';\n\t\t\tthis.elPopup.style.right = parseInt(this.el.style.right || '0') + 'px';\n\t\t\tthis.elPopup.style.bottom = parseInt(this.el.style.bottom || '0') + 'px';\n\t\t}\n\n\t\tthis.el.parentElement?.insertBefore(this.elPopup, this.el);\n\t\tthis.elPopup.classList.remove('template');\n\n\t\tif (this.options.invertX) {\n\t\t\tthis.elPopup.classList.add('invert-x');\n\t\t}\n\n\t\tlet fromTop = !!this.el.closest('.modal-header');\n\t\tif (!fromTop) {\n\t\t\tfromTop = !!this.el.closest('#top_panel');\n\t\t}\n\t\tif (!fromTop) {\n\t\t\tfromTop = !!this.el.closest('#secondmenu');\n\t\t}\n\t\tif (fromTop) {\n\t\t\tthis.elPopup.classList.add('p-from-top');\n\t\t}\n\n\t\t// появление с анимацией\n\t\tsetTimeout(() => this.elPopup?.classList.add('top-popup-wrapper-shown'));\n\n\t\tif (this.elFront && !this.elFront.matches('body')) {\n\t\t\tthis.elFront.append(this.elPopup);\n\n\t\t\tthis.shift.top = DOM.offset(this.el).top - this.el.offsetTop - DOM.offset(this.elFront).top;\n\t\t\tthis.shift.left = DOM.offset(this.el).left - this.el.offsetLeft - DOM.offset(this.elFront).left;\n\n\t\t\t// position() не учитывает margin, замечено для flex\n\t\t\tthis.shift.top -= parseInt(this.el.style['margin-top'] || 0);\n\t\t\tthis.shift.left -= parseInt(this.el.style['margin-left'] || 0);\n\n\t\t\tif (this.elPopup instanceof HTMLElement) {\n\t\t\t\tthis.elPopup.style.top = parseInt(this.elPopup.style.top || '0') + this.shift.top + 'px';\n\t\t\t\tthis.elPopup.style.left = parseInt(this.elPopup.style.left || '0') + this.shift.left + 'px';\n\t\t\t}\n\t\t}\n\n\t\tif (this.$ && Core.$) {\n\t\t\tthis.$.trigger('aftershow.top-menu-popup', [Core.$(this.elPopup)]);\n\t\t}\n\n\t\tthis.recalcPosition();\n\n\t\tthis.elPopup.setAttribute('tabindex', '0');\n\t\tthis.focus();\n\n\t\tWorker.decoratorAfterOpen(this);\n\n\t\tthis.mountEvents();\n\t}\n\n\tasync mountJQuery() {\n\t\tif (!Core.$) return;\n\n\t\tthis.$ = Core.$(this.el);\n\t}\n\n\t/**\n\t * Выполнить фокусировку на нужный элемент после открытия окна\n\t */\n\tfocus(): void {\n\t\tlet el: Element | null;\n\n\t\tif (this.elPopup) {\n\t\t\tel = DOM.querySelectorVisible(this.elPopup, '.top-popup-autofocus');\n\n\t\t\t// поле ввода\n\t\t\tif (!el) {\n\t\t\t\tel = DOM.querySelectorVisible(this.elPopup, ':read-write, select:not(:disabled)');\n\t\t\t}\n\n\t\t\t// кнопка\n\t\t\tif (!el) {\n\t\t\t\tel = DOM.querySelectorVisible(this.elPopup, '.top-popup_footer .top-button');\n\t\t\t}\n\n\t\t\tif (!el) {\n\t\t\t\tel = this.elPopup;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * @see this.openerIsInput\n\t\t\t */\n\t\t\tif (!this.openerIsInput) {\n\t\t\t\t// выполнить фокусировку сразу, для применения необходимых стилей\n\t\t\t\tif (el instanceof HTMLElement) el.focus();\n\n\t\t\t\t// выполнить фокусировку после завершения анимации открытия popup\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (el instanceof HTMLElement) el.focus();\n\t\t\t\t}, this.options.transitionDuration);\n\t\t\t}\n\t\t}\n\t}\n\n\tmountEvents(): void {\n\t\t// закрытие при клике вне контекстного меню\n\t\tthis.addEventListenerWithUnmount(document, 'mousedown', (e) => this.onMousedown(e as MouseEvent));\n\n\t\tif (this.openerIsInput) {\n\t\t\t/**\n\t\t\t * Фокусировка к моменту открытия popup уже установлена на поле ввода\n\t\t\t *\n\t\t\t * @see this.openerIsInput\n\t\t\t */\n\t\t\tthis.onFocusCloseOthers();\n\t\t} else {\n\t\t\tif (this.elPopup && this.elPopupInner) {\n\t\t\t\t// закрыть другие меню\n\t\t\t\tthis.addEventListenerWithUnmount(this.elPopup, 'focus', (e) => this.onFocus(e as FocusEvent));\n\n\t\t\t\t// автоматическое закрытие при отведении мыши\n\t\t\t\tif (this.options.openByHover) {\n\t\t\t\t\tthis.addEventListenerWithUnmount(this.elPopup, 'mouseleave', (e) => this.onMouseleave(e as MouseEvent));\n\t\t\t\t\tthis.addEventListenerWithUnmount(this.elPopupInner, 'mouseleave', (e) => this.onMouseleave(e as MouseEvent));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// не скроллить страницу\n\t\tif (this.options.isFullScreen && this.elPopupBody) {\n\t\t\tthis.addEventListenerWithUnmount(this.elPopupBody, 'touchmove', (e) => this.onTouchmove(e as TouchEvent));\n\t\t}\n\t}\n\n\t/**\n\t * Обработка клика вне окна\n\t */\n\tprivate onMousedown(e: MouseEvent): void {\n\t\t// // не оригинальное событие\n\t\t// if (!e || !e.originalEvent || !e.originalEvent.isTrusted) {\n\t\t// \treturn;\n\t\t// }\n\n\t\t// Popup уже закрыт\n\t\tif (!this.elPopup || !(e.target instanceof Element)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// клик на внешнем элементе\n\t\tif (!this.isFirstClick) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isFirstClick = false;\n\t\tsetTimeout(() => this.isFirstClick = true);\n\n\t\t// клик не основной кнопкой мыши\n\t\tif (e instanceof MouseEvent && e.button !== 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// открыто другое меню с posBy = fixed, сначала должно быть закрыто оно\n\t\tlet elPopupOpened = DOM.querySelectorVisibleLast(document.body, ':scope > .top-popup-wrapper');\n\t\tif (elPopupOpened && elPopupOpened !== this.elPopup) {\n\t\t\treturn;\n\t\t}\n\n\t\t// открыто другое меню в top-popup-front, сначала должно быть закрыто оно\n\t\tif (e.target.closest('.top-popup-front')) {\n\t\t\telPopupOpened = DOM.querySelectorVisibleLast(e.target.closest('.top-popup-front')!, ':scope > .top-popup-wrapper');\n\n\t\t\tif (elPopupOpened && elPopupOpened !== this.elPopup) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// клик на кнопке открытия этого меню\n\t\tif (e.target.closest(`[data-top-popup-id=\"${this.options.id}\"]`)) {\n\t\t\te.preventDefault();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// элемент формы, к которому идет переход\n\t\tlet toFormEl: HTMLElement | null = e.target.closest('input, select, textarea, button, [tabindex]');\n\t\tif (toFormEl === this.elPopup) toFormEl = null;\n\n\t\t// сохранить фокус после закрытия popup, если это не переход к другому элементу\n\t\tconst restoreFocus = !toFormEl;\n\n\t\t/**\n\t\t * Не сбравсывать уже установленный фокус\n\t\t */\n\t\tif (restoreFocus && this.openerIsInput) {\n\t\t\te.preventDefault();\n\t\t}\n\n\t\t// клик внутри этого меню\n\t\tif (this.elPopup.contains(e.target)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// клик вне родительского диалогового окна\n\t\tif (this.elPopup.closest('.ui-dialog') && !e.target.closest('.ui-dialog')) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (Worker.decoratorIsIgnoreOuterClick(e)) {\n\t\t\treturn;\n\t\t}\n\n\t\tWorker.close(this.elPopup, restoreFocus);\n\t}\n\n\t/**\n\t * Произошла фокусировка на этот popup\n\t */\n\tprivate onFocus(e: FocusEvent): void {\n\t\t// // не оригинальное событие\n\t\t// if (!e || !e.originalEvent || !e.originalEvent.isTrusted) {\n\t\t// \treturn;\n\t\t// }\n\n\t\tif (e.target instanceof Element && e.target.matches('input')) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.onFocusCloseOthers();\n\t}\n\n\t/**\n\t * Закрыть другие Popup при фокусе на элемент формы в текущем\n\t */\n\tprivate onFocusCloseOthers(): void {\n\t\t// это окно уже закрывается\n\t\tif (this.isClosed) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst elsPopups = Worker.getAllVisible();\n\t\telsPopups.forEach(elPopup => {\n\t\t\t// фокус внутри этого окна\n\t\t\tif (this.elPopup?.contains(elPopup)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// это Popup из которого был открыт Popup с фокусом\n\t\t\t// глубина вложенности: до 3 подменю\n\t\t\tif (\n\t\t\t\tthis.popupParent?.elPopup === elPopup ||\n\t\t\t\tthis.popupParent?.popupParent?.elPopup === elPopup\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tWorker.close(elPopup);\n\t\t});\n\t}\n\n\t/**\n\t * Закрыть Popup при отведении мыши\n\t */\n\tprivate onMouseleave(_e: MouseEvent): void {\n\t\tsetTimeout(() => {\n\t\t\tif (this.elPopupInner && this.elPopupInner.matches(':hover') || !this.elPopup) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tWorker.close(this.elPopup);\n\t\t}, 100);\n\t}\n\n\t/**\n\t * Контроль положения Popup при fixed позиционировании\n\t */\n\tprivate onResize(): void {\n\t\t// на android при вызове метода append сбрасывается фокус с input внутри this.elPopup\n\t\tif (this.elPopup && this.elPopup.parentElement !== document.body) {\n\t\t\tdocument.body.append(this.elPopup);\n\t\t}\n\n\t\tif (this.elPopup instanceof HTMLElement) {\n\t\t\tthis.elPopup.style.top = DOM.offset(this.el).top + 'px';\n\t\t\tthis.elPopup.style.left = DOM.offset(this.el).left + 'px';\n\t\t}\n\t}\n\n\tunmount(): void {\n\t\tsuper.unmount();\n\n\t\tif (this.el instanceof HTMLElement) this.el.dataset.topPopupOpened = '';\n\t\tif (!this.elActiveByDefault) {\n\t\t\tthis.el.classList.remove('top-active');\n\t\t}\n\n\t\tlet style = this.el.getAttribute('style');\n\t\tif (style) {\n\t\t\tstyle = style.replace(/position:[^;]*;?/g, '');\n\t\t\tthis.el.setAttribute('style', style);\n\t\t}\n\t}\n\n\t// контроль за положением Popup, чтобы оно не вылезало за пределы документа\n\trecalcPosition(pForce?: typeof this.options.p): void {\n\t\tif (!(this.elPopup instanceof HTMLElement)) return;\n\n\t\tlet p = pForce ?? this.options.p;\n\t\tlet leftPos: number;\n\n\t\tif (this.el instanceof HTMLElement) {\n\t\t\tthis.elPopup.style.height = this.el.offsetHeight + 'px';\n\n\t\t\tthis.elPopup.classList.remove('p0', 'p1', 'p2', 'p3', 'p4');\n\t\t\tthis.elPopup.classList.add('p' + p);\n\n\t\t\tswitch (this.options.posBy) {\n\t\t\t\tcase 'left':\n\t\t\t\t\tleftPos = this.el.offsetLeft + parseInt(this.el.style['margin-left'] || '0');\n\t\t\t\t\tleftPos += this.shift.left;\n\t\t\t\t\tthis.elPopup.style.left = leftPos + 'px';\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'right':\n\t\t\t\t\tif (!(this.el.offsetParent instanceof HTMLElement)) break;\n\n\t\t\t\t\tleftPos = this.el.offsetLeft + parseInt(this.el.style['margin-left'] || '0');\n\t\t\t\t\tthis.elPopup.style.right = this.el.offsetParent.offsetWidth - this.el.offsetWidth - leftPos + 'px';\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fixed':\n\t\t\t\t\tthis.addEventListenerWithUnmount(window, 'resize', () => this.onResize());\n\n\t\t\t\t\tthis.onResize();\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.options.posBy?.append(this.elPopup);\n\t\t\t}\n\t\t}\n\n\t\t// контроль за пложением Popup, чтобы оно не вылезало за пределы документа\n\t\tconst boundingClientRect = this.elPopup.getBoundingClientRect();\n\t\tthis.elPopup.style.setProperty('--top-popup-height', this.elPopup.offsetHeight + 'px');\n\t\tthis.elPopup.style.setProperty('--top-popup-right-bounding', boundingClientRect.right + 'px');\n\t\tthis.elPopup.style.setProperty('--top-popup-bottom-bounding', boundingClientRect.bottom + 'px');\n\t\tthis.elPopup.style.setProperty('--top-popup-top', boundingClientRect.top + 'px');\n\t\tthis.elPopup.style.setProperty('--top-popup-left', boundingClientRect.left + 'px');\n\n\t\tif (this.elPopupInner instanceof HTMLElement) {\n\t\t\tthis.elPopupInner.style.maxWidth = 'unset';\n\t\t\tthis.elPopupInner.style.maxHeight = 'unset';\n\t\t}\n\n\t\t// выходит ли popup за экран с конкретного края\n\t\tconst out = {\n\t\t\ttop: false,\n\t\t\tright: false,\n\t\t\tbottom: false,\n\t\t\tleft: false,\n\t\t};\n\n\t\t// выходит ли popup за экран с конкретного края, если применено инвертирование\n\t\tconst outWithInvert = {\n\t\t\ttop: false,\n\t\t\tright: false,\n\t\t\tbottom: false,\n\t\t\tleft: false,\n\t\t};\n\n\t\t// имеет ли смысл прикреплять окно к другой стороне кнопки\n\t\tlet canUseInvertX = boundingClientRect.left > window.innerWidth / 2;\n\t\tlet canUseInvertY = boundingClientRect.top > window.innerHeight / 2;\n\n\t\tif (p === 4) {\n\t\t\tcanUseInvertX = !canUseInvertX;\n\t\t}\n\n\t\tif (p === 1) {\n\t\t\tcanUseInvertY = !canUseInvertY;\n\t\t}\n\n\t\tconst contentBoundingClientRect = this.elPopupInner?.getBoundingClientRect();\n\n\t\tlet contentRight: number;\n\t\tlet contentBottom: number;\n\n\t\tconst margin = DOM.cssNumber(this.elPopup, '--top-popup-offset');\n\t\tconst elHeight = this.el.offsetHeight;\n\t\tconst elWidth = this.el.offsetWidth;\n\n\t\tif (contentBoundingClientRect) {\n\t\t\tcontentRight = window.innerWidth - contentBoundingClientRect.right;\n\t\t\tcontentBottom = window.innerHeight - contentBoundingClientRect.bottom;\n\n\t\t\tif (contentBoundingClientRect.top < margin) {\n\t\t\t\tout.top = true;\n\n\t\t\t\tif (contentBoundingClientRect.top < margin * 2 - contentBoundingClientRect.height + elHeight) {\n\t\t\t\t\toutWithInvert.top = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (contentRight < margin) {\n\t\t\t\tout.right = true;\n\n\t\t\t\tif (contentRight < margin * 2 - contentBoundingClientRect.width + elWidth) {\n\t\t\t\t\toutWithInvert.right = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (contentBottom < margin) {\n\t\t\t\tout.bottom = true;\n\n\t\t\t\tif (contentBottom < margin * 2 - contentBoundingClientRect.height + elHeight) {\n\t\t\t\t\toutWithInvert.bottom = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (contentBoundingClientRect.left < margin) {\n\t\t\t\tout.left = true;\n\n\t\t\t\tif (contentBoundingClientRect.left < margin * 2 - contentBoundingClientRect.width + elHeight) {\n\t\t\t\t\toutWithInvert.left = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Определить новое положение p, если popup не помещается\n\t\t *\n\t\t * Следует выполнять в два этапа:\n\t\t * - по горизонтали\n\t\t * - по вертикали\n\t\t */\n\t\tconst genP = (axis: 'x' | 'y', p: number) => {\n\t\t\t// проверяем горизонталь\n\t\t\tif (axis === 'x') {\n\t\t\t\tif (!out.right && !out.left) return p;\n\n\t\t\t\tif (p === 1 || p === 3) {\n\t\t\t\t\tif (!outWithInvert.right && !outWithInvert.left && canUseInvertX) return p;\n\t\t\t\t}\n\n\t\t\t\tif (out.right && (p === 0 || p === 2) && canUseInvertX) {\n\t\t\t\t\tp = 4;\n\t\t\t\t}\n\n\t\t\t\tif (out.left && (p === 0 || p === 4) && canUseInvertX) {\n\t\t\t\t\tp = 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// проверяем вертикаль\n\t\t\tif (axis === 'y') {\n\t\t\t\t// не помещается и можно использовать инвертирование\n\t\t\t\tif (!out.top && !out.bottom) return p;\n\n\t\t\t\tif (p === 2 || p === 4) {\n\t\t\t\t\tif (!outWithInvert.top && !outWithInvert.bottom && canUseInvertY) return p;\n\t\t\t\t}\n\n\t\t\t\tif (out.top && (p === 0 || p === 1) && canUseInvertY) {\n\t\t\t\t\tp = 3;\n\t\t\t\t}\n\n\t\t\t\tif (out.bottom && canUseInvertY) {\n\t\t\t\t\tp = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn p;\n\t\t};\n\n\t\t/**\n\t\t * Приоритет определения `p` по осям зависит от начального значения `p`\n\t\t *\n\t\t * Пытаемся сохранить выбранную ось: X или Y\n\t\t */\n\t\tlet axis: Array<'x' | 'y'> = ['x', 'y'];\n\t\tif (p === 0 || p === 1 || p === 3) axis = ['y', 'x'];\n\n\t\tlet newP = p ?? 0;\n\t\taxis.forEach((axisI) => {\n\t\t\tnewP = genP(axisI, newP);\n\t\t});\n\t\tp = newP;\n\n\t\tif (out.bottom && (p === 2 || p === 4) && canUseInvertY) {\n\t\t\t// меню справа может перемещаться вверх, только если есть место слева\n\t\t\tthis.elPopup.classList.add('invert-y');\n\t\t}\n\n\t\tif (out.right && (p === 0 || p === 1 || p === 3)) {\n\t\t\tthis.elPopup.classList.add('invert-x');\n\t\t}\n\n\t\tthis.elPopup.classList.remove('p0', 'p1', 'p2', 'p3', 'p4');\n\t\tthis.elPopup.classList.add('p' + p);\n\n\t\tif (this.elPopupInner instanceof HTMLElement) {\n\t\t\tthis.elPopupInner.style.maxWidth = '';\n\t\t\tthis.elPopupInner.style.maxHeight = '';\n\t\t}\n\n\t\t// if (this.elPopupBody instanceof HTMLElement) {\n\t\t// \t// отобразить popup по вертикали с другой стороны, если с другой стороны больше места\n\t\t// \tconst hasScroll = this.elPopupBody.offsetHeight < this.elPopupBody.scrollHeight;\n\t\t// \tvd(this.elPopupBody.scrollHeight);\n\t\t// \tvd(this.elPopupBody.offsetHeight);\n\t\t// \tif (hasScroll && pForce === undefined) {\n\t\t// \t\tconst contentBoundingClientRect = this.elPopupBody?.getBoundingClientRect();\n\t\t// \t\tif (\n\t\t// \t\t\tp === 1 && contentBoundingClientRect.top * 2 < contentBoundingClientRect.bottom ||\n\t\t// \t\t\tp === 3 && contentBoundingClientRect.bottom * 2 < contentBoundingClientRect.top\n\t\t// \t\t) {\n\t\t// \t\t\tthis.recalcPosition(p === 1 ? 3 : 1);\n\t\t//\n\t\t// \t\t\treturn;\n\t\t// \t\t}\n\t\t// \t}\n\t\t// }\n\n\t\tWorker.scrollToActive(this.elPopup);\n\t};\n\n\tonTouchmove(e: TouchEvent): void {\n\t\tif (e.currentTarget instanceof HTMLElement && e.target instanceof HTMLElement) {\n\t\t\t// разрешить горизональный скролл\n\t\t\tlet hasScrollX = e.currentTarget.scrollWidth > e.currentTarget.offsetWidth;\n\t\t\tif (hasScrollX) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (e.target.parentElement?.scrollWidth && e.target.parentElement?.offsetWidth) {\n\t\t\t\t// разрешить горизональный скролл\n\t\t\t\tlet hasScrollX2 = e.target.parentElement.scrollWidth > e.target.parentElement?.offsetWidth;\n\t\t\t\tif (hasScrollX2) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!e.currentTarget.matches('.has_scroll')) {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tif (this.isClosed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isClosed = true;\n\n\t\tif (this.$ && Core.$ && this.elPopup) {\n\t\t\tthis.$.trigger('afterclose.top-menu-popup', [Core.$(this.elPopup)]);\n\t\t}\n\n\t\tif (Worker.noClose) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.unmount();\n\n\t\tthis.elPopup?.classList.add('top-popup-wrapper-closed');\n\n\t\tsetTimeout(() => {\n\t\t\tthis.vueClose();\n\n\t\t\tif (!this.elPopup) return;\n\n\t\t\tif (this.options.useOriginal) {\n\t\t\t\tthis.elPopup.removeAttribute('style');\n\t\t\t\tthis.elPopup.classList.remove('top-popup-wrapper-shown', 'top-popup-wrapper-closed');\n\t\t\t\tthis.elPopup.classList.add('template');\n\t\t\t\tthis.elStartPosition?.append(this.elPopup);\n\n\t\t\t\tthis.elPopup.querySelector('div.top-popup_content.top-column')?.classList.remove('top-column');\n\t\t\t\tthis.elPopup.querySelector('.notch-border')?.remove();\n\t\t\t\tthis.elPopup.querySelector('.notch')?.remove();\n\n\t\t\t\tthis.elPopupInner?.replaceWith(...this.elPopupInner.childNodes);\n\n\t\t\t\tDOM.storageClear(this.elPopup);\n\t\t\t} else {\n\t\t\t\tDOM.storageClear(this.elPopup);\n\n\t\t\t\tthis.elPopup.remove();\n\t\t\t\tdelete this.elPopup;\n\t\t\t}\n\n\t\t\tconst elsPopups = Worker.getAllVisible();\n\t\t\tconst elPopupLast = elsPopups.length && elsPopups[elsPopups.length - 1];\n\n\t\t\tif (elPopupLast) {\n\t\t\t\tWorker.getPopup(elPopupLast).focus();\n\t\t\t} else {\n\t\t\t\tdocument.documentElement.classList.remove('with_popup');\n\t\t\t}\n\t\t}, this.options.transitionDuration);\n\t}\n\n\tasync vueOpen(): Promise<void> {\n\t\tawait this.vueGetComponent()?.onOpen(this);\n\t}\n\n\tvueClose(): void {\n\t\tthis.vueGetComponent()?.onClose(this);\n\t}\n\n\t// получить vueConnectors компонента Popup\n\tvueGetComponent() {\n\t\tif (this.el instanceof HTMLElement && this.options.id) return Worker.vueConnectors.get(this.options.id);\n\t}\n}\n\nGlobalEvents.init();\n"],"names":["Component","componentName","el","options","component","utils_dom","eventData","type","listener","nodes","node","GlobalEvents","e","elUl","elItem","elPopup2","popup_worker","elCloser","elPopup","elBtn","elFooterLastBtn","elMore","countLi","elsLiVisible","index","elItemActive","Core","vueConnector","elInput","classes","existsWidgetSearch","i18n","forms","TopLibPopup","fromTop","elPopupOpened","restoreFocus","toFormEl","leftPos","boundingClientRect","contentRight","contentBottom","margin","elHeight","elWidth","contentBoundingClientRect","out","outWithInvert","genP","axis2","p2","canUseInvertX","canUseInvertY","axis","newP","axisI","elsPopups","elPopupLast"],"mappings":"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"}
|