@emailmaker/filemanager 0.10.79 → 0.10.80

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.
@@ -0,0 +1,2302 @@
1
+ (Object(typeof self !== "undefined" ? self : this)["webpackChunkfileManager"] = Object(typeof self !== "undefined" ? self : this)["webpackChunkfileManager"] || []).push([[379],{
2
+
3
+ /***/ 1560:
4
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5
+
6
+ "use strict";
7
+ // ESM COMPAT FLAG
8
+ __webpack_require__.r(__webpack_exports__);
9
+
10
+ // EXPORTS
11
+ __webpack_require__.d(__webpack_exports__, {
12
+ IconsTab: () => (/* binding */ IconsTab),
13
+ "default": () => (/* binding */ ImageIcons_IconsTab)
14
+ });
15
+
16
+ // EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js
17
+ var jsx_runtime = __webpack_require__(4848);
18
+ // EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react"}
19
+ var external_root_React_commonjs2_react_commonjs_react_amd_react_ = __webpack_require__(5442);
20
+ var external_root_React_commonjs2_react_commonjs_react_amd_react_default = /*#__PURE__*/__webpack_require__.n(external_root_React_commonjs2_react_commonjs_react_amd_react_);
21
+ // EXTERNAL MODULE: external {"root":"antd","commonjs2":"antd","commonjs":"antd","amd":"antd"}
22
+ var external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_ = __webpack_require__(550);
23
+ // EXTERNAL MODULE: ./node_modules/react-i18next/dist/es/index.js + 15 modules
24
+ var es = __webpack_require__(2389);
25
+ // EXTERNAL MODULE: ./node_modules/@untitledui/icons/dist/SearchMd.mjs
26
+ var SearchMd = __webpack_require__(6005);
27
+ // EXTERNAL MODULE: ./src/hooks/index.ts + 6 modules
28
+ var hooks = __webpack_require__(7433);
29
+ // EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js
30
+ var injectStylesIntoStyleTag = __webpack_require__(5072);
31
+ var injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag);
32
+ // EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js
33
+ var styleDomAPI = __webpack_require__(7825);
34
+ var styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI);
35
+ // EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js
36
+ var insertBySelector = __webpack_require__(7659);
37
+ var insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector);
38
+ // EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js
39
+ var setAttributesWithoutAttributes = __webpack_require__(5056);
40
+ var setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes);
41
+ // EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js
42
+ var insertStyleElement = __webpack_require__(540);
43
+ var insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement);
44
+ // EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js
45
+ var styleTagTransform = __webpack_require__(1113);
46
+ var styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform);
47
+ // EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[3].use[1]!./node_modules/sass-loader/dist/cjs.js!./src/components/ImageIcons/iconsTab.module.scss
48
+ var iconsTab_module = __webpack_require__(9875);
49
+ var iconsTab_module_default = /*#__PURE__*/__webpack_require__.n(iconsTab_module);
50
+ ;// ./src/components/ImageIcons/iconsTab.module.scss
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+ var options = {};
63
+
64
+ options.styleTagTransform = (styleTagTransform_default());
65
+ options.setAttributes = (setAttributesWithoutAttributes_default());
66
+ options.insert = insertBySelector_default().bind(null, "head");
67
+ options.domAPI = (styleDomAPI_default());
68
+ options.insertStyleElement = (insertStyleElement_default());
69
+
70
+ var update = injectStylesIntoStyleTag_default()((iconsTab_module_default()), options);
71
+
72
+
73
+
74
+
75
+ /* harmony default export */ const ImageIcons_iconsTab_module = ((iconsTab_module_default()) && (iconsTab_module_default()).locals ? (iconsTab_module_default()).locals : undefined);
76
+
77
+ ;// ./src/components/ImageIcons/IconsSearchForm.tsx
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+ const IconsSearchForm = ({ query, onQueryChange, onSubmit, hasResults = false, inputRef, }) => {
86
+ const { t } = (0,es/* useTranslation */.Bd)();
87
+ const { options } = (0,hooks/* useFileManagerContext */.wh)();
88
+ const { config } = options;
89
+ const showResultsMode = query.length > 0 && hasResults;
90
+ return ((0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsSearchFormCenteredContainer, children: [(0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form, { layout: "inline", onFinish: onSubmit, className: showResultsMode ? ImageIcons_iconsTab_module.iconsSearchResults : ImageIcons_iconsTab_module.iconsSearchFormCentered, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form.Item, { className: ImageIcons_iconsTab_module.iconsSearchFormInput, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Input, { ref: inputRef, className: ImageIcons_iconsTab_module.iconsSearchFormInputInput, allowClear: true, prefix: (0,jsx_runtime.jsx)(SearchMd/* SearchMd */.g, { size: 16, strokeWidth: config === null || config === void 0 ? void 0 : config.iconStrokeWidth, onClick: onSubmit }), placeholder: t('Search icons'), value: query, onChange: e => onQueryChange(e.target.value), onKeyDown: e => e.code === 'Space' && onSubmit(), onPressEnter: onSubmit, spellCheck: "false" }) }) }), showResultsMode && (0,jsx_runtime.jsx)("div", { className: `ant-divider ${ImageIcons_iconsTab_module.iconsSearchDivider}`, role: "separator" })] }));
91
+ };
92
+ /* harmony default export */ const ImageIcons_IconsSearchForm = (IconsSearchForm);
93
+
94
+ ;// ./src/components/ImageIcons/IconsControls.tsx
95
+
96
+
97
+
98
+
99
+
100
+ const IconsControls = props => {
101
+ const { t } = (0,es/* useTranslation */.Bd)();
102
+ const { colorHex, setColorHex, colorHex2, setColorHex2, colorHex3, setColorHex3, sizePx, setSizePx, strokeWidth, setStrokeWidth, showSecondColor, showThirdColor, } = props;
103
+ return ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsControls, children: (0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsControlsControls, children: [(0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsControlsStrokeWidth, children: [(0,jsx_runtime.jsx)("span", { children: t('Size') }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.InputNumber, { min: 20, max: 200, step: 1, value: sizePx, formatter: value => `${value}px`, parser: displayValue => {
104
+ const s = String(displayValue !== null && displayValue !== void 0 ? displayValue : '')
105
+ .trim()
106
+ .replace(/\s*px\s*$/i, '');
107
+ const n = parseInt(s, 10);
108
+ return (Number.isFinite(n) ? n : 0);
109
+ }, onChange: v => setSizePx(typeof v === 'number' && !Number.isNaN(v) ? v : 50) })] }), (0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsControlsStrokeWidth, children: [(0,jsx_runtime.jsx)("span", { children: t('Stroke width') }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.InputNumber, { min: 0.3, max: 3, step: 0.1, value: typeof strokeWidth === 'number' ? strokeWidth : 1, formatter: value => `${value}px`, parser: value => (value ? value.replace('px', '') : ''), onChange: v => setStrokeWidth(typeof v === 'number' ? v : 1) })] }), (0,jsx_runtime.jsxs)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Space, { size: 8, children: [(0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsControlElement, children: [(0,jsx_runtime.jsx)("span", { children: t('Color1') }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.ColorPicker, { value: colorHex, format: "hex", disabledAlpha: true, onChange: (_, hex) => setColorHex(hex), size: "middle" })] }), showSecondColor && ((0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsControlElement, children: [(0,jsx_runtime.jsx)("span", { children: t('Color2') }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.ColorPicker, { value: colorHex2, format: "hex", disabledAlpha: true, onChange: (_, hex) => setColorHex2(hex), size: "middle" })] })), showThirdColor && ((0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsControlElement, children: [(0,jsx_runtime.jsx)("span", { children: t('Color3') }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.ColorPicker, { value: colorHex3, format: "hex", disabledAlpha: true, onChange: (_, hex) => setColorHex3(hex), size: "middle" })] }))] })] }) }));
110
+ };
111
+ /* harmony default export */ const ImageIcons_IconsControls = (IconsControls);
112
+
113
+ // EXTERNAL MODULE: ./node_modules/@ant-design/icons/es/icons/LoadingOutlined.js + 1 modules
114
+ var LoadingOutlined = __webpack_require__(3567);
115
+ // EXTERNAL MODULE: ./src/components/NoFilesMessage/NoFilesMessage.tsx + 1 modules
116
+ var NoFilesMessage = __webpack_require__(1790);
117
+ // EXTERNAL MODULE: ./src/hooks/useCustomIcons.ts + 23 modules
118
+ var useCustomIcons = __webpack_require__(2429);
119
+ // EXTERNAL MODULE: ./src/presentation/media-list/useMediaListEngine.ts + 1 modules
120
+ var useMediaListEngine = __webpack_require__(3263);
121
+ ;// ./src/components/ImageIcons/IconsGrid.tsx
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+ const antIcon = (0,jsx_runtime.jsx)(LoadingOutlined/* default */.A, { style: { fontSize: 20 }, spin: true });
133
+ const PREFETCH_THRESHOLD_PX = 240;
134
+ /** Фиксированная минимальная ширина колонки: не зависит от previewSize, иначе при каждом px меняется число колонок и размер «прыгает». */
135
+ const GRID_MIN_COLUMN_WIDTH_PX = 160;
136
+ /** Превью + подпись + отступы карточки (см. .iconsGridItem padding / .iconsGridItemName). */
137
+ const GRID_ROW_HEIGHT_BEYOND_THUMB_PX = 56;
138
+ const IconsGrid = ({ items, loading, isCollectingResults = false, hasMore = false, hasQuery, selectedHash, onItemClick, onInsert: _onInsert, onLoadMore, colorVars, svgTextMap, previewSize, selectedHashes, onToggleSelect, }) => {
139
+ const { t } = (0,es/* useTranslation */.Bd)();
140
+ const { ThumbsUpIcon } = (0,useCustomIcons/* useCustomIcons */.D)();
141
+ const hasSelected = Boolean(selectedHashes && selectedHashes.size > 0);
142
+ const loadMoreLockRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
143
+ const { positionedItems, containerHeight, isNearEnd, handleViewportChange } = (0,useMediaListEngine/* useMediaListEngine */.W)({
144
+ items,
145
+ getId: item => item.hash,
146
+ getPreviewSrc: () => undefined,
147
+ getAltText: item => item.name,
148
+ layoutMode: 'grid',
149
+ minColumnWidth: GRID_MIN_COLUMN_WIDTH_PX,
150
+ estimatedItemHeight: (previewSize !== null && previewSize !== void 0 ? previewSize : 50) + GRID_ROW_HEIGHT_BEYOND_THUMB_PX,
151
+ gap: 16,
152
+ prefetchThresholdPx: PREFETCH_THRESHOLD_PX,
153
+ });
154
+ const viewportContainerRef = (0,hooks/* useViewportMetricsSync */._O)(handleViewportChange, [
155
+ items.length,
156
+ previewSize !== null && previewSize !== void 0 ? previewSize : 50,
157
+ ]);
158
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
159
+ if (!hasMore) {
160
+ loadMoreLockRef.current = null;
161
+ }
162
+ }, [hasMore, items.length]);
163
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
164
+ if (!loading && !isCollectingResults && hasMore && items.length > 0 && isNearEnd) {
165
+ if (loadMoreLockRef.current === items.length) {
166
+ return;
167
+ }
168
+ loadMoreLockRef.current = items.length;
169
+ onLoadMore === null || onLoadMore === void 0 ? void 0 : onLoadMore();
170
+ }
171
+ }, [hasMore, isCollectingResults, isNearEnd, items.length, loading, onLoadMore]);
172
+ const emptyContent = hasQuery ? ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridEmptyState, children: (0,jsx_runtime.jsx)(NoFilesMessage/* NoFilesMessage */.G, {}) })) : ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridEmptyState, children: (0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.resultsContainer, children: [(0,jsx_runtime.jsx)("span", { className: ImageIcons_iconsTab_module.videoIcon, children: (0,jsx_runtime.jsx)(ThumbsUpIcon, { className: ImageIcons_iconsTab_module.playButton, style: { width: 48, height: 49, marginBottom: 10 } }) }), (0,jsx_runtime.jsx)("h1", { className: ImageIcons_iconsTab_module.title, children: t('Thousands of icons') }), (0,jsx_runtime.jsx)("p", { className: ImageIcons_iconsTab_module.subtitle, children: t("Enter a search query and we'll find the perfect icon for you") })] }) }));
173
+ return ((0,jsx_runtime.jsxs)("div", { id: "iconsScrollableDiv", ref: viewportContainerRef, className: ImageIcons_iconsTab_module.iconsGrid, children: [items.length === 0 && !loading ? (emptyContent) : ((0,jsx_runtime.jsxs)(jsx_runtime.Fragment, { children: [(0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridVirtualCanvas, style: { height: containerHeight }, children: positionedItems.map(({ row, layout }) => {
174
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
175
+ const item = row.item;
176
+ const isSelected = Boolean((selectedHashes && selectedHashes.has(item.hash)) || selectedHash === item.hash);
177
+ const svgHtml = svgTextMap[item.hash];
178
+ return ((0,jsx_runtime.jsxs)("div", { style: {
179
+ position: 'absolute',
180
+ top: layout.top,
181
+ left: layout.left,
182
+ width: layout.width,
183
+ height: layout.height,
184
+ }, className: `${ImageIcons_iconsTab_module.iconsGridItem} ${isSelected ? ImageIcons_iconsTab_module.iconsGridItemSelected : ''} ${hasSelected ? ImageIcons_iconsTab_module.iconsGridShowCheckboxes : ''}`, onClick: () => onItemClick(item), children: [(0,jsx_runtime.jsx)("div", { style: { height: previewSize !== null && previewSize !== void 0 ? previewSize : 50 }, className: ImageIcons_iconsTab_module.iconsGridItemThumbnail, children: svgHtml ? ((0,jsx_runtime.jsx)("div", { style: {
185
+ color: colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex,
186
+ ['--icon-grad-1']: (_a = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex) !== null && _a !== void 0 ? _a : '#000',
187
+ ['--icon-grad-2']: (_b = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex2) !== null && _b !== void 0 ? _b : '#ff007a',
188
+ ['--icon-color-1']: (_c = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex) !== null && _c !== void 0 ? _c : '#000',
189
+ ['--icon-color-2']: (_d = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex2) !== null && _d !== void 0 ? _d : '#ff007a',
190
+ ['--icon-color-3']: (_e = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex3) !== null && _e !== void 0 ? _e : '#00C2FF',
191
+ ['--icon-stroke-1']: (_f = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex) !== null && _f !== void 0 ? _f : '#000',
192
+ ['--icon-stroke-2']: (_g = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex2) !== null && _g !== void 0 ? _g : '#ff007a',
193
+ ['--icon-stroke-3']: (_h = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex3) !== null && _h !== void 0 ? _h : '#00C2FF',
194
+ ['--icon-fill-1']: (_j = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex) !== null && _j !== void 0 ? _j : '#000',
195
+ ['--icon-fill-2']: (_k = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex2) !== null && _k !== void 0 ? _k : '#ff007a',
196
+ ['--icon-fill-3']: (_l = colorVars === null || colorVars === void 0 ? void 0 : colorVars.colorHex3) !== null && _l !== void 0 ? _l : '#00C2FF',
197
+ }, dangerouslySetInnerHTML: { __html: svgHtml }, className: ImageIcons_iconsTab_module.iconsGridItemSvg })) : ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridItemImg, style: { display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Spin, { indicator: antIcon, size: "small" }) })) }), (0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridItemName, title: item.name, children: item.name }), onToggleSelect ? ((0,jsx_runtime.jsx)("div", { onClick: e => {
198
+ e.stopPropagation();
199
+ }, className: ImageIcons_iconsTab_module.iconsGridCheckbox, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Checkbox, { checked: Boolean(selectedHashes && selectedHashes.has(item.hash)), onChange: () => onToggleSelect(item.hash) }) })) : null] }, item.hash));
200
+ }) }), isCollectingResults && ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridLoadingMore, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Spin, { indicator: antIcon }) }))] })), loading && items.length === 0 && ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsGridLoading, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Spin, { indicator: antIcon }) }))] }));
201
+ };
202
+ /* harmony default export */ const ImageIcons_IconsGrid = (IconsGrid);
203
+
204
+ ;// ./src/components/ImageIcons/defaultIconStockTranslate.ts
205
+ function hasCyrillic(s) {
206
+ return /[\u0400-\u04FF]/.test(s);
207
+ }
208
+ function createIconStockTranslateFetch(url) {
209
+ const trimmedUrl = url.trim();
210
+ return async (input, opts) => {
211
+ var _a, _b;
212
+ const text = input.trim();
213
+ if (!hasCyrillic(text)) {
214
+ return text;
215
+ }
216
+ try {
217
+ const res = await fetch(trimmedUrl, {
218
+ method: 'POST',
219
+ headers: { 'Content-Type': 'application/json' },
220
+ body: JSON.stringify({ text: input, locale: opts.locale }),
221
+ credentials: 'same-origin',
222
+ });
223
+ if (!res.ok) {
224
+ return text;
225
+ }
226
+ const data = (await res.json());
227
+ const out = (_b = (_a = data.translatedText) !== null && _a !== void 0 ? _a : data.text) !== null && _b !== void 0 ? _b : text;
228
+ return String(out).trim() || text;
229
+ }
230
+ catch (_c) {
231
+ return text;
232
+ }
233
+ };
234
+ }
235
+ /** `handleTranslate` имеет приоритет; иначе при непустом `iconStockTranslateUrl` — POST с телом `{ text, locale? }`. */
236
+ function resolveIconStockTranslate(config) {
237
+ var _a;
238
+ if (!config)
239
+ return undefined;
240
+ if (config.handleTranslate)
241
+ return config.handleTranslate;
242
+ const url = (_a = config.iconStockTranslateUrl) === null || _a === void 0 ? void 0 : _a.trim();
243
+ if (!url)
244
+ return undefined;
245
+ return createIconStockTranslateFetch(url);
246
+ }
247
+
248
+ // EXTERNAL MODULE: ./node_modules/@iconify-json/lucide/index.mjs + 2 modules
249
+ var lucide = __webpack_require__(4393);
250
+ // EXTERNAL MODULE: ./node_modules/@iconify-json/tabler/index.mjs + 2 modules
251
+ var tabler = __webpack_require__(27);
252
+ // EXTERNAL MODULE: ./node_modules/@iconify/utils/lib/icon-set/get-icon.js + 3 modules
253
+ var get_icon = __webpack_require__(9249);
254
+ ;// ./src/components/ImageIcons/iconSearchRuLexicon.ts
255
+ /** Стоп-слова при многословном AND-поиске. */
256
+ const STOP_WORDS = new Set([
257
+ 'и',
258
+ 'в',
259
+ 'во',
260
+ 'на',
261
+ 'с',
262
+ 'со',
263
+ 'к',
264
+ 'ко',
265
+ 'у',
266
+ 'о',
267
+ 'об',
268
+ 'от',
269
+ 'до',
270
+ 'по',
271
+ 'за',
272
+ 'из',
273
+ 'без',
274
+ 'для',
275
+ 'при',
276
+ 'про',
277
+ 'или',
278
+ 'the',
279
+ 'a',
280
+ 'an',
281
+ 'and',
282
+ 'or',
283
+ 'of',
284
+ 'to',
285
+ 'in',
286
+ 'on',
287
+ 'for',
288
+ ]);
289
+ /**
290
+ * RU → подстроки в slug / словах из имён Lucide и Tabler Icons.
291
+ */
292
+ const RU_ICON_TERMS = {
293
+ дом: ['home', 'house'],
294
+ домой: ['home'],
295
+ сердце: ['heart'],
296
+ любовь: ['heart'],
297
+ звезда: ['star'],
298
+ солнце: ['sun'],
299
+ луна: ['moon'],
300
+ облако: ['cloud'],
301
+ дождь: ['rain', 'cloud'],
302
+ снег: ['snow'],
303
+ огонь: ['fire', 'flame'],
304
+ вода: ['droplet', 'water'],
305
+ молния: ['bolt', 'zap', 'lightning'],
306
+ пользователь: ['user', 'person'],
307
+ человек: ['user', 'person', 'people'],
308
+ люди: ['users', 'people'],
309
+ лицо: ['face', 'smile'],
310
+ улыбка: ['smile'],
311
+ рука: ['hand'],
312
+ глаз: ['eye'],
313
+ ключ: ['key'],
314
+ замок: ['lock'],
315
+ почта: ['mail', 'email', 'inbox'],
316
+ письмо: ['mail', 'envelope', 'email'],
317
+ конверт: ['envelope', 'mail'],
318
+ сообщение: ['message', 'chat'],
319
+ чат: ['message', 'chat'],
320
+ телефон: ['phone'],
321
+ смартфон: ['smartphone', 'device'],
322
+ камера: ['camera'],
323
+ фото: ['image', 'photo'],
324
+ картинка: ['image', 'picture'],
325
+ изображение: ['image', 'photo'],
326
+ видео: ['video'],
327
+ музыка: ['music'],
328
+ звук: ['volume', 'speaker', 'audio'],
329
+ микрофон: ['mic', 'microphone'],
330
+ поиск: ['search'],
331
+ лупа: ['search'],
332
+ настройки: ['settings', 'cog', 'gear'],
333
+ меню: ['menu'],
334
+ закрыть: ['x', 'close'],
335
+ удалить: ['trash', 'delete'],
336
+ корзина: ['trash'],
337
+ редактировать: ['edit', 'pencil'],
338
+ копировать: ['copy'],
339
+ сохранить: ['save'],
340
+ скачать: ['download'],
341
+ загрузить: ['upload'],
342
+ папка: ['folder'],
343
+ файл: ['file', 'document'],
344
+ документ: ['file', 'document'],
345
+ текст: ['text'],
346
+ календарь: ['calendar'],
347
+ время: ['clock'],
348
+ часы: ['clock', 'watch'],
349
+ карта: ['map'],
350
+ глобус: ['globe'],
351
+ мир: ['globe', 'world', 'earth'],
352
+ адрес: ['map-pin', 'location', 'pin'],
353
+ метка: ['map-pin', 'marker', 'pin'],
354
+ стрелка: ['arrow', 'chevron'],
355
+ влево: ['left', 'arrow-left', 'chevron-left'],
356
+ вправо: ['right', 'arrow-right', 'chevron-right'],
357
+ вверх: ['up', 'arrow-up', 'chevron-up'],
358
+ вниз: ['down', 'arrow-down', 'chevron-down'],
359
+ плей: ['play'],
360
+ пауза: ['pause'],
361
+ стоп: ['stop'],
362
+ галочка: ['check'],
363
+ крестик: ['x'],
364
+ плюс: ['plus'],
365
+ минус: ['minus'],
366
+ покупки: ['shopping', 'cart', 'bag'],
367
+ магазин: ['store', 'shop'],
368
+ подарок: ['gift'],
369
+ щит: ['shield'],
370
+ банк: ['bank', 'building'],
371
+ картабанковская: ['credit-card', 'card'],
372
+ уведомление: ['bell'],
373
+ колокол: ['bell'],
374
+ флаг: ['flag'],
375
+ закладка: ['bookmark'],
376
+ ссылка: ['link'],
377
+ код: ['code', 'terminal'],
378
+ терминал: ['terminal'],
379
+ лампочка: ['lightbulb', 'light-bulb'],
380
+ идея: ['lightbulb'],
381
+ батарея: ['battery'],
382
+ питание: ['power', 'plug'],
383
+ сеть: ['wifi', 'network'],
384
+ принтер: ['printer'],
385
+ монитор: ['monitor', 'display'],
386
+ компьютер: ['computer', 'laptop', 'pc'],
387
+ клавиатура: ['keyboard'],
388
+ книга: ['book'],
389
+ график: ['chart', 'graph'],
390
+ таблица: ['table', 'grid'],
391
+ список: ['list'],
392
+ фильтр: ['filter'],
393
+ тег: ['tag'],
394
+ отправить: ['send'],
395
+ поделиться: ['share'],
396
+ нравится: ['thumbs', 'like'],
397
+ скрыть: ['eye-off', 'hidden'],
398
+ предупреждение: ['alert', 'warning'],
399
+ ошибка: ['x-circle', 'alert-circle'],
400
+ успех: ['check-circle'],
401
+ информация: ['info'],
402
+ помощь: ['help'],
403
+ вопрос: ['help', 'question'],
404
+ язык: ['language', 'languages', 'translate'],
405
+ перевод: ['language', 'translate'],
406
+ масштаб: ['zoom', 'maximize'],
407
+ экран: ['monitor', 'screen', 'display'],
408
+ цвет: ['palette', 'swatch'],
409
+ кисть: ['brush', 'paint'],
410
+ карандаш: ['pencil'],
411
+ выравнивание: ['align'],
412
+ центр: ['center'],
413
+ круг: ['circle'],
414
+ квадрат: ['square'],
415
+ вход: ['log-in', 'login'],
416
+ выход: ['log-out', 'logout'],
417
+ профиль: ['user', 'account'],
418
+ команда: ['users', 'group'],
419
+ задача: ['check', 'list', 'todo'],
420
+ цель: ['target'],
421
+ вложение: ['paperclip'],
422
+ архив: ['archive'],
423
+ ножницы: ['scissors'],
424
+ скрепка: ['paperclip'],
425
+ локация: ['map-pin'],
426
+ навигация: ['navigation', 'compass'],
427
+ компас: ['compass'],
428
+ самолет: ['plane', 'airplane'],
429
+ машина: ['car'],
430
+ мяч: ['ball'],
431
+ мячик: ['ball'],
432
+ поезд: ['train'],
433
+ корабль: ['ship'],
434
+ велосипед: ['bike', 'bicycle'],
435
+ кофе: ['coffee'],
436
+ еда: ['utensils', 'cake', 'pizza'],
437
+ собака: ['dog'],
438
+ кошка: ['cat'],
439
+ птица: ['bird'],
440
+ дерево: ['tree'],
441
+ цветок: ['flower'],
442
+ гора: ['mountain'],
443
+ волны: ['waves'],
444
+ зонт: ['umbrella'],
445
+ работа: ['briefcase'],
446
+ школа: ['school', 'academic', 'graduation'],
447
+ больница: ['cross', 'heart', 'medical'],
448
+ ребенок: ['baby'],
449
+ семья: ['home', 'users'],
450
+ группа: ['users', 'group'],
451
+ мужчина: ['man', 'user'],
452
+ женщина: ['woman', 'user'],
453
+ кольцо: ['ring'],
454
+ корона: ['crown'],
455
+ медаль: ['medal', 'award'],
456
+ кубок: ['trophy'],
457
+ рюкзак: ['backpack'],
458
+ чемодан: ['luggage'],
459
+ кошелек: ['wallet'],
460
+ очки: ['glasses'],
461
+ шляпа: ['hat'],
462
+ рубашка: ['shirt'],
463
+ обувь: ['shoe'],
464
+ здание: ['building'],
465
+ окно: ['window'],
466
+ дверь: ['door'],
467
+ лифт: ['arrow-up-down', 'arrows-up-down'],
468
+ парковка: ['parking'],
469
+ топливо: ['fuel'],
470
+ дорога: ['route', 'road'],
471
+ мост: ['bridge'],
472
+ река: ['waves'],
473
+ море: ['waves'],
474
+ ночь: ['moon'],
475
+ день: ['sun'],
476
+ таймер: ['timer'],
477
+ будильник: ['alarm'],
478
+ деньги: ['banknote', 'currency', 'dollar'],
479
+ процент: ['percent'],
480
+ квитанция: ['receipt'],
481
+ счет: ['receipt', 'document'],
482
+ договор: ['document', 'signature'],
483
+ печать: ['stamp'],
484
+ подпись: ['signature', 'pen'],
485
+ суд: ['scale'],
486
+ полиция: ['shield'],
487
+ пожарные: ['fire'],
488
+ скорая: ['life', 'buoy', 'cross'],
489
+ аптека: ['pill'],
490
+ таблетка: ['pill'],
491
+ здоровье: ['heart', 'pulse'],
492
+ рост: ['trending-up', 'arrow-up'],
493
+ падение: ['trending-down', 'arrow-down'],
494
+ робот: ['bot', 'cpu'],
495
+ мозг: ['brain'],
496
+ база: ['database'],
497
+ сервер: ['server'],
498
+ облакоинтернет: ['cloud'],
499
+ заметка: ['note', 'sticky'],
500
+ комментарий: ['chat', 'bubble'],
501
+ якорь: ['anchor'],
502
+ пароль: ['key', 'lock'],
503
+ отпечаток: ['fingerprint'],
504
+ обновить: ['refresh', 'sync'],
505
+ синхронизация: ['refresh', 'sync'],
506
+ наушники: ['headphones'],
507
+ громкость: ['volume'],
508
+ беззвука: ['volume-x', 'mute'],
509
+ повтор: ['repeat'],
510
+ следующий: ['skip-forward', 'forward'],
511
+ предыдущий: ['skip-back', 'backward'],
512
+ камеравыкл: ['camera-off'],
513
+ микрофонвыкл: ['mic-off'],
514
+ телефонзвонок: ['phone-call'],
515
+ входящие: ['inbox'],
516
+ исходящие: ['send', 'outbox'],
517
+ черновик: ['draft', 'file'],
518
+ спам: ['ban', 'shield'],
519
+ рассылка: ['mail', 'send'],
520
+ подписка: ['bell', 'rss'],
521
+ отписка: ['bell-off'],
522
+ палитра: ['palette'],
523
+ градиент: ['gradient'],
524
+ слои: ['layers'],
525
+ кроп: ['crop'],
526
+ поворот: ['rotate'],
527
+ гаечный: ['wrench'],
528
+ молоток: ['hammer'],
529
+ баг: ['bug'],
530
+ штрихкод: ['barcode'],
531
+ куаркод: ['qr-code'],
532
+ звезда2: ['sparkles'],
533
+ магия: ['wand', 'sparkles'],
534
+ снежинка: ['snowflake'],
535
+ радуга: ['rainbow'],
536
+ лист: ['leaf'],
537
+ ракета: ['rocket'],
538
+ спутник: ['satellite'],
539
+ капля: ['droplet'],
540
+ грузовик: ['truck'],
541
+ автобус: ['bus'],
542
+ такси: ['car', 'taxi'],
543
+ торт: ['cake'],
544
+ пицца: ['pizza'],
545
+ яблоко: ['apple'],
546
+ банан: ['banana'],
547
+ рыба: ['fish'],
548
+ вино: ['wine'],
549
+ пиво: ['beer'],
550
+ чашка: ['cup', 'mug'],
551
+ рассылка2: ['mail', 'megaphone'],
552
+ шаблон: ['layout', 'file'],
553
+ воронка: ['filter', 'funnel'],
554
+ аналитика: ['chart', 'pie'],
555
+ отчет: ['document', 'chart'],
556
+ дашборд: ['layout', 'grid'],
557
+ поддержка: ['life-buoy', 'headset'],
558
+ /** Бренды / сервисы (подстроки в `brand-*`, `*-in-*` и т.п.) */
559
+ телеграм: ['telegram', 'send'],
560
+ вотсап: ['whatsapp'],
561
+ инстаграм: ['instagram'],
562
+ ютуб: ['youtube'],
563
+ твиттер: ['twitter'],
564
+ фейсбук: ['facebook'],
565
+ гитхаб: ['github', 'git'],
566
+ гугл: ['google', 'chrome'],
567
+ яндекс: ['search'],
568
+ эпл: ['apple'],
569
+ вк: ['vk'],
570
+ };
571
+ function iconSearchRuLexicon_hasCyrillic(s) {
572
+ return /[\u0400-\u04FF]/.test(s);
573
+ }
574
+ function isWordChar(code) {
575
+ return ((code >= 48 && code <= 57) ||
576
+ (code >= 65 && code <= 90) ||
577
+ (code >= 97 && code <= 122) ||
578
+ (code >= 1040 && code <= 1103) ||
579
+ code === 1025 ||
580
+ code === 1105);
581
+ }
582
+ function trimTokenEdges(t) {
583
+ let start = 0;
584
+ let end = t.length;
585
+ while (start < end && !isWordChar(t.charCodeAt(start)))
586
+ start += 1;
587
+ while (end > start && !isWordChar(t.charCodeAt(end - 1)))
588
+ end -= 1;
589
+ return t.slice(start, end);
590
+ }
591
+ function tokenize(q) {
592
+ return q
593
+ .toLowerCase()
594
+ .trim()
595
+ .split(/[\s,.;/\\|]+/)
596
+ .map(trimTokenEdges)
597
+ .filter(t => t.length >= 2 && !STOP_WORDS.has(t));
598
+ }
599
+ /** Группы для AND: в каждой — OR по англ. подстрокам. */
600
+ function buildRuExpandedGroups(query) {
601
+ const tokens = tokenize(query);
602
+ if (tokens.length === 0)
603
+ return [];
604
+ const groups = [];
605
+ for (const token of tokens) {
606
+ if (iconSearchRuLexicon_hasCyrillic(token)) {
607
+ const en = RU_ICON_TERMS[token];
608
+ if (en === null || en === void 0 ? void 0 : en.length) {
609
+ groups.push([...en]);
610
+ }
611
+ else {
612
+ groups.push([token]);
613
+ }
614
+ }
615
+ else {
616
+ groups.push([token]);
617
+ }
618
+ }
619
+ return groups;
620
+ }
621
+ function buildSearchNeedles(query) {
622
+ const direct = query.trim().toLowerCase();
623
+ const groups = buildRuExpandedGroups(query);
624
+ return { direct, groups };
625
+ }
626
+ function haystackMatchesRuAware(haystack, direct, groups) {
627
+ if (direct.length >= 2 && haystack.includes(direct)) {
628
+ return true;
629
+ }
630
+ if (groups.length === 0) {
631
+ return false;
632
+ }
633
+ return groups.every(g => g.some(needle => needle.length >= 2 && haystack.includes(needle)));
634
+ }
635
+
636
+ ;// ./src/components/ImageIcons/iconStockSearch.ts
637
+
638
+
639
+
640
+
641
+ const STOCK_SETS = [
642
+ { json: lucide/* icons */.Pt, label: 'Lucide' },
643
+ { json: tabler/* icons */.Pt, label: 'Tabler Icons' },
644
+ ];
645
+ function resolveCanonicalSlug(set, slug) {
646
+ let s = slug;
647
+ const icons = set.icons;
648
+ for (let guard = 0; guard < 24; guard += 1) {
649
+ const raw = icons[s];
650
+ if (raw && typeof raw.parent === 'string') {
651
+ s = raw.parent;
652
+ continue;
653
+ }
654
+ break;
655
+ }
656
+ return s;
657
+ }
658
+ function isHiddenCanonical(set, slug) {
659
+ const raw = set.icons[slug];
660
+ return Boolean(raw && 'body' in raw && raw.hidden);
661
+ }
662
+ function prettyName(slug) {
663
+ return slug
664
+ .split('-')
665
+ .map(p => (p.length ? p.charAt(0).toUpperCase() + p.slice(1) : p))
666
+ .join(' ');
667
+ }
668
+ function buildRowsForSet(json, label) {
669
+ const prefix = json.prefix || label.toLowerCase();
670
+ const rows = [];
671
+ for (const slug of Object.keys(json.icons)) {
672
+ const raw = json.icons[slug];
673
+ if (raw && 'body' in raw && raw.hidden)
674
+ continue;
675
+ const canonical = resolveCanonicalSlug(json, slug);
676
+ if (isHiddenCanonical(json, canonical))
677
+ continue;
678
+ if (!(0,get_icon/* getIconData */.y)(json, slug))
679
+ continue;
680
+ const haystack = `${slug} ${slug.replace(/-/g, ' ')}`.toLowerCase();
681
+ rows.push({ prefix, slug, canonical, haystack, label });
682
+ }
683
+ return rows;
684
+ }
685
+ let searchRows = null;
686
+ function getRows() {
687
+ if (!searchRows) {
688
+ searchRows = STOCK_SETS.flatMap(({ json, label }) => buildRowsForSet(json, label));
689
+ }
690
+ return searchRows;
691
+ }
692
+ function scoreRowMatch(row, direct, groups) {
693
+ const { haystack, slug } = row;
694
+ if (!haystackMatchesRuAware(haystack, direct, groups))
695
+ return 0;
696
+ let score = 10;
697
+ if (direct.length >= 2 && haystack.includes(direct)) {
698
+ if (slug.startsWith(direct))
699
+ score += 100;
700
+ else if (haystack.startsWith(direct))
701
+ score += 50;
702
+ else if (haystack.split(/\s+/).some(p => p.startsWith(direct)))
703
+ score += 30;
704
+ else
705
+ score += 15;
706
+ }
707
+ else if (groups.length > 0) {
708
+ for (const g of groups) {
709
+ const matched = g.filter(n => n.length >= 2 && haystack.includes(n));
710
+ if (matched.length === 0)
711
+ continue;
712
+ const best = Math.max(...matched.map(needle => {
713
+ if (slug.startsWith(needle))
714
+ return 100;
715
+ if (haystack.startsWith(needle))
716
+ return 50;
717
+ if (haystack.split(/\s+/).some(p => p.startsWith(needle)))
718
+ return 30;
719
+ return 15;
720
+ }));
721
+ score += best;
722
+ }
723
+ }
724
+ return score;
725
+ }
726
+ /** Стабильный id вида `prefix:icon-name` для кэша и `StreamlineSearchItem.hash`. */
727
+ function listMatchingStockIconIds(query) {
728
+ const trimmed = query.trim();
729
+ if (trimmed.length < 3)
730
+ return [];
731
+ const { direct, groups } = buildSearchNeedles(trimmed);
732
+ const byId = new Map();
733
+ for (const row of getRows()) {
734
+ const score = scoreRowMatch(row, direct, groups);
735
+ if (score <= 0)
736
+ continue;
737
+ const fullId = `${row.prefix}:${row.canonical}`;
738
+ const prev = byId.get(fullId);
739
+ if (!prev || score > prev.score) {
740
+ byId.set(fullId, { score });
741
+ }
742
+ }
743
+ return Array.from(byId.entries())
744
+ .sort((a, b) => b[1].score - a[1].score || a[0].localeCompare(b[0]))
745
+ .map(([id]) => id);
746
+ }
747
+ /** Сохраняет порядок `primary`, в конец добавляет id из `secondary`, которых ещё не было. */
748
+ function mergeStockIconIdsOrdered(primary, secondary) {
749
+ if (secondary.length === 0)
750
+ return primary;
751
+ const seen = new Set(primary);
752
+ const out = [...primary];
753
+ for (const id of secondary) {
754
+ if (!seen.has(id)) {
755
+ seen.add(id);
756
+ out.push(id);
757
+ }
758
+ }
759
+ return out;
760
+ }
761
+ function stockIconIdToItem(fullId) {
762
+ var _a;
763
+ const colon = fullId.indexOf(':');
764
+ const prefix = colon > 0 ? fullId.slice(0, colon) : '';
765
+ const canonical = colon > 0 ? fullId.slice(colon + 1) : fullId;
766
+ const entry = STOCK_SETS.find(s => (s.json.prefix || s.label.toLowerCase()) === prefix);
767
+ const familyName = (_a = entry === null || entry === void 0 ? void 0 : entry.label) !== null && _a !== void 0 ? _a : prefix;
768
+ return {
769
+ hash: fullId,
770
+ name: prettyName(canonical),
771
+ imagePreviewUrl: '',
772
+ isFree: true,
773
+ familySlug: prefix,
774
+ familyName,
775
+ };
776
+ }
777
+
778
+ // EXTERNAL MODULE: ./node_modules/@iconify/utils/lib/svg/build.js + 3 modules
779
+ var build = __webpack_require__(1452);
780
+ // EXTERNAL MODULE: ./node_modules/@iconify/utils/lib/svg/html.js
781
+ var html = __webpack_require__(6649);
782
+ // EXTERNAL MODULE: ./src/utils/svgToPng.ts
783
+ var svgToPng = __webpack_require__(3817);
784
+ ;// ./src/utils/svgParseUtils.ts
785
+ /**
786
+ * Утилиты для парсинга SVG: определение количества цветов, толщины линий и стиля иконок.
787
+ * Поддерживает атрибуты и inline style, градиенты (linear и radial), различные форматы цветов.
788
+ */
789
+ const SHAPE_TAGS = 'path|rect|circle|ellipse|polygon|line|polyline|g';
790
+ /** Конвертирует цвет в hex для ColorPicker (rgb, rgba, имя → #rrggbb) */
791
+ function colorToHex(raw) {
792
+ var _a;
793
+ const s = raw.trim();
794
+ if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(s)) {
795
+ const m = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})/);
796
+ if (m) {
797
+ const hex = m[1].length === 3 ? m[1].replace(/(.)/g, '$1$1') : m[1];
798
+ return '#' + hex.toLowerCase();
799
+ }
800
+ }
801
+ const rgb = s.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
802
+ if (rgb) {
803
+ return '#' + [1, 2, 3].map(i => parseInt(rgb[i], 10).toString(16).padStart(2, '0')).join('');
804
+ }
805
+ const rgba = s.match(/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*[\d.]+\s*\)/);
806
+ if (rgba) {
807
+ return '#' + [1, 2, 3].map(i => parseInt(rgba[i], 10).toString(16).padStart(2, '0')).join('');
808
+ }
809
+ const named = {
810
+ black: '#000000', white: '#ffffff', red: '#ff0000', green: '#008000', blue: '#0000ff',
811
+ };
812
+ const lower = s.toLowerCase();
813
+ return (_a = named[lower]) !== null && _a !== void 0 ? _a : (normalizeColorForCompare(s) || '#000000');
814
+ }
815
+ /** Нормализует цвет к hex для сравнения (без учёта прозрачности для уникальности) */
816
+ function normalizeColorForCompare(raw) {
817
+ const s = raw.trim();
818
+ if (!s || s === 'none' || s === 'transparent')
819
+ return null;
820
+ if (/^url\(#/.test(s))
821
+ return null; // градиент — не считаем как отдельный цвет
822
+ if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(s)) {
823
+ const m = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})/);
824
+ return m ? '#' + (m[1].length === 3 ? m[1].replace(/(.)/g, '$1$1') : m[1]).toLowerCase() : null;
825
+ }
826
+ if (/^rgb\(/.test(s)) {
827
+ const m = s.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
828
+ if (m)
829
+ return '#' + [1, 2, 3].map(i => parseInt(m[i], 10).toString(16).padStart(2, '0')).join('');
830
+ }
831
+ if (/^rgba\(/.test(s)) {
832
+ const m = s.match(/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*[\d.]+\s*\)/);
833
+ if (m)
834
+ return '#' + [1, 2, 3].map(i => parseInt(m[i], 10).toString(16).padStart(2, '0')).join('');
835
+ }
836
+ const namedColors = {
837
+ black: '#000000', white: '#ffffff', red: '#ff0000', green: '#008000', blue: '#0000ff',
838
+ };
839
+ const lower = s.toLowerCase();
840
+ if (namedColors[lower])
841
+ return namedColors[lower];
842
+ if (lower === 'currentcolor' || lower === 'inherit')
843
+ return null;
844
+ if (/^[a-zA-Z]+$/.test(s))
845
+ return null;
846
+ return null;
847
+ }
848
+ /** Извлекает значение CSS-свойства из строки style */
849
+ function extractFromStyle(styleStr, prop) {
850
+ const re = new RegExp(`${prop}\\s*:\\s*([^;]+)`, 'i');
851
+ const m = styleStr.match(re);
852
+ return m ? m[1].trim() : null;
853
+ }
854
+ /** Собирает все цвета fill/stroke из SVG (атрибуты + style) */
855
+ function extractColorsFromSvg(svg) {
856
+ const colors = [];
857
+ const seen = new Set();
858
+ // 1. Градиенты — stop-color
859
+ const stopColors = Array.from(svg.matchAll(/<stop[^>]*?stop-color\s*=\s*["']([^"']+)["']/gi)).map(m => m[1]);
860
+ stopColors.forEach(c => {
861
+ const norm = normalizeColorForCompare(c);
862
+ if (norm && !seen.has(norm)) {
863
+ seen.add(norm);
864
+ colors.push(c);
865
+ }
866
+ });
867
+ // 2. Элементы с fill/stroke в атрибутах
868
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
869
+ let match;
870
+ while ((match = attrRe.exec(svg)) !== null) {
871
+ const attrs = match[1];
872
+ // fill="..." или fill='...'
873
+ const fillM = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
874
+ if (fillM && fillM[1]) {
875
+ const norm = normalizeColorForCompare(fillM[1]);
876
+ if (norm && !seen.has(norm)) {
877
+ seen.add(norm);
878
+ colors.push(fillM[1]);
879
+ }
880
+ }
881
+ // stroke="..." или stroke='...'
882
+ const strokeM = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
883
+ if (strokeM && strokeM[1]) {
884
+ const norm = normalizeColorForCompare(strokeM[1]);
885
+ if (norm && !seen.has(norm)) {
886
+ seen.add(norm);
887
+ colors.push(strokeM[1]);
888
+ }
889
+ }
890
+ // style="fill: ...; stroke: ..."
891
+ const styleM = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
892
+ if (styleM && styleM[1]) {
893
+ const fill = extractFromStyle(styleM[1], 'fill');
894
+ if (fill) {
895
+ const norm = normalizeColorForCompare(fill);
896
+ if (norm && !seen.has(norm)) {
897
+ seen.add(norm);
898
+ colors.push(fill);
899
+ }
900
+ }
901
+ const stroke = extractFromStyle(styleM[1], 'stroke');
902
+ if (stroke) {
903
+ const norm = normalizeColorForCompare(stroke);
904
+ if (norm && !seen.has(norm)) {
905
+ seen.add(norm);
906
+ colors.push(stroke);
907
+ }
908
+ }
909
+ }
910
+ }
911
+ // 3. Глобальные fill/stroke на svg
912
+ const svgOpen = svg.match(/<svg([^>]*)>/i);
913
+ if (svgOpen && svgOpen[1]) {
914
+ const attrs = svgOpen[1];
915
+ for (const [attrName, reStr] of [
916
+ ['fill', /fill\s*=\s*["']([^"']*)["']/i],
917
+ ['stroke', /stroke\s*=\s*["']([^"']*)["']/i],
918
+ ]) {
919
+ const m = attrs.match(reStr);
920
+ if (m && m[1]) {
921
+ const norm = normalizeColorForCompare(m[1]);
922
+ if (norm && !seen.has(norm)) {
923
+ seen.add(norm);
924
+ colors.push(m[1]);
925
+ }
926
+ }
927
+ }
928
+ const styleM = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
929
+ if (styleM && styleM[1]) {
930
+ for (const prop of ['fill', 'stroke']) {
931
+ const v = extractFromStyle(styleM[1], prop);
932
+ if (v) {
933
+ const norm = normalizeColorForCompare(v);
934
+ if (norm && !seen.has(norm)) {
935
+ seen.add(norm);
936
+ colors.push(v);
937
+ }
938
+ }
939
+ }
940
+ }
941
+ }
942
+ return colors;
943
+ }
944
+ /** Считает элементы с fill (не none, не url) */
945
+ function countFills(svg) {
946
+ let count = 0;
947
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
948
+ let m;
949
+ while ((m = attrRe.exec(svg)) !== null) {
950
+ const attrs = m[1];
951
+ const fillAttr = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
952
+ const fillStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
953
+ const fillFromAttr = fillAttr && fillAttr[1] && !/^none$/i.test(fillAttr[1]) && !/^url\(#/i.test(fillAttr[1]);
954
+ const fillFromStyle = fillStyle && extractFromStyle(fillStyle[1], 'fill') && !/^none$/i.test(extractFromStyle(fillStyle[1], 'fill'));
955
+ if (fillFromAttr || fillFromStyle)
956
+ count += 1;
957
+ }
958
+ return count;
959
+ }
960
+ /** Считает элементы с stroke (не none, не url) */
961
+ function countStrokes(svg) {
962
+ let count = 0;
963
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
964
+ let m;
965
+ while ((m = attrRe.exec(svg)) !== null) {
966
+ const attrs = m[1];
967
+ const strokeAttr = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
968
+ const strokeStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
969
+ const strokeFromAttr = strokeAttr && strokeAttr[1] && !/^none$/i.test(strokeAttr[1]) && !/^url\(#/i.test(strokeAttr[1]);
970
+ const strokeFromStyle = strokeStyle && extractFromStyle(strokeStyle[1], 'stroke') && !/^none$/i.test(extractFromStyle(strokeStyle[1], 'stroke'));
971
+ if (strokeFromAttr || strokeFromStyle)
972
+ count += 1;
973
+ }
974
+ return count;
975
+ }
976
+ /** Проверяет наличие градиентов (linear или radial) */
977
+ function hasGradient(svg) {
978
+ return /<linearGradient/i.test(svg) || /<radialGradient/i.test(svg) || /fill="url\(#|stroke="url\(#/i.test(svg);
979
+ }
980
+ /** Парсит числовое значение stroke-width, отбрасывая px, em и т.д. */
981
+ function parseStrokeWidthValue(raw) {
982
+ const s = raw.trim().replace(/(?:px|em|ex|%)\s*$/i, '');
983
+ const v = parseFloat(s);
984
+ if (Number.isNaN(v) || v <= 0 || v > 10)
985
+ return null;
986
+ return Math.round(v * 10) / 10;
987
+ }
988
+ /** Извлекает stroke-width из SVG — только из видимых shape-элементов, избегает defs */
989
+ function extractStrokeWidth(svg) {
990
+ const values = [];
991
+ const defsEnd = svg.indexOf('</defs>');
992
+ const mainContent = defsEnd >= 0 ? svg.slice(defsEnd) : svg;
993
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})[^>]*stroke-width\\s*=\\s*["']([^"']+)["']`, 'gi');
994
+ let m;
995
+ while ((m = attrRe.exec(mainContent)) !== null) {
996
+ const v = parseStrokeWidthValue(m[1]);
997
+ if (v != null)
998
+ values.push(v);
999
+ }
1000
+ const styleRe = new RegExp(`<(?:${SHAPE_TAGS})[^>]*style\\s*=\\s*["'][^"']*stroke-width\\s*:\\s*([^;"]+)[^"']*["']`, 'gi');
1001
+ while ((m = styleRe.exec(mainContent)) !== null) {
1002
+ const v = parseStrokeWidthValue(m[1]);
1003
+ if (v != null)
1004
+ values.push(v);
1005
+ }
1006
+ if (values.length === 0)
1007
+ return undefined;
1008
+ values.sort((a, b) => a - b);
1009
+ const mid = Math.floor(values.length / 2);
1010
+ return values.length % 2 === 1 ? values[mid] : (values[mid - 1] + values[mid]) / 2;
1011
+ }
1012
+ /** Парсит SVG и возвращает метаданные для определения стиля family */
1013
+ function parseSvgForFamily(svg) {
1014
+ const colors = extractColorsFromSvg(svg);
1015
+ return {
1016
+ colors,
1017
+ fillsCount: countFills(svg),
1018
+ strokesCount: countStrokes(svg),
1019
+ hasGradient: hasGradient(svg),
1020
+ strokeWidth: extractStrokeWidth(svg),
1021
+ };
1022
+ }
1023
+ /** Агрегирует результаты по нескольким SVG */
1024
+ function aggregateSvgParseResults(results) {
1025
+ const allColors = [];
1026
+ const colorSet = new Set();
1027
+ let fillsCount = 0;
1028
+ let strokesCount = 0;
1029
+ let hasGradient = false;
1030
+ let strokeWidth;
1031
+ for (const r of results) {
1032
+ fillsCount += r.fillsCount;
1033
+ strokesCount += r.strokesCount;
1034
+ if (r.hasGradient)
1035
+ hasGradient = true;
1036
+ for (const c of r.colors) {
1037
+ const norm = normalizeColorForCompare(c);
1038
+ if (norm && !colorSet.has(norm)) {
1039
+ colorSet.add(norm);
1040
+ allColors.push(c);
1041
+ }
1042
+ }
1043
+ if (strokeWidth == null && r.strokeWidth != null)
1044
+ strokeWidth = r.strokeWidth;
1045
+ }
1046
+ return {
1047
+ colors: allColors,
1048
+ fillsCount,
1049
+ strokesCount,
1050
+ hasGradient,
1051
+ strokeWidth,
1052
+ };
1053
+ }
1054
+ function addColorToMap(map, rawVal, nextIdxRef) {
1055
+ const norm = normalizeColorForCompare(rawVal);
1056
+ if (norm && !map.has(norm)) {
1057
+ map.set(norm, nextIdxRef.v);
1058
+ nextIdxRef.v = Math.min(nextIdxRef.v + 1, 3);
1059
+ }
1060
+ }
1061
+ /**
1062
+ * Строит карту: нормализованный цвет → индекс переменной (1, 2, 3...).
1063
+ * Порядок — по первому появлению цвета (сначала svg, затем shape-элементы).
1064
+ */
1065
+ function buildFillColorToVarIndexMap(svg) {
1066
+ var _a, _b, _c, _d;
1067
+ const map = new Map();
1068
+ const nextIdxRef = { v: 1 };
1069
+ const svgOpen = svg.match(/<svg([^>]*)>/i);
1070
+ if (svgOpen === null || svgOpen === void 0 ? void 0 : svgOpen[1]) {
1071
+ const m = svgOpen[1].match(/fill\s*=\s*["']([^"']*)["']/i);
1072
+ if ((m === null || m === void 0 ? void 0 : m[1]) && !/^none$/i.test(m[1]) && !/^url\(#/i.test(m[1]))
1073
+ addColorToMap(map, m[1], nextIdxRef);
1074
+ }
1075
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
1076
+ let m;
1077
+ while ((m = attrRe.exec(svg)) !== null) {
1078
+ const attrs = m[1];
1079
+ const fillAttr = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1080
+ const fillStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1081
+ const fillFromStyle = (_a = fillStyle === null || fillStyle === void 0 ? void 0 : fillStyle[1]) === null || _a === void 0 ? void 0 : _a.match(/fill\s*:\s*([^;]+)/i);
1082
+ const fillVal = (_d = ((_b = fillAttr === null || fillAttr === void 0 ? void 0 : fillAttr[1]) !== null && _b !== void 0 ? _b : (_c = fillFromStyle === null || fillFromStyle === void 0 ? void 0 : fillFromStyle[1]) === null || _c === void 0 ? void 0 : _c.trim())) === null || _d === void 0 ? void 0 : _d.trim();
1083
+ if (fillVal && !/^none$/i.test(fillVal) && !/^url\(#/i.test(fillVal)) {
1084
+ addColorToMap(map, fillVal, nextIdxRef);
1085
+ }
1086
+ }
1087
+ return map;
1088
+ }
1089
+ /**
1090
+ * Единая карта цветов: fill и stroke в порядке появления.
1091
+ * Используется для правильного отображения обводки (stroke) как отдельного цвета.
1092
+ */
1093
+ function buildUnifiedColorToVarIndexMap(svg) {
1094
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1095
+ const map = new Map();
1096
+ const nextIdxRef = { v: 1 };
1097
+ const addColor = (rawVal) => {
1098
+ const norm = normalizeColorForCompare(rawVal);
1099
+ if (norm && !map.has(norm)) {
1100
+ map.set(norm, nextIdxRef.v);
1101
+ nextIdxRef.v = Math.min(nextIdxRef.v + 1, 3);
1102
+ }
1103
+ };
1104
+ const svgOpen = svg.match(/<svg([^>]*)>/i);
1105
+ if (svgOpen === null || svgOpen === void 0 ? void 0 : svgOpen[1]) {
1106
+ const attrs = svgOpen[1];
1107
+ const fillM = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1108
+ const strokeM = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1109
+ if ((fillM === null || fillM === void 0 ? void 0 : fillM[1]) && !/^none$/i.test(fillM[1]) && !/^url\(#/i.test(fillM[1]))
1110
+ addColor(fillM[1]);
1111
+ if ((strokeM === null || strokeM === void 0 ? void 0 : strokeM[1]) && !/^none$/i.test(strokeM[1]) && !/^url\(#/i.test(strokeM[1]))
1112
+ addColor(strokeM[1]);
1113
+ }
1114
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
1115
+ let m;
1116
+ while ((m = attrRe.exec(svg)) !== null) {
1117
+ const attrs = m[1];
1118
+ const fillAttr = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1119
+ const fillStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1120
+ const fillFromStyle = (_a = fillStyle === null || fillStyle === void 0 ? void 0 : fillStyle[1]) === null || _a === void 0 ? void 0 : _a.match(/fill\s*:\s*([^;]+)/i);
1121
+ const fillVal = (_d = ((_b = fillAttr === null || fillAttr === void 0 ? void 0 : fillAttr[1]) !== null && _b !== void 0 ? _b : (_c = fillFromStyle === null || fillFromStyle === void 0 ? void 0 : fillFromStyle[1]) === null || _c === void 0 ? void 0 : _c.trim())) === null || _d === void 0 ? void 0 : _d.trim();
1122
+ if (fillVal && !/^none$/i.test(fillVal) && !/^url\(#/i.test(fillVal))
1123
+ addColor(fillVal);
1124
+ const strokeAttr = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1125
+ const strokeStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1126
+ const strokeFromStyle = (_e = strokeStyle === null || strokeStyle === void 0 ? void 0 : strokeStyle[1]) === null || _e === void 0 ? void 0 : _e.match(/stroke\s*:\s*([^;]+)/i);
1127
+ const strokeVal = (_h = ((_f = strokeAttr === null || strokeAttr === void 0 ? void 0 : strokeAttr[1]) !== null && _f !== void 0 ? _f : (_g = strokeFromStyle === null || strokeFromStyle === void 0 ? void 0 : strokeFromStyle[1]) === null || _g === void 0 ? void 0 : _g.trim())) === null || _h === void 0 ? void 0 : _h.trim();
1128
+ if (strokeVal && !/^none$/i.test(strokeVal) && !/^url\(#/i.test(strokeVal))
1129
+ addColor(strokeVal);
1130
+ }
1131
+ return map;
1132
+ }
1133
+ /** Аналогично для stroke. Учитывает stroke на <svg> — наследуется paths. */
1134
+ function buildStrokeColorToVarIndexMap(svg) {
1135
+ var _a, _b, _c, _d;
1136
+ const map = new Map();
1137
+ const nextIdxRef = { v: 1 };
1138
+ const svgOpen = svg.match(/<svg([^>]*)>/i);
1139
+ if (svgOpen === null || svgOpen === void 0 ? void 0 : svgOpen[1]) {
1140
+ const m = svgOpen[1].match(/stroke\s*=\s*["']([^"']*)["']/i);
1141
+ if ((m === null || m === void 0 ? void 0 : m[1]) && !/^none$/i.test(m[1]) && !/^url\(#/i.test(m[1]))
1142
+ addColorToMap(map, m[1], nextIdxRef);
1143
+ }
1144
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
1145
+ let m;
1146
+ while ((m = attrRe.exec(svg)) !== null) {
1147
+ const attrs = m[1];
1148
+ const strokeAttr = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1149
+ const strokeStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1150
+ const strokeFromStyle = (_a = strokeStyle === null || strokeStyle === void 0 ? void 0 : strokeStyle[1]) === null || _a === void 0 ? void 0 : _a.match(/stroke\s*:\s*([^;]+)/i);
1151
+ const strokeVal = (_d = ((_b = strokeAttr === null || strokeAttr === void 0 ? void 0 : strokeAttr[1]) !== null && _b !== void 0 ? _b : (_c = strokeFromStyle === null || strokeFromStyle === void 0 ? void 0 : strokeFromStyle[1]) === null || _c === void 0 ? void 0 : _c.trim())) === null || _d === void 0 ? void 0 : _d.trim();
1152
+ if (strokeVal && !/^none$/i.test(strokeVal) && !/^url\(#/i.test(strokeVal)) {
1153
+ addColorToMap(map, strokeVal, nextIdxRef);
1154
+ }
1155
+ }
1156
+ return map;
1157
+ }
1158
+ /**
1159
+ * Извлекает цвета из SVG в том же порядке, что и buildUnifiedColorToVarIndexMap.
1160
+ * Возвращает [color1, color2, color3] — сырые значения для пикеров.
1161
+ */
1162
+ function extractColorsInUnifiedOrder(svg) {
1163
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1164
+ const result = [];
1165
+ const seen = new Set();
1166
+ const addColor = (rawVal) => {
1167
+ const norm = normalizeColorForCompare(rawVal);
1168
+ if (norm && !seen.has(norm)) {
1169
+ seen.add(norm);
1170
+ result.push(rawVal);
1171
+ }
1172
+ };
1173
+ const stopColors = Array.from(svg.matchAll(/<stop[^>]*?stop-color\s*=\s*["']([^"']+)["']/gi)).map(m => m[1]);
1174
+ if (stopColors.length >= 2) {
1175
+ stopColors.slice(0, 3).forEach(c => addColor(c));
1176
+ return result;
1177
+ }
1178
+ const svgOpen = svg.match(/<svg([^>]*)>/i);
1179
+ if (svgOpen === null || svgOpen === void 0 ? void 0 : svgOpen[1]) {
1180
+ const attrs = svgOpen[1];
1181
+ const fillM = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1182
+ const strokeM = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1183
+ if ((fillM === null || fillM === void 0 ? void 0 : fillM[1]) && !/^none$/i.test(fillM[1]) && !/^url\(#/i.test(fillM[1]))
1184
+ addColor(fillM[1]);
1185
+ if ((strokeM === null || strokeM === void 0 ? void 0 : strokeM[1]) && !/^none$/i.test(strokeM[1]) && !/^url\(#/i.test(strokeM[1]))
1186
+ addColor(strokeM[1]);
1187
+ }
1188
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
1189
+ let m;
1190
+ while ((m = attrRe.exec(svg)) !== null) {
1191
+ const attrs = m[1];
1192
+ const fillAttr = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1193
+ const fillStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1194
+ const fillFromStyle = (_a = fillStyle === null || fillStyle === void 0 ? void 0 : fillStyle[1]) === null || _a === void 0 ? void 0 : _a.match(/fill\s*:\s*([^;]+)/i);
1195
+ const fillVal = (_d = ((_b = fillAttr === null || fillAttr === void 0 ? void 0 : fillAttr[1]) !== null && _b !== void 0 ? _b : (_c = fillFromStyle === null || fillFromStyle === void 0 ? void 0 : fillFromStyle[1]) === null || _c === void 0 ? void 0 : _c.trim())) === null || _d === void 0 ? void 0 : _d.trim();
1196
+ if (fillVal && !/^none$/i.test(fillVal) && !/^url\(#/i.test(fillVal))
1197
+ addColor(fillVal);
1198
+ const strokeAttr = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1199
+ const strokeStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1200
+ const strokeFromStyle = (_e = strokeStyle === null || strokeStyle === void 0 ? void 0 : strokeStyle[1]) === null || _e === void 0 ? void 0 : _e.match(/stroke\s*:\s*([^;]+)/i);
1201
+ const strokeVal = (_h = ((_f = strokeAttr === null || strokeAttr === void 0 ? void 0 : strokeAttr[1]) !== null && _f !== void 0 ? _f : (_g = strokeFromStyle === null || strokeFromStyle === void 0 ? void 0 : strokeFromStyle[1]) === null || _g === void 0 ? void 0 : _g.trim())) === null || _h === void 0 ? void 0 : _h.trim();
1202
+ if (strokeVal && !/^none$/i.test(strokeVal) && !/^url\(#/i.test(strokeVal))
1203
+ addColor(strokeVal);
1204
+ }
1205
+ return result.slice(0, 3);
1206
+ }
1207
+ /** Извлекает цвета для установки в пикеры (stops, fills, strokes по приоритету) */
1208
+ function extractColorsForPickers(svg) {
1209
+ const stops = Array.from(svg.matchAll(/<stop[^>]*?stop-color\s*=\s*["']([^"']+)["']/gi)).map(m => m[1]);
1210
+ const fills = [];
1211
+ const strokes = [];
1212
+ const svgOpen = svg.match(/<svg([^>]*)>/i);
1213
+ if (svgOpen === null || svgOpen === void 0 ? void 0 : svgOpen[1]) {
1214
+ const attrs = svgOpen[1];
1215
+ const svgFill = attrs.match(/fill\s*=\s*["']([^"']+)["']/i);
1216
+ const svgStroke = attrs.match(/stroke\s*=\s*["']([^"']+)["']/i);
1217
+ if ((svgFill === null || svgFill === void 0 ? void 0 : svgFill[1]) && !/^none$/i.test(svgFill[1]) && !/^url\(#/i.test(svgFill[1]))
1218
+ fills.push(svgFill[1]);
1219
+ if ((svgStroke === null || svgStroke === void 0 ? void 0 : svgStroke[1]) && !/^none$/i.test(svgStroke[1]) && !/^url\(#/i.test(svgStroke[1]))
1220
+ strokes.push(svgStroke[1]);
1221
+ }
1222
+ const attrRe = new RegExp(`<(?:${SHAPE_TAGS})([^>]*)>`, 'gi');
1223
+ let m;
1224
+ while ((m = attrRe.exec(svg)) !== null) {
1225
+ const attrs = m[1];
1226
+ const fillAttr = attrs.match(/fill\s*=\s*["']([^"']+)["']/i);
1227
+ const strokeAttr = attrs.match(/stroke\s*=\s*["']([^"']+)["']/i);
1228
+ if ((fillAttr === null || fillAttr === void 0 ? void 0 : fillAttr[1]) && !/^none$/i.test(fillAttr[1]) && !/^url\(#/i.test(fillAttr[1]))
1229
+ fills.push(fillAttr[1]);
1230
+ if ((strokeAttr === null || strokeAttr === void 0 ? void 0 : strokeAttr[1]) && !/^none$/i.test(strokeAttr[1]) && !/^url\(#/i.test(strokeAttr[1]))
1231
+ strokes.push(strokeAttr[1]);
1232
+ const styleM = attrs.match(/style\s*=\s*["']([^"']+)["']/i);
1233
+ if (styleM) {
1234
+ const f = extractFromStyle(styleM[1], 'fill');
1235
+ const s = extractFromStyle(styleM[1], 'stroke');
1236
+ if (f && !/^none$/i.test(f))
1237
+ fills.push(f);
1238
+ if (s && !/^none$/i.test(s))
1239
+ strokes.push(s);
1240
+ }
1241
+ }
1242
+ return { fills, strokes, stops };
1243
+ }
1244
+
1245
+ ;// ./src/components/ImageIcons/normalizeSvgForCss.ts
1246
+
1247
+ /**
1248
+ * Prepares SVG for tinting via CSS variables in the grid / preview (Lucide + Tabler / Iconify).
1249
+ */
1250
+ function normalizeSvgForCss(text, opts) {
1251
+ let out = text;
1252
+ const hasGradientDef = /<linearGradient[\s\S]*?<\/linearGradient>/i.test(out) || /<radialGradient[\s\S]*?<\/radialGradient>/i.test(out);
1253
+ const usesGradientRef = /fill="url\(#/i.test(out) || /stroke="url\(#/i.test(out);
1254
+ if (!usesGradientRef) {
1255
+ const colorMap = buildUnifiedColorToVarIndexMap(out);
1256
+ const getColorVar = (raw) => {
1257
+ const norm = normalizeColorForCompare(raw);
1258
+ const idx = norm ? colorMap.get(norm) : undefined;
1259
+ if (idx === 1)
1260
+ return 'var(--icon-color-1)';
1261
+ if (idx === 2)
1262
+ return 'var(--icon-color-2)';
1263
+ if (idx === 3)
1264
+ return 'var(--icon-color-3)';
1265
+ return 'currentColor';
1266
+ };
1267
+ out = out.replace(/<svg([^>]*)>/i, (_full, attrs) => {
1268
+ let newAttrs = attrs;
1269
+ const svgFill = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1270
+ if ((svgFill === null || svgFill === void 0 ? void 0 : svgFill[1]) && !/^none$/i.test(svgFill[1]) && !/^url\(#/i.test(svgFill[1])) {
1271
+ newAttrs = newAttrs.replace(/fill\s*=\s*["'][^"']*["']/i, `fill="${getColorVar(svgFill[1])}"`);
1272
+ }
1273
+ const svgStroke = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1274
+ if ((svgStroke === null || svgStroke === void 0 ? void 0 : svgStroke[1]) && !/^none$/i.test(svgStroke[1]) && !/^url\(#/i.test(svgStroke[1])) {
1275
+ newAttrs = newAttrs.replace(/stroke\s*=\s*["'][^"']*["']/i, `stroke="${getColorVar(svgStroke[1])}"`);
1276
+ }
1277
+ return `<svg${newAttrs}>`;
1278
+ });
1279
+ out = out.replace(/<(path|rect|circle|ellipse|polygon|line|polyline)([^>]*?)(\/>|>)/gi, (_full, tag, attrs, end) => {
1280
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1281
+ let newAttrs = attrs;
1282
+ const fillAttr = attrs.match(/fill\s*=\s*["']([^"']*)["']/i);
1283
+ const fillStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1284
+ const fillFromStyle = (_a = fillStyle === null || fillStyle === void 0 ? void 0 : fillStyle[1]) === null || _a === void 0 ? void 0 : _a.match(/fill\s*:\s*([^;]+)/i);
1285
+ const fillVal = (_d = ((_b = fillAttr === null || fillAttr === void 0 ? void 0 : fillAttr[1]) !== null && _b !== void 0 ? _b : (_c = fillFromStyle === null || fillFromStyle === void 0 ? void 0 : fillFromStyle[1]) === null || _c === void 0 ? void 0 : _c.trim())) === null || _d === void 0 ? void 0 : _d.trim();
1286
+ if (fillVal && !/^none$/i.test(fillVal) && !/^url\(#/i.test(fillVal)) {
1287
+ const varName = getColorVar(fillVal);
1288
+ if (fillAttr)
1289
+ newAttrs = newAttrs.replace(/fill\s*=\s*["'][^"']*["']/i, `fill="${varName}"`);
1290
+ else if (fillStyle === null || fillStyle === void 0 ? void 0 : fillStyle[1]) {
1291
+ newAttrs = newAttrs.replace(/style\s*=\s*["']([^"']*)["']/i, (_m, s) => {
1292
+ const replaced = s.replace(/fill\s*:\s*[^;]+/gi, 'fill: ' + varName);
1293
+ return 'style="' + replaced + '"';
1294
+ });
1295
+ }
1296
+ }
1297
+ const strokeAttr = attrs.match(/stroke\s*=\s*["']([^"']*)["']/i);
1298
+ const strokeStyle = attrs.match(/style\s*=\s*["']([^"']*)["']/i);
1299
+ const strokeFromStyle = (_e = strokeStyle === null || strokeStyle === void 0 ? void 0 : strokeStyle[1]) === null || _e === void 0 ? void 0 : _e.match(/stroke\s*:\s*([^;]+)/i);
1300
+ const strokeVal = (_h = ((_f = strokeAttr === null || strokeAttr === void 0 ? void 0 : strokeAttr[1]) !== null && _f !== void 0 ? _f : (_g = strokeFromStyle === null || strokeFromStyle === void 0 ? void 0 : strokeFromStyle[1]) === null || _g === void 0 ? void 0 : _g.trim())) === null || _h === void 0 ? void 0 : _h.trim();
1301
+ const hasStroke = strokeVal && !/^none$/i.test(strokeVal) && !/^url\(#/i.test(strokeVal);
1302
+ if (hasStroke) {
1303
+ const varName = getColorVar(strokeVal);
1304
+ if (strokeAttr)
1305
+ newAttrs = newAttrs.replace(/stroke\s*=\s*["'][^"']*["']/i, `stroke="${varName}"`);
1306
+ else if (strokeStyle === null || strokeStyle === void 0 ? void 0 : strokeStyle[1]) {
1307
+ newAttrs = newAttrs.replace(/style\s*=\s*["']([^"']*)["']/i, (_m, s) => {
1308
+ const replaced = s.replace(/stroke\s*:\s*[^;]+/gi, 'stroke: ' + varName);
1309
+ return 'style="' + replaced + '"';
1310
+ });
1311
+ }
1312
+ }
1313
+ return `<${tag}${newAttrs}${end}`;
1314
+ });
1315
+ }
1316
+ if (hasGradientDef) {
1317
+ out = out.replace(/<linearGradient([^>]*?)>([\s\S]*?)<\/linearGradient>/gi, (_full, attrs, inner) => {
1318
+ let idx = 0;
1319
+ const replacedInner = inner.replace(/<stop([^>]*?)>/gi, (_s, sattrs) => {
1320
+ const varName = idx === 0 ? 'var(--icon-grad-1)' : 'var(--icon-grad-2)';
1321
+ idx += 1;
1322
+ if (/stop-color\s*=/.test(sattrs)) {
1323
+ const replaced = sattrs.replace(/stop-color="[^"]*"/i, 'stop-color="' + varName + '"');
1324
+ return '<stop' + replaced + '>';
1325
+ }
1326
+ return '<stop' + sattrs + ' stop-color="' + varName + '">';
1327
+ });
1328
+ return `<linearGradient${attrs}>${replacedInner}</linearGradient>`;
1329
+ });
1330
+ out = out.replace(/<radialGradient([^>]*?)>([\s\S]*?)<\/radialGradient>/gi, (_full, attrs, inner) => {
1331
+ let idx = 0;
1332
+ const replacedInner = inner.replace(/<stop([^>]*?)>/gi, (_s, sattrs) => {
1333
+ const varName = idx === 0 ? 'var(--icon-grad-1)' : 'var(--icon-grad-2)';
1334
+ idx += 1;
1335
+ if (/stop-color\s*=/.test(sattrs)) {
1336
+ const replaced = sattrs.replace(/stop-color="[^"]*"/i, 'stop-color="' + varName + '"');
1337
+ return '<stop' + replaced + '>';
1338
+ }
1339
+ return '<stop' + sattrs + ' stop-color="' + varName + '">';
1340
+ });
1341
+ return `<radialGradient${attrs}>${replacedInner}</radialGradient>`;
1342
+ });
1343
+ }
1344
+ if (typeof (opts === null || opts === void 0 ? void 0 : opts.strokeWidth) === 'number' && !Number.isNaN(opts.strokeWidth)) {
1345
+ if (/stroke-width\s*=\s*["'][^"']*["']/i.test(out)) {
1346
+ out = out.replace(/stroke-width\s*=\s*["'][^"']*["']/gi, `stroke-width="${opts.strokeWidth}"`);
1347
+ }
1348
+ if (/stroke-width\s*:/.test(out)) {
1349
+ out = out.replace(/stroke-width\s*:\s*[^;]+/gi, `stroke-width: ${opts.strokeWidth}`);
1350
+ }
1351
+ if (!/stroke-width/i.test(out)) {
1352
+ out = out.replace(/<svg/, `<svg stroke-width="${opts.strokeWidth}"`);
1353
+ }
1354
+ }
1355
+ out = out.replace(/<svg([^>]*)>/i, (_full, attrs) => {
1356
+ const newAttrs = attrs.replace(/\swidth="[^"]*"/i, '').replace(/\sheight="[^"]*"/i, '');
1357
+ return `<svg${newAttrs} width="100%" height="100%">`;
1358
+ });
1359
+ return out;
1360
+ }
1361
+
1362
+ ;// ./src/components/ImageIcons/useIconifyStock.ts
1363
+
1364
+
1365
+
1366
+
1367
+
1368
+
1369
+ const svgCache = new Map();
1370
+ const ICON_JSON_BY_PREFIX = {
1371
+ [lucide/* icons */.Pt.prefix || 'lucide']: lucide/* icons */.Pt,
1372
+ [tabler/* icons */.Pt.prefix || 'tabler']: tabler/* icons */.Pt,
1373
+ };
1374
+ function parseStockIconId(iconId) {
1375
+ const i = iconId.indexOf(':');
1376
+ if (i <= 0)
1377
+ return null;
1378
+ const prefix = iconId.slice(0, i);
1379
+ const slug = iconId.slice(i + 1);
1380
+ if (!slug)
1381
+ return null;
1382
+ return { prefix, slug };
1383
+ }
1384
+ function buildRawSvg(prefix, slug, size) {
1385
+ const set = ICON_JSON_BY_PREFIX[prefix];
1386
+ if (!set) {
1387
+ throw new Error(`Unknown icon set prefix: ${prefix}`);
1388
+ }
1389
+ const data = (0,get_icon/* getIconData */.y)(set, slug);
1390
+ if (!data) {
1391
+ throw new Error(`Unknown icon: ${prefix}:${slug}`);
1392
+ }
1393
+ const built = (0,build/* iconToSVG */.p)(data, { width: size, height: size });
1394
+ let svg = (0,html/* iconToHTML */.U)(built.body, built.attributes);
1395
+ svg = svg.replace(/<svg([^>]*)>/i, (_full, attrs) => {
1396
+ const newAttrs = attrs.replace(/\swidth="[^"]*"/i, '').replace(/\sheight="[^"]*"/i, '');
1397
+ return `<svg${newAttrs} width="100%" height="100%">`;
1398
+ });
1399
+ return svg;
1400
+ }
1401
+ function useIconifyStock(useCssColor) {
1402
+ const fetchSvgDataUrl = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (iconId, options) => {
1403
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1404
+ const parsed = parseStockIconId(iconId);
1405
+ if (!parsed) {
1406
+ throw new Error(`Invalid icon id (expected prefix:name): ${iconId}`);
1407
+ }
1408
+ const { prefix, slug } = parsed;
1409
+ const size = (_a = options === null || options === void 0 ? void 0 : options.size) !== null && _a !== void 0 ? _a : 96;
1410
+ const keyParts = [
1411
+ iconId,
1412
+ useCssColor ? 'css=1' : 'css=0',
1413
+ useCssColor
1414
+ ? ''
1415
+ : `c1=${(_c = (_b = options === null || options === void 0 ? void 0 : options.inlineColors) === null || _b === void 0 ? void 0 : _b.colorHex) !== null && _c !== void 0 ? _c : ''}|c2=${(_e = (_d = options === null || options === void 0 ? void 0 : options.inlineColors) === null || _d === void 0 ? void 0 : _d.colorHex2) !== null && _e !== void 0 ? _e : ''}|c3=${(_g = (_f = options === null || options === void 0 ? void 0 : options.inlineColors) === null || _f === void 0 ? void 0 : _f.colorHex3) !== null && _g !== void 0 ? _g : ''}`,
1416
+ (options === null || options === void 0 ? void 0 : options.strokeWidth) != null ? `sw=${options.strokeWidth}` : '',
1417
+ `s=${size}`,
1418
+ ].filter(Boolean);
1419
+ const cacheKey = keyParts.join('|');
1420
+ const cached = svgCache.get(cacheKey);
1421
+ if (cached)
1422
+ return cached;
1423
+ if ((_h = options === null || options === void 0 ? void 0 : options.signal) === null || _h === void 0 ? void 0 : _h.aborted) {
1424
+ throw new DOMException('Aborted', 'AbortError');
1425
+ }
1426
+ const originalText = buildRawSvg(prefix, slug, size);
1427
+ let svgText = originalText;
1428
+ if (useCssColor) {
1429
+ svgText = normalizeSvgForCss(svgText, { strokeWidth: options === null || options === void 0 ? void 0 : options.strokeWidth });
1430
+ }
1431
+ else if (options === null || options === void 0 ? void 0 : options.inlineColors) {
1432
+ svgText = (0,svgToPng/* applyInlineColors */.K7)(svgText, options.inlineColors);
1433
+ }
1434
+ const dataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
1435
+ const result = { text: svgText, url: dataUrl, original: originalText };
1436
+ svgCache.set(cacheKey, result);
1437
+ return result;
1438
+ }, [useCssColor]);
1439
+ return { fetchSvgDataUrl, normalizeSvgForCss: normalizeSvgForCss };
1440
+ }
1441
+
1442
+ // EXTERNAL MODULE: ./node_modules/@untitledui/icons/dist/Scale01.mjs
1443
+ var Scale01 = __webpack_require__(6213);
1444
+ // EXTERNAL MODULE: ./node_modules/@untitledui/icons/dist/Copy04.mjs
1445
+ var Copy04 = __webpack_require__(969);
1446
+ // EXTERNAL MODULE: ./node_modules/@untitledui/icons/dist/FolderPlus.mjs
1447
+ var FolderPlus = __webpack_require__(5070);
1448
+ // EXTERNAL MODULE: ./src/components/FolderTree/FolderTree.tsx + 1 modules
1449
+ var FolderTree = __webpack_require__(486);
1450
+ // EXTERNAL MODULE: ./src/components/FileModals/FileModals.module.scss
1451
+ var FileModals_module = __webpack_require__(5954);
1452
+ // EXTERNAL MODULE: ./src/hooks/useFolderSelectionMenu.tsx
1453
+ var useFolderSelectionMenu = __webpack_require__(520);
1454
+ // EXTERNAL MODULE: ./src/hooks/useNotifications.tsx
1455
+ var useNotifications = __webpack_require__(3435);
1456
+ // EXTERNAL MODULE: ./src/utils/dedupeUploadNamesOnClient.ts
1457
+ var dedupeUploadNamesOnClient = __webpack_require__(3795);
1458
+ // EXTERNAL MODULE: ./src/utils/nameNormalization.ts
1459
+ var nameNormalization = __webpack_require__(7407);
1460
+ // EXTERNAL MODULE: ./src/utils/resolveUniqueUploadName.ts
1461
+ var resolveUniqueUploadName = __webpack_require__(7742);
1462
+ ;// ./src/components/ImageIcons/useIconsCopyToFolder.tsx
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+ async function uploadSelectedIconsToFolder(params) {
1474
+ var _a;
1475
+ const { hashes, items, folderId, dataProviders, getPngDataUrlForItem, dataUrlToBlob, config } = params;
1476
+ let successCount = 0;
1477
+ let failCount = 0;
1478
+ for (const hash of hashes) {
1479
+ const item = items.find(i => i.hash === hash);
1480
+ if (!item) {
1481
+ failCount += 1;
1482
+ continue;
1483
+ }
1484
+ const dataUrl = await getPngDataUrlForItem(item);
1485
+ if (!dataUrl) {
1486
+ failCount += 1;
1487
+ continue;
1488
+ }
1489
+ const fileNameBase = ((_a = item.name) === null || _a === void 0 ? void 0 : _a.trim()) || `icon-${hash}`;
1490
+ const normalizedFileName = (0,nameNormalization/* normalizeFileName */.Px)(`${fileNameBase}.png`, config);
1491
+ const fileName = await (0,resolveUniqueUploadName/* resolveUniqueUploadNameWithProvider */.v)(dataProviders, normalizedFileName, folderId, false, (0,dedupeUploadNamesOnClient/* isDedupeUploadNamesOnClientEnabled */.m)(config));
1492
+ const blob = dataUrlToBlob(dataUrl, 'image/png');
1493
+ const file = new File([blob], fileName, {
1494
+ type: 'image/png',
1495
+ lastModified: Date.now(),
1496
+ });
1497
+ try {
1498
+ await dataProviders.uploadFile({
1499
+ name: fileName,
1500
+ size: file.size,
1501
+ type: file.type,
1502
+ folderId,
1503
+ data: file,
1504
+ extension: 'png',
1505
+ });
1506
+ successCount += 1;
1507
+ }
1508
+ catch (_b) {
1509
+ failCount += 1;
1510
+ }
1511
+ }
1512
+ return { successCount, failCount };
1513
+ }
1514
+ const useIconsCopyToFolder = ({ items, selectedHashes, getPngDataUrlForItem, dataUrlToBlob, clearSelection, }) => {
1515
+ const { t } = (0,es/* useTranslation */.Bd)();
1516
+ const { options, state: fmState } = (0,hooks/* useFileManagerContext */.wh)();
1517
+ const notification = (0,useNotifications/* useNotifications */.E)();
1518
+ const [isCopyIconsModalVisible, setIsCopyIconsModalVisible] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(false);
1519
+ const [copyForm] = external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form.useForm();
1520
+ const [isCopyLoading, setIsCopyLoading] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(false);
1521
+ const copyInFlightRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(false);
1522
+ const { state: foldersState, actions: { fetchFolders, fetchChildFolders, handleModalOk: handleFolderModalOk }, } = (0,hooks/* useFolders */.nv)();
1523
+ const { EmptyFolderIcon } = (0,useCustomIcons/* useCustomIcons */.D)();
1524
+ const { activeFormField, setActiveFormField, generateMenuItemsFromFolders } = (0,useFolderSelectionMenu/* useFolderSelectionMenu */.p)({
1525
+ folders: Array.isArray(foldersState.folders) ? foldersState.folders : [],
1526
+ selectedFolder: fmState.selectedFolder,
1527
+ EmptyFolderIcon,
1528
+ handleCreateFolderModalOk: handleFolderModalOk,
1529
+ setIsLoading: setIsCopyLoading,
1530
+ t,
1531
+ });
1532
+ const openCopyModal = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async () => {
1533
+ await fetchFolders();
1534
+ setIsCopyIconsModalVisible(true);
1535
+ }, [fetchFolders]);
1536
+ const handleCopyTreeSelect = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (selectedKeys) => {
1537
+ if (selectedKeys.length > 0) {
1538
+ copyForm.setFieldsValue({ targetFolder: selectedKeys[0] });
1539
+ if (activeFormField !== selectedKeys[0].toString()) {
1540
+ setActiveFormField('');
1541
+ }
1542
+ }
1543
+ }, [activeFormField, copyForm, setActiveFormField]);
1544
+ const performCopyToFolder = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (overrideFolderId) => {
1545
+ var _a, _b;
1546
+ try {
1547
+ const { dataProviders } = options;
1548
+ if (!dataProviders || (!dataProviders.uploadFile && !dataProviders.uploadFiles)) {
1549
+ notification.error({
1550
+ id: 'FILES_UPLOAD_PROVIDER_NOT_CONFIGURED',
1551
+ message: t('API-endpoint for file upload is not configured'),
1552
+ placement: 'bottomRight',
1553
+ });
1554
+ return;
1555
+ }
1556
+ const folderId = overrideFolderId || (fmState === null || fmState === void 0 ? void 0 : fmState.selectedFolder) || undefined;
1557
+ const hashes = Array.from(selectedHashes);
1558
+ if (hashes.length === 0)
1559
+ return;
1560
+ const uploadFile = (_a = dataProviders.uploadFile) !== null && _a !== void 0 ? _a : (async (args) => {
1561
+ var _a, _b, _c;
1562
+ if (!dataProviders.uploadFiles) {
1563
+ throw new Error('Upload is not supported by data provider');
1564
+ }
1565
+ const result = await dataProviders.uploadFiles({
1566
+ folderId: args.folderId,
1567
+ items: [
1568
+ {
1569
+ name: args.name,
1570
+ size: args.size,
1571
+ type: args.type,
1572
+ folderId: args.folderId,
1573
+ data: args.data,
1574
+ extension: args.extension,
1575
+ },
1576
+ ],
1577
+ });
1578
+ const first = (_a = result === null || result === void 0 ? void 0 : result.detailed) === null || _a === void 0 ? void 0 : _a[0];
1579
+ if (!result || !result.success || !first || first.success === false) {
1580
+ const errorMessage = ((_b = first === null || first === void 0 ? void 0 : first.error) === null || _b === void 0 ? void 0 : _b.message) || ((_c = result === null || result === void 0 ? void 0 : result.error) === null || _c === void 0 ? void 0 : _c.message) || 'Upload failed';
1581
+ throw new Error(errorMessage);
1582
+ }
1583
+ return first.data;
1584
+ });
1585
+ const { successCount, failCount } = await uploadSelectedIconsToFolder({
1586
+ hashes,
1587
+ items,
1588
+ folderId,
1589
+ dataProviders: {
1590
+ uploadFile,
1591
+ getFiles: dataProviders.getFiles,
1592
+ getFolders: dataProviders.getFolders,
1593
+ },
1594
+ getPngDataUrlForItem,
1595
+ dataUrlToBlob,
1596
+ config: options === null || options === void 0 ? void 0 : options.config,
1597
+ });
1598
+ if (successCount > 0) {
1599
+ notification.success({
1600
+ id: 'FILES_COPY_SUCCESS',
1601
+ message: t('Files copied'),
1602
+ placement: 'bottomRight',
1603
+ data: {
1604
+ successCount,
1605
+ totalCount: hashes.length,
1606
+ itemIds: hashes,
1607
+ folderId: folderId !== null && folderId !== void 0 ? folderId : null,
1608
+ },
1609
+ });
1610
+ }
1611
+ if (failCount > 0) {
1612
+ notification.error({
1613
+ id: 'FILES_COPY_ERROR',
1614
+ message: t('При копировании произошли ошибки'),
1615
+ placement: 'bottomRight',
1616
+ data: {
1617
+ failCount,
1618
+ totalCount: hashes.length,
1619
+ itemIds: hashes,
1620
+ folderId: folderId !== null && folderId !== void 0 ? folderId : null,
1621
+ },
1622
+ });
1623
+ }
1624
+ clearSelection();
1625
+ }
1626
+ catch (e) {
1627
+ console.error(e);
1628
+ notification.error({
1629
+ id: 'FILES_COPY_ERROR',
1630
+ message: t('При копировании произошли ошибки'),
1631
+ placement: 'bottomRight',
1632
+ innerException: e,
1633
+ data: {
1634
+ failCount: Array.from(selectedHashes).length || 0,
1635
+ totalCount: Array.from(selectedHashes).length || 0,
1636
+ itemIds: Array.from(selectedHashes),
1637
+ folderId: (_b = fmState === null || fmState === void 0 ? void 0 : fmState.selectedFolder) !== null && _b !== void 0 ? _b : null,
1638
+ },
1639
+ });
1640
+ }
1641
+ }, [
1642
+ clearSelection,
1643
+ dataUrlToBlob,
1644
+ getPngDataUrlForItem,
1645
+ items,
1646
+ notification,
1647
+ options,
1648
+ selectedHashes,
1649
+ fmState === null || fmState === void 0 ? void 0 : fmState.selectedFolder,
1650
+ t,
1651
+ ]);
1652
+ const closeCopyModal = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(() => {
1653
+ if (isCopyLoading || copyInFlightRef.current)
1654
+ return;
1655
+ setIsCopyIconsModalVisible(false);
1656
+ setActiveFormField('');
1657
+ setIsCopyLoading(false);
1658
+ }, [isCopyLoading, setActiveFormField]);
1659
+ const resetAfterClose = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(() => {
1660
+ setActiveFormField('');
1661
+ setIsCopyLoading(false);
1662
+ }, [setActiveFormField]);
1663
+ const handleIconsCopyOk = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (targetFolder) => {
1664
+ if (copyInFlightRef.current)
1665
+ return;
1666
+ copyInFlightRef.current = true;
1667
+ setIsCopyLoading(true);
1668
+ try {
1669
+ await performCopyToFolder(targetFolder !== null && targetFolder !== void 0 ? targetFolder : null);
1670
+ setIsCopyIconsModalVisible(false);
1671
+ setActiveFormField('');
1672
+ }
1673
+ finally {
1674
+ copyInFlightRef.current = false;
1675
+ setIsCopyLoading(false);
1676
+ }
1677
+ }, [performCopyToFolder, setActiveFormField]);
1678
+ const handleCreateFolderAndCopy = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(() => {
1679
+ var _a;
1680
+ const targetFolder = (_a = fmState.selectedFolder) !== null && _a !== void 0 ? _a : 'folders';
1681
+ setActiveFormField(targetFolder);
1682
+ copyForm.setFieldsValue({ folderName: t('New folder'), targetFolder });
1683
+ }, [copyForm, fmState.selectedFolder, setActiveFormField, t]);
1684
+ return {
1685
+ isCopyIconsModalVisible,
1686
+ isCopyLoading,
1687
+ copyForm,
1688
+ openCopyModal,
1689
+ closeCopyModal,
1690
+ resetAfterClose,
1691
+ handleCopyTreeSelect,
1692
+ handleIconsCopyOk,
1693
+ handleCreateFolderAndCopy,
1694
+ fetchChildFolders,
1695
+ generateMenuItemsFromFolders,
1696
+ };
1697
+ };
1698
+
1699
+ ;// ./src/components/ImageIcons/IconsTab.tsx
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+
1718
+ const FIRST_LOAD_LIMIT = 30;
1719
+ const SCROLL_LOAD_LIMIT = 30;
1720
+ const ICON_STOCK_SVG_FETCH_CONCURRENCY = 8;
1721
+ async function mapWithConcurrency(items, limit, fn) {
1722
+ if (items.length === 0)
1723
+ return [];
1724
+ const results = new Array(items.length);
1725
+ let nextIndex = 0;
1726
+ const poolSize = Math.max(1, Math.min(limit, items.length));
1727
+ const worker = async () => {
1728
+ while (true) {
1729
+ const i = nextIndex++;
1730
+ if (i >= items.length)
1731
+ return;
1732
+ results[i] = await fn(items[i]);
1733
+ }
1734
+ };
1735
+ await Promise.all(Array.from({ length: poolSize }, () => worker()));
1736
+ return results;
1737
+ }
1738
+ const IconsTab = ({ customRequest, query: queryProp, setQuery: setQueryProp, inputRef, }) => {
1739
+ var _a, _b, _c;
1740
+ const { t } = (0,es/* useTranslation */.Bd)();
1741
+ const [localQuery, setLocalQuery] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState('');
1742
+ const query = queryProp !== undefined ? queryProp : localQuery;
1743
+ const setQuery = setQueryProp !== undefined ? setQueryProp : setLocalQuery;
1744
+ const [effectiveQuery, setEffectiveQuery] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState('');
1745
+ const [items, setItems] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState([]);
1746
+ const [offset, setOffset] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(0);
1747
+ const [hasMore, setHasMore] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(false);
1748
+ const [loading, setLoading] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(false);
1749
+ const [isCollectingResults, setIsCollectingResults] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(false);
1750
+ const [selectedHash, setSelectedHash] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(null);
1751
+ const [svgTextMap, setSvgTextMap] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState({});
1752
+ const [originalSvgMap, setOriginalSvgMap] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState({});
1753
+ const [colorHex, setColorHex] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState('#000000');
1754
+ const [colorHex2, setColorHex2] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState('#ff007a');
1755
+ const [colorHex3, setColorHex3] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState('#00C2FF');
1756
+ const [strokeWidth, setStrokeWidth] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(1);
1757
+ const [sizePx, setSizePx] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(50);
1758
+ /** Lucide / Tabler SVG: CSS variables in the grid; PNG export bakes colors client-side. */
1759
+ const useCssColor = true;
1760
+ const [isInsertLoading, setIsInsertLoading] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(false);
1761
+ const fileManager = (0,hooks/* useFileManagerContext */.wh)();
1762
+ const { options } = fileManager;
1763
+ const isMountedRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(false);
1764
+ const searchDebounceRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
1765
+ const searchSeqRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(0);
1766
+ const lastCompletedSearchSignatureRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
1767
+ const fetchSearchRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
1768
+ const translateRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(undefined);
1769
+ translateRef.current = resolveIconStockTranslate(options === null || options === void 0 ? void 0 : options.config);
1770
+ const localeRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef((_a = options === null || options === void 0 ? void 0 : options.config) === null || _a === void 0 ? void 0 : _a.locale);
1771
+ localeRef.current = (_b = options === null || options === void 0 ? void 0 : options.config) === null || _b === void 0 ? void 0 : _b.locale;
1772
+ const svgAbortRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
1773
+ const svgLoadFailuresRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(new Set());
1774
+ const insertAbortRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
1775
+ const inFlightSearchKeysRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(new Set());
1776
+ const [selectedHashes, setSelectedHashes] = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useState(new Set());
1777
+ const sortedStockIdsRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef([]);
1778
+ const colorsExtractedForQueryRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(null);
1779
+ const { fetchSvgDataUrl, normalizeSvgForCss } = useIconifyStock(useCssColor);
1780
+ const aggregatedParse = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useMemo(() => {
1781
+ if (items.length === 0)
1782
+ return null;
1783
+ const itemHashes = new Set(items.map(i => i.hash));
1784
+ const source = Object.keys(originalSvgMap).some(h => itemHashes.has(h)) ? originalSvgMap : svgTextMap;
1785
+ const texts = items.map(i => source[i.hash]).filter((t) => Boolean(t));
1786
+ if (texts.length === 0)
1787
+ return null;
1788
+ const results = texts.map(txt => parseSvgForFamily(txt));
1789
+ return aggregateSvgParseResults(results);
1790
+ }, [items, originalSvgMap, svgTextMap]);
1791
+ const hasAnyGradient = Boolean(aggregatedParse === null || aggregatedParse === void 0 ? void 0 : aggregatedParse.hasGradient);
1792
+ const usesSecondColorVar = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useMemo(() => {
1793
+ return items.some(i => {
1794
+ const txt = svgTextMap[i.hash];
1795
+ return txt && /var\(--icon-color-2\)/i.test(txt);
1796
+ });
1797
+ }, [items, svgTextMap]);
1798
+ const usesThirdColorVar = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useMemo(() => {
1799
+ return items.some(i => {
1800
+ const txt = svgTextMap[i.hash];
1801
+ return txt && /var\(--icon-color-3\)/i.test(txt);
1802
+ });
1803
+ }, [items, svgTextMap]);
1804
+ const showSecondColor = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useMemo(() => {
1805
+ if (!useCssColor)
1806
+ return false;
1807
+ if (!aggregatedParse)
1808
+ return false;
1809
+ return hasAnyGradient || (aggregatedParse.colors.length >= 2 && usesSecondColorVar);
1810
+ }, [aggregatedParse, hasAnyGradient, useCssColor, usesSecondColorVar]);
1811
+ const showThirdColor = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useMemo(() => {
1812
+ if (!useCssColor)
1813
+ return false;
1814
+ if (!aggregatedParse)
1815
+ return false;
1816
+ return aggregatedParse.colors.length >= 3 && usesThirdColorVar;
1817
+ }, [aggregatedParse, useCssColor, usesThirdColorVar]);
1818
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
1819
+ isMountedRef.current = true;
1820
+ return () => {
1821
+ var _a, _b;
1822
+ isMountedRef.current = false;
1823
+ try {
1824
+ (_a = svgAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
1825
+ (_b = insertAbortRef.current) === null || _b === void 0 ? void 0 : _b.abort();
1826
+ }
1827
+ catch (_c) {
1828
+ // ignore
1829
+ }
1830
+ };
1831
+ }, []);
1832
+ const initialQueryRef = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useRef(query);
1833
+ const fetchSearch = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(
1834
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- lucide search + infinite scroll
1835
+ async (args) => {
1836
+ var _a, _b, _c;
1837
+ const baseQuery = (_b = (_a = args.override) === null || _a === void 0 ? void 0 : _a.query) !== null && _b !== void 0 ? _b : effectiveQuery;
1838
+ if (!baseQuery || baseQuery.trim().length < 3)
1839
+ return;
1840
+ if (args.initial ? loading : isCollectingResults || loading)
1841
+ return;
1842
+ if (!isMountedRef.current)
1843
+ return;
1844
+ if (args.initial) {
1845
+ sortedStockIdsRef.current =
1846
+ ((_c = args.override) === null || _c === void 0 ? void 0 : _c.stockIds) !== undefined ? args.override.stockIds : listMatchingStockIconIds(baseQuery);
1847
+ setLoading(true);
1848
+ setItems([]);
1849
+ setSvgTextMap({});
1850
+ setOriginalSvgMap({});
1851
+ setOffset(0);
1852
+ setHasMore(false);
1853
+ }
1854
+ else {
1855
+ setIsCollectingResults(true);
1856
+ }
1857
+ const all = sortedStockIdsRef.current;
1858
+ const currentOffset = args.initial ? 0 : offset;
1859
+ const limit = args.initial ? FIRST_LOAD_LIMIT : SCROLL_LOAD_LIMIT;
1860
+ const requestKey = `${baseQuery}|${currentOffset}|${limit}|${args.initial ? 'i' : 'm'}`;
1861
+ if (inFlightSearchKeysRef.current.has(requestKey)) {
1862
+ return;
1863
+ }
1864
+ inFlightSearchKeysRef.current.add(requestKey);
1865
+ try {
1866
+ const batch = all.slice(currentOffset, currentOffset + limit).map(stockIconIdToItem);
1867
+ if (!isMountedRef.current)
1868
+ return;
1869
+ if (args.initial) {
1870
+ const nextItems = batch.filter((item, index, allItems) => allItems.findIndex(candidate => candidate.hash === item.hash) === index);
1871
+ setItems(nextItems);
1872
+ }
1873
+ else {
1874
+ setItems(prev => {
1875
+ const knownHashes = new Set(prev.map(item => item.hash));
1876
+ const nextBatch = batch.filter(item => !knownHashes.has(item.hash));
1877
+ return nextBatch.length > 0 ? [...prev, ...nextBatch] : prev;
1878
+ });
1879
+ }
1880
+ setHasMore(currentOffset + batch.length < all.length);
1881
+ setOffset(currentOffset + batch.length);
1882
+ }
1883
+ catch (e) {
1884
+ if ((e === null || e === void 0 ? void 0 : e.name) === 'AbortError')
1885
+ return;
1886
+ console.error(e);
1887
+ external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.message.error(t('Request error'));
1888
+ }
1889
+ finally {
1890
+ if (isMountedRef.current) {
1891
+ if (args.initial) {
1892
+ setLoading(false);
1893
+ }
1894
+ else {
1895
+ setIsCollectingResults(false);
1896
+ }
1897
+ }
1898
+ inFlightSearchKeysRef.current.delete(requestKey);
1899
+ }
1900
+ }, [effectiveQuery, isCollectingResults, loading, offset, t]);
1901
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
1902
+ fetchSearchRef.current = fetchSearch;
1903
+ }, [fetchSearch]);
1904
+ const runSearch = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (rawQuery) => {
1905
+ var _a;
1906
+ if (!rawQuery || rawQuery.trim().length < 3)
1907
+ return;
1908
+ const requestedSignature = rawQuery.trim();
1909
+ if (lastCompletedSearchSignatureRef.current === requestedSignature) {
1910
+ return;
1911
+ }
1912
+ const requestId = ++searchSeqRef.current;
1913
+ const rawTrim = rawQuery.trim();
1914
+ let translatedQuery = rawTrim;
1915
+ if (translateRef.current) {
1916
+ try {
1917
+ const out = await translateRef.current(rawQuery, { locale: localeRef.current });
1918
+ translatedQuery = (out !== null && out !== void 0 ? out : rawTrim).trim() || rawTrim;
1919
+ }
1920
+ catch (e) {
1921
+ console.error('IconsTab: translation error', e);
1922
+ translatedQuery = rawTrim;
1923
+ }
1924
+ }
1925
+ if (requestId !== searchSeqRef.current)
1926
+ return;
1927
+ svgLoadFailuresRef.current.clear();
1928
+ setSelectedHash(null);
1929
+ setSelectedHashes(new Set());
1930
+ setEffectiveQuery(translatedQuery);
1931
+ let stockIds;
1932
+ if (translateRef.current && rawTrim !== translatedQuery) {
1933
+ stockIds = mergeStockIconIdsOrdered(listMatchingStockIconIds(translatedQuery), listMatchingStockIconIds(rawTrim));
1934
+ }
1935
+ await ((_a = fetchSearchRef.current) === null || _a === void 0 ? void 0 : _a.call(fetchSearchRef, {
1936
+ initial: true,
1937
+ override: { query: translatedQuery, stockIds },
1938
+ }));
1939
+ lastCompletedSearchSignatureRef.current = requestedSignature;
1940
+ }, []);
1941
+ const handleSubmit = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async () => {
1942
+ if (!query || query.trim().length < 3)
1943
+ return;
1944
+ if (searchDebounceRef.current) {
1945
+ window.clearTimeout(searchDebounceRef.current);
1946
+ searchDebounceRef.current = null;
1947
+ }
1948
+ await runSearch(query);
1949
+ }, [query, runSearch]);
1950
+ const resetToInitialIconsState = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(() => {
1951
+ searchSeqRef.current += 1;
1952
+ svgLoadFailuresRef.current.clear();
1953
+ sortedStockIdsRef.current = [];
1954
+ colorsExtractedForQueryRef.current = null;
1955
+ setEffectiveQuery('');
1956
+ setItems([]);
1957
+ setIsCollectingResults(false);
1958
+ setHasMore(false);
1959
+ setOffset(0);
1960
+ lastCompletedSearchSignatureRef.current = null;
1961
+ setSelectedHash(null);
1962
+ setSelectedHashes(new Set());
1963
+ setColorHex('#000000');
1964
+ setColorHex2('#ff007a');
1965
+ setColorHex3('#00C2FF');
1966
+ }, []);
1967
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
1968
+ const initialQuery = initialQueryRef.current;
1969
+ if (initialQuery && initialQuery.trim().length >= 3) {
1970
+ runSearch(initialQuery);
1971
+ }
1972
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1973
+ }, []);
1974
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
1975
+ const trimmed = query.trim();
1976
+ if (searchDebounceRef.current) {
1977
+ window.clearTimeout(searchDebounceRef.current);
1978
+ searchDebounceRef.current = null;
1979
+ }
1980
+ if (trimmed.length < 3) {
1981
+ resetToInitialIconsState();
1982
+ return;
1983
+ }
1984
+ searchDebounceRef.current = window.setTimeout(() => {
1985
+ runSearch(trimmed);
1986
+ }, 700);
1987
+ }, [query, resetToInitialIconsState, runSearch]);
1988
+ const handleIconClick = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback((item) => {
1989
+ setSelectedHash(item.hash);
1990
+ }, []);
1991
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
1992
+ var _a;
1993
+ if (items.length === 0)
1994
+ return;
1995
+ let toFetch = items.map(i => i.hash).filter(h => !svgTextMap[h]);
1996
+ toFetch = toFetch.filter(h => !svgLoadFailuresRef.current.has(h));
1997
+ if (toFetch.length === 0)
1998
+ return;
1999
+ let cancelled = false;
2000
+ (_a = svgAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
2001
+ const controller = new AbortController();
2002
+ svgAbortRef.current = controller;
2003
+ mapWithConcurrency(toFetch, ICON_STOCK_SVG_FETCH_CONCURRENCY, h => fetchSvgDataUrl(h, {
2004
+ strokeWidth: typeof strokeWidth === 'number' ? strokeWidth : undefined,
2005
+ size: sizePx,
2006
+ signal: controller.signal,
2007
+ inlineColors: useCssColor ? undefined : { colorHex, colorHex2, colorHex3 },
2008
+ })
2009
+ .then(r => ({ h, r }))
2010
+ .catch((err) => {
2011
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError') {
2012
+ return { h, r: null };
2013
+ }
2014
+ svgLoadFailuresRef.current.add(h);
2015
+ return { h, r: null };
2016
+ }))
2017
+ .then(results => {
2018
+ if (cancelled || !isMountedRef.current)
2019
+ return;
2020
+ const textUpdates = {};
2021
+ const originalUpdates = {};
2022
+ results.forEach(rr => {
2023
+ if (rr && rr.h && rr.r) {
2024
+ textUpdates[rr.h] = rr.r.text;
2025
+ if (rr.r.original)
2026
+ originalUpdates[rr.h] = rr.r.original;
2027
+ }
2028
+ });
2029
+ if (Object.keys(textUpdates).length > 0)
2030
+ setSvgTextMap(prev => (Object.assign(Object.assign({}, prev), textUpdates)));
2031
+ if (Object.keys(originalUpdates).length > 0)
2032
+ setOriginalSvgMap(prev => (Object.assign(Object.assign({}, prev), originalUpdates)));
2033
+ })
2034
+ .catch(() => {
2035
+ /* aborted or network */
2036
+ });
2037
+ return () => {
2038
+ cancelled = true;
2039
+ controller.abort();
2040
+ };
2041
+ }, [colorHex, colorHex2, colorHex3, fetchSvgDataUrl, items, sizePx, strokeWidth, svgTextMap, useCssColor]);
2042
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
2043
+ if (items.length === 0)
2044
+ return;
2045
+ const hashes = items.map(i => i.hash);
2046
+ const updatesText = {};
2047
+ let changed = false;
2048
+ hashes.forEach(h => {
2049
+ const base = originalSvgMap[h] || svgTextMap[h];
2050
+ if (!base)
2051
+ return;
2052
+ const next = normalizeSvgForCss(base, { strokeWidth: typeof strokeWidth === 'number' ? strokeWidth : undefined });
2053
+ if (next && next !== svgTextMap[h]) {
2054
+ updatesText[h] = next;
2055
+ changed = true;
2056
+ }
2057
+ });
2058
+ if (changed && Object.keys(updatesText).length > 0) {
2059
+ setSvgTextMap(prev => (Object.assign(Object.assign({}, prev), updatesText)));
2060
+ }
2061
+ }, [items, normalizeSvgForCss, originalSvgMap, strokeWidth, svgTextMap]);
2062
+ external_root_React_commonjs2_react_commonjs_react_amd_react_default().useEffect(() => {
2063
+ if (items.length === 0)
2064
+ return;
2065
+ const q = effectiveQuery.trim();
2066
+ if (!q || colorsExtractedForQueryRef.current === q)
2067
+ return;
2068
+ const firstWithOrig = items.find(i => originalSvgMap[i.hash]);
2069
+ if (!firstWithOrig)
2070
+ return;
2071
+ const raw = originalSvgMap[firstWithOrig.hash];
2072
+ if (!raw)
2073
+ return;
2074
+ colorsExtractedForQueryRef.current = q;
2075
+ const colors = extractColorsInUnifiedOrder(raw);
2076
+ const toHex = (c) => {
2077
+ const s = (c || '').trim();
2078
+ const m = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
2079
+ if (m) {
2080
+ const hex = m[1].length === 3 ? m[1].replace(/(.)/g, '$1$1') : m[1];
2081
+ return '#' + hex.toLowerCase();
2082
+ }
2083
+ return colorToHex(c);
2084
+ };
2085
+ if (colors[0])
2086
+ setColorHex(toHex(colors[0]));
2087
+ if (colors[1])
2088
+ setColorHex2(toHex(colors[1]));
2089
+ if (colors[2])
2090
+ setColorHex3(toHex(colors[2]));
2091
+ }, [effectiveQuery, items, originalSvgMap]);
2092
+ const buildSvgWithInlineColors = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback((svg) => (0,svgToPng/* applyInlineColors */.K7)(svg, { colorHex, colorHex2, colorHex3 }), [colorHex, colorHex2, colorHex3]);
2093
+ const toggleSelect = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback((hash) => {
2094
+ setSelectedHashes(prev => {
2095
+ const next = new Set(prev);
2096
+ if (next.has(hash))
2097
+ next.delete(hash);
2098
+ else
2099
+ next.add(hash);
2100
+ return next;
2101
+ });
2102
+ }, []);
2103
+ const clearSelection = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(() => {
2104
+ setSelectedHashes(new Set());
2105
+ }, []);
2106
+ const selectedItem = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useMemo(() => {
2107
+ if (selectedHashes.size === 1) {
2108
+ const [hash] = Array.from(selectedHashes);
2109
+ return items.find(item => item.hash === hash) || null;
2110
+ }
2111
+ if (selectedHashes.size === 0 && selectedHash) {
2112
+ return items.find(item => item.hash === selectedHash) || null;
2113
+ }
2114
+ return null;
2115
+ }, [items, selectedHash, selectedHashes]);
2116
+ const dataUrlToBlob = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback((dataUrl, mimeType = 'image/png') => {
2117
+ try {
2118
+ const parts = dataUrl.split(',');
2119
+ if (parts.length < 2)
2120
+ return new Blob([], { type: mimeType });
2121
+ const base64Data = parts[1] || '';
2122
+ const byteCharacters = atob(base64Data);
2123
+ const byteNumbers = new Array(byteCharacters.length);
2124
+ for (let i = 0; i < byteCharacters.length; i += 1) {
2125
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
2126
+ }
2127
+ const byteArray = new Uint8Array(byteNumbers);
2128
+ return new Blob([byteArray], { type: mimeType });
2129
+ }
2130
+ catch (_a) {
2131
+ return new Blob([], { type: mimeType });
2132
+ }
2133
+ }, []);
2134
+ const getPngDataUrlForItem = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (item, signal) => {
2135
+ try {
2136
+ let svgText = svgTextMap[item.hash] || originalSvgMap[item.hash];
2137
+ if (!svgText) {
2138
+ const svgRes = await fetchSvgDataUrl(item.hash, {
2139
+ strokeWidth: typeof strokeWidth === 'number' ? strokeWidth : undefined,
2140
+ size: sizePx,
2141
+ signal,
2142
+ inlineColors: useCssColor ? undefined : { colorHex, colorHex2, colorHex3 },
2143
+ });
2144
+ svgText = svgRes.text;
2145
+ }
2146
+ const forPng = useCssColor ? buildSvgWithInlineColors(svgText) : svgText;
2147
+ const dims = (0,svgToPng/* computeSvgTargetDimensions */.of)(forPng, sizePx);
2148
+ return (0,svgToPng/* rasterizeSvgToPng */.e2)(forPng, dims.width, dims.height);
2149
+ }
2150
+ catch (_a) {
2151
+ return null;
2152
+ }
2153
+ }, [
2154
+ buildSvgWithInlineColors,
2155
+ colorHex,
2156
+ colorHex2,
2157
+ colorHex3,
2158
+ fetchSvgDataUrl,
2159
+ originalSvgMap,
2160
+ sizePx,
2161
+ strokeWidth,
2162
+ svgTextMap,
2163
+ useCssColor,
2164
+ ]);
2165
+ const handleInsert = external_root_React_commonjs2_react_commonjs_react_amd_react_default().useCallback(async (item) => {
2166
+ var _a;
2167
+ try {
2168
+ if (!isMountedRef.current)
2169
+ return;
2170
+ setIsInsertLoading(true);
2171
+ (_a = insertAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
2172
+ const controller = new AbortController();
2173
+ insertAbortRef.current = controller;
2174
+ const dataUrl = await getPngDataUrlForItem(item, controller.signal);
2175
+ if (!isMountedRef.current || !dataUrl)
2176
+ return;
2177
+ await Promise.resolve(customRequest(dataUrl));
2178
+ }
2179
+ catch (e) {
2180
+ console.error('IconsTab: insert error', e);
2181
+ external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.message.error(t('Request error'));
2182
+ }
2183
+ finally {
2184
+ if (isMountedRef.current)
2185
+ setIsInsertLoading(false);
2186
+ }
2187
+ }, [customRequest, getPngDataUrlForItem, t]);
2188
+ const { isCopyIconsModalVisible, isCopyLoading, copyForm, openCopyModal, closeCopyModal, resetAfterClose, handleCopyTreeSelect, handleIconsCopyOk, fetchChildFolders, generateMenuItemsFromFolders, handleCreateFolderAndCopy, } = useIconsCopyToFolder({
2189
+ items,
2190
+ selectedHashes,
2191
+ getPngDataUrlForItem,
2192
+ dataUrlToBlob,
2193
+ clearSelection,
2194
+ });
2195
+ const showResultsUi = Boolean(effectiveQuery.trim()) && (items.length > 0 || loading);
2196
+ const showSelectionHeader = showResultsUi && selectedHashes.size > 0;
2197
+ return ((0,jsx_runtime.jsxs)(jsx_runtime.Fragment, { children: [(0,jsx_runtime.jsxs)("div", { className: `${ImageIcons_iconsTab_module.iconsTab} ${effectiveQuery.trim() ? ImageIcons_iconsTab_module.hasSearch : ''}`, children: [showResultsUi && showSelectionHeader ? ((0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsHeaderContainer, children: [(0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsHeaderContainerLeft, children: [(0,jsx_runtime.jsxs)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Typography.Text, { type: "secondary", children: [selectedHashes.size, " ", t('selected')] }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Button, { icon: (0,jsx_runtime.jsx)(Scale01/* Scale01 */.Q, { size: 16 }), onClick: clearSelection, children: t('Deselected') })] }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Space, { children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Button, { icon: (0,jsx_runtime.jsx)(Copy04/* Copy04 */.U, { size: 16 }), onClick: openCopyModal, children: t('Copy to folder') }) })] })) : ((0,jsx_runtime.jsx)(ImageIcons_IconsSearchForm, { query: query, onQueryChange: setQuery, onSubmit: handleSubmit, hasResults: items.length > 0 || loading, inputRef: inputRef })), showResultsUi ? ((0,jsx_runtime.jsx)(ImageIcons_IconsControls, { colorHex: colorHex, setColorHex: setColorHex, colorHex2: colorHex2, setColorHex2: setColorHex2, colorHex3: colorHex3, setColorHex3: setColorHex3, sizePx: sizePx, setSizePx: setSizePx, strokeWidth: strokeWidth, setStrokeWidth: setStrokeWidth, showSecondColor: showSecondColor, showThirdColor: showThirdColor })) : null, (0,jsx_runtime.jsx)(ImageIcons_IconsGrid, { items: items, loading: loading, isCollectingResults: isCollectingResults, hasMore: hasMore, hasQuery: Boolean(effectiveQuery.trim()), selectedHash: selectedHash, onItemClick: handleIconClick, onInsert: handleInsert, onLoadMore: () => {
2198
+ fetchSearch({ initial: false }).catch(() => {
2199
+ /* ignore */
2200
+ });
2201
+ }, colorVars: { colorHex, colorHex2, colorHex3 }, svgTextMap: svgTextMap, previewSize: sizePx, selectedHashes: selectedHashes, onToggleSelect: toggleSelect }), selectedItem ? ((0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.iconsBottomBar, children: [(0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Divider, { className: "zero-divider" }), (0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.iconsBottomBarContent, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Space, { children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Button, { size: "large", type: "primary", style: { height: 40 }, loading: isInsertLoading, onClick: () => handleInsert(selectedItem), children: t('Choose') }) }) })] })) : null] }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Modal, { title: (0,jsx_runtime.jsx)("div", { className: "modal-title", children: t('Copy to folder') }), open: isCopyIconsModalVisible, onCancel: () => {
2202
+ if (isCopyLoading)
2203
+ return;
2204
+ closeCopyModal();
2205
+ }, maskClosable: !isCopyLoading, closable: !isCopyLoading, keyboard: !isCopyLoading, footer: (0,jsx_runtime.jsxs)("div", { className: FileModals_module["default"].formFooter, children: [(0,jsx_runtime.jsxs)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Button, { className: FileModals_module["default"].folderButton, onClick: handleCreateFolderAndCopy, loading: isCopyLoading, children: [(0,jsx_runtime.jsx)(FolderPlus/* FolderPlus */.J, { size: 18, strokeWidth: (_c = options.config) === null || _c === void 0 ? void 0 : _c.iconStrokeWidth }), t('Create folder')] }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Button, { type: "primary", className: FileModals_module["default"].folderButton, onClick: () => {
2206
+ closeCopyModal();
2207
+ }, loading: isCopyLoading, children: t('Done') })] }), afterClose: () => resetAfterClose(), children: (0,jsx_runtime.jsxs)("div", { className: ImageIcons_iconsTab_module.copyToFolderModalBody, children: [isCopyLoading ? ((0,jsx_runtime.jsx)("div", { className: ImageIcons_iconsTab_module.copyToFolderModalLoadingOverlay, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Spin, { size: "large" }) })) : null, (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form, { form: copyForm, layout: "vertical", initialValues: { targetFolder: 'folders', folderName: t('New folder'), is_force_create: false }, children: (0,jsx_runtime.jsxs)("div", { className: FileModals_module["default"].foldersWrapper, children: [(0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form.Item, { name: "targetFolder", rules: [{ required: true, message: t('Select the destination folder') }], className: FileModals_module["default"].formItem, children: (0,jsx_runtime.jsx)(FolderTree/* FolderTree */.z, { onSelect: handleCopyTreeSelect, generateMenuItems: () => generateMenuItemsFromFolders({
2208
+ targetForm: copyForm,
2209
+ onTreeSelect: handleCopyTreeSelect,
2210
+ onComplete: handleIconsCopyOk,
2211
+ actionButtonText: t('Copy here'),
2212
+ }), fetchChildFolders: fetchChildFolders, disabledFolders: [], mode: "selection", className: 'folderSelectionTree', defaultExpandAll: true }) }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form.Item, { name: 'folderName', style: { display: 'none' }, rules: [
2213
+ {
2214
+ required: true,
2215
+ validator: (_, value) => {
2216
+ if (typeof value === 'string' && value.trim().length === 0) {
2217
+ return Promise.reject(new Error(t('Enter the name of the folder')));
2218
+ }
2219
+ return Promise.resolve();
2220
+ },
2221
+ },
2222
+ ], children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Input, {}) }), (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Form.Item, { name: 'is_force_create', style: { display: 'none' }, children: (0,jsx_runtime.jsx)(external_root_antd_commonjs2_antd_commonjs_antd_amd_antd_.Input, {}) })] }) })] }) })] }));
2223
+ };
2224
+ /* harmony default export */ const ImageIcons_IconsTab = (IconsTab);
2225
+
2226
+
2227
+ /***/ }),
2228
+
2229
+ /***/ 9875:
2230
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
2231
+
2232
+ // Imports
2233
+ var ___CSS_LOADER_API_SOURCEMAP_IMPORT___ = __webpack_require__(1354);
2234
+ var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(6314);
2235
+ var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);
2236
+ // Module
2237
+ ___CSS_LOADER_EXPORT___.push([module.id, `.iconsTab-module__iconsTab__rVCdL{display:flex;flex-direction:column;height:100%;min-height:0}.iconsTab-module__iconsTab__rVCdL.iconsTab-module__hasSearch__eOBPx{padding-top:0}.iconsTab-module__iconsSearchWrapper__Wl05l{width:100%;height:100%;min-height:0;overflow:hidden;box-sizing:border-box;line-height:0;display:flex;flex-direction:column;align-items:center;padding:24px}.iconsTab-module__iconsSearchForm__pOT9P{display:flex;gap:8px;width:100%;margin-bottom:0}.iconsTab-module__iconsSearchFormCenteredContainer__EcZ66{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;width:100%;padding:24px 24px 0}.iconsTab-module__iconsSearchFormCentered__mBHMX{display:flex;flex-direction:row;width:100%;align-items:flex-start;justify-content:center}.iconsTab-module__iconsSearchFormCentered__mBHMX .iconsTab-module__iconsSearchFormInput__aOh5i{width:640px;max-width:100%;padding:0;margin:auto auto 12px;transition:all 300ms ease}.iconsTab-module__iconsSearchFormCentered__mBHMX .iconsTab-module__iconsSearchFormInputInput__P1TM6{max-width:100%;width:100%}.iconsTab-module__iconsSearchFormInput__aOh5i{width:240px;padding:0;margin-bottom:0;transition:all 300ms ease}.iconsTab-module__iconsSearchResults__iMIGw{width:100%;display:flex;flex-direction:row;gap:8px;align-items:flex-start;justify-content:flex-start}.iconsTab-module__iconsSearchResults__iMIGw .iconsTab-module__iconsSearchFormInput__aOh5i{width:240px;flex:0 0 auto;margin-bottom:0}.iconsTab-module__iconsControlsControls__fPlU6{display:flex;align-items:center;gap:16px}.iconsTab-module__iconsSearchFormInputInput__P1TM6{width:100%}.iconsTab-module__iconsControls__U6HDG{display:flex;justify-content:space-between;align-items:center;width:100%;padding:24px 6px 24px 24px;border-bottom:1px solid var(--colorBorder)}.iconsTab-module__iconsControlsFamilySlug__WcZT7{opacity:.7}.iconsTab-module__iconsControlElement___RXMX{display:flex;align-items:center;gap:8px}.iconsTab-module__iconsControlElement___RXMX>span{color:var(--colorTextTertiary)}.iconsTab-module__iconsControlsStrokeWidth__p7z65{display:flex;align-items:center;gap:8px}.iconsTab-module__iconsControlsStrokeWidth__p7z65>span{color:var(--colorTextTertiary)}.iconsTab-module__iconsControlsStrokeWidth__p7z65 .iconsTab-module__ant-input-number__gVeff{width:80px}.iconsTab-module__iconsControlsCompact__kjz5q{position:relative}.iconsTab-module__iconsControlsInputNumber__uJAmX{width:110px}.iconsTab-module__iconsControlsInputNumber__uJAmX .ant-input-number,.iconsTab-module__iconsControlsInputNumber__uJAmX .ant-input-number-focused{border-top-left-radius:6px;border-bottom-left-radius:6px}.iconsTab-module__iconsControlsDropdownBtn__CsHya{padding:0;height:32px;min-width:36px;width:36px;border-top-right-radius:6px !important;border-bottom-right-radius:6px !important;border-top-left-radius:0 !important;border-bottom-left-radius:0 !important;display:inline-flex;align-items:center;justify-content:center;color:var(--colorTextTertiary)}.iconsTab-module__iconsControlsDropdownBtn__CsHya .anticon{font-size:12px;line-height:1}.iconsTab-module__iconsControlsDropdownBtn__CsHya:hover{color:var(--colorTextSecondary)}.iconsTab-module__iconsControlsCompact__kjz5q .iconsTab-module__iconsControlsDropdownBtn__CsHya{border-top-right-radius:6px !important;border-bottom-right-radius:6px !important}.iconsTab-module__sliderDropdown__rp1Dw{position:absolute;left:50%;transform:translateX(-50%);top:calc(100% + 6px);width:240px;background:#fff;border:1px solid rgba(0,0,0,.08);box-shadow:0 4px 12px rgba(0,0,0,.12);border-radius:8px;padding:10px 12px;z-index:1000}.iconsTab-module__iconsControlsHeader__Dk5bC{display:flex;align-items:center}.iconsTab-module__iconsSearchFormSelect__wc4Eb{width:160px !important}.iconsTab-module__iconsSearchFormStyleItem__s6wIB{margin-bottom:0;animation:iconsTab-module__fadeInSlide__JHeZ6 300ms ease forwards}@keyframes iconsTab-module__fadeInSlide__JHeZ6{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.iconsTab-module__iconsSearchDivider__baxtd{margin-top:24px;margin-bottom:0;border-color:var(--colorBorder);width:100%}.iconsTab-module__iconsSearchFormInputIcon__LGFqD{font-size:16px;cursor:pointer}.iconsTab-module__iconsGrid__fdgZB{width:100%;flex:1 1 auto;min-height:0;overflow:auto;overflow-x:hidden;box-sizing:border-box;padding:24px}.iconsTab-module__iconsBottomBar__ZJjsz{position:sticky;bottom:0;background:var(--colorBgLayout);z-index:5;width:100%}.iconsTab-module__iconsBottomBarContent__9SxMG{display:flex;justify-content:right;padding:17px 24px;align-items:center}.iconsTab-module__iconsGridEmpty__gE6NT{margin:40px 0px}.iconsTab-module__iconsGridEmptyState__OGcNZ{display:flex;justify-content:center;align-items:center;padding:0}.iconsTab-module__resultsContainer__u4uoQ{width:640px;max-width:100%;overflow:auto;box-sizing:border-box;padding:60px 16px;border-radius:12px;background-color:var(--colorBgContainer);display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center}.iconsTab-module__playButton__CS3Kr{color:var(--colorPrimary);margin-bottom:16px}.iconsTab-module__title__X8NPu{font-size:16px;font-weight:600;line-height:1.2;margin-bottom:4px}.iconsTab-module__subtitle__k6wsl{font-size:14px;color:var(--colorSecondary);line-height:1.2}.iconsTab-module__iconsGridInfiniteScroll__x0_E9{overflow:hidden !important}.iconsTab-module__iconsGridLoadingMore__MJy6W{display:flex;justify-content:center;padding:16px 0}.iconsTab-module__iconsGridGrid__jpJcf{display:grid;grid-template-columns:repeat(auto-fill, minmax(var(--icons-grid-min-col, 148px), 1fr));gap:16px}.iconsTab-module__iconsGridVirtualCanvas__cdbMd{position:relative;width:100%}.iconsTab-module__iconsGridItem__iHBC0{position:relative;border-radius:8px;padding:12px;background:#fff;cursor:pointer;display:flex;flex-direction:column;box-sizing:border-box;overflow:hidden;box-shadow:inset 0 0 0 1px #f0f0f0}.iconsTab-module__iconsGridItemThumbnail__nz4oB{display:flex;align-items:center;justify-content:center;flex:1 1 auto;min-height:0}.iconsTab-module__iconsGridItemSvg__nMNf2{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.iconsTab-module__iconsGridItemImg__uR1rx{max-width:100%;object-fit:contain}.iconsTab-module__iconsGridItemName__dxHty{margin-top:8px;font-size:12px;line-height:1.2;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:0 0 auto}.iconsTab-module__iconsGridItemSelected__O6f4h::after{content:"";position:absolute;inset:0;border:2px solid #1890ff;border-radius:inherit;pointer-events:none}.iconsTab-module__iconsGridItemInsertButton__nuuWZ{position:absolute;top:8px;right:8px}.iconsTab-module__iconsGridLoading__r5wNu{display:flex;align-items:center;justify-content:center;width:100%;min-height:50vh}.iconsTab-module__iconsControlsBackButton__lHXYH{margin-right:20px}.iconsTab-module__iconsGridCheckbox__TebOL{position:absolute;top:8px;left:8px;z-index:2;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out}.iconsTab-module__iconsGridItem__iHBC0:hover .iconsTab-module__iconsGridCheckbox__TebOL{opacity:1;pointer-events:auto}.iconsTab-module__iconsGridShowCheckboxes__Lwxc6 .iconsTab-module__iconsGridCheckbox__TebOL{opacity:1;pointer-events:auto}.iconsTab-module__iconsHeaderContainer__nlaKy{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;box-sizing:border-box;padding:24px 24px;margin:0;border-bottom:1px solid var(--colorBorder)}.iconsTab-module__iconsHeaderContainerLeft__sqO0_{display:flex;gap:10px;align-items:center}.iconsTab-module__iconsHeaderDivider__ujyPd{margin-top:24px;margin-bottom:0;border-color:var(--colorBorder);width:100%}.iconsTab-module__copyToFolderModalBody__AkxuH{position:relative}.iconsTab-module__copyToFolderModalLoadingOverlay__dd9RB{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center;background:hsla(0,0%,100%,.6);pointer-events:all}`, "",{"version":3,"sources":["webpack://./src/components/ImageIcons/iconsTab.module.scss"],"names":[],"mappings":"AAAA,kCACI,YAAA,CACA,qBAAA,CACA,WAAA,CACA,YAAA,CAEA,oEACI,aAAA,CAIR,4CACI,UAAA,CACA,WAAA,CACA,YAAA,CACA,eAAA,CACA,qBAAA,CACA,aAAA,CACA,YAAA,CACA,qBAAA,CACA,kBAAA,CACA,YAAA,CAGJ,yCACI,YAAA,CACA,OAAA,CACA,UAAA,CACA,eAAA,CAGJ,0DACI,YAAA,CACA,qBAAA,CACA,sBAAA,CACA,0BAAA,CACA,UAAA,CACA,mBAAA,CAGJ,iDACI,YAAA,CACA,kBAAA,CACA,UAAA,CACA,sBAAA,CACA,sBAAA,CAEA,+FACI,WAAA,CACA,cAAA,CACA,SAAA,CACA,qBAAA,CACA,yBAAA,CAGJ,oGACI,cAAA,CACA,UAAA,CAIR,8CACI,WAAA,CACA,SAAA,CACA,eAAA,CACA,yBAAA,CAGJ,4CACI,UAAA,CACA,YAAA,CACA,kBAAA,CACA,OAAA,CACA,sBAAA,CACA,0BAAA,CAEA,0FACI,WAAA,CACA,aAAA,CACA,eAAA,CAIR,+CACI,YAAA,CACA,kBAAA,CACA,QAAA,CAGJ,mDACI,UAAA,CAKJ,uCACI,YAAA,CACA,6BAAA,CACA,kBAAA,CACA,UAAA,CACA,0BAAA,CACA,0CAAA,CAGJ,iDACI,UAAA,CAGJ,6CACI,YAAA,CACA,kBAAA,CACA,OAAA,CAEA,kDACI,8BAAA,CAIR,kDACI,YAAA,CACA,kBAAA,CACA,OAAA,CAEA,uDACI,8BAAA,CAGJ,4FACI,UAAA,CAIR,8CACI,iBAAA,CAGJ,kDACI,WAAA,CAGJ,gJAEI,0BAAA,CACA,6BAAA,CAGJ,kDACI,SAAA,CACA,WAAA,CACA,cAAA,CACA,UAAA,CACA,sCAAA,CACA,yCAAA,CACA,mCAAA,CACA,sCAAA,CACA,mBAAA,CACA,kBAAA,CACA,sBAAA,CACA,8BAAA,CAEA,2DACI,cAAA,CACA,aAAA,CAGJ,wDACI,+BAAA,CAIR,gGACI,sCAAA,CACA,yCAAA,CAGJ,wCACI,iBAAA,CACA,QAAA,CACA,0BAAA,CACA,oBAAA,CACA,WAAA,CACA,eAAA,CACA,gCAAA,CACA,qCAAA,CACA,iBAAA,CACA,iBAAA,CACA,YAAA,CAGJ,6CACI,YAAA,CACA,kBAAA,CAIJ,+CACI,sBAAA,CAGJ,kDACI,eAAA,CACA,iEAAA,CAGJ,+CACI,KACI,SAAA,CACA,2BAAA,CAEJ,GACI,SAAA,CACA,uBAAA,CAAA,CAIR,4CACI,eAAA,CACA,eAAA,CACA,+BAAA,CACA,UAAA,CAGJ,kDACI,cAAA,CACA,cAAA,CAGJ,mCACI,UAAA,CACA,aAAA,CACA,YAAA,CACA,aAAA,CACA,iBAAA,CACA,qBAAA,CACA,YAAA,CAGJ,wCACI,eAAA,CACA,QAAA,CACA,+BAAA,CACA,SAAA,CACA,UAAA,CAGJ,+CACI,YAAA,CACA,qBAAA,CACA,iBAAA,CACA,kBAAA,CAGJ,wCACI,eAAA,CAGJ,6CACI,YAAA,CACA,sBAAA,CACA,kBAAA,CACA,SAAA,CAGJ,0CACI,WAAA,CACA,cAAA,CACA,aAAA,CACA,qBAAA,CACA,iBAAA,CACA,kBAAA,CACA,wCAAA,CACA,YAAA,CACA,kBAAA,CACA,sBAAA,CACA,qBAAA,CACA,iBAAA,CAGJ,oCACI,yBAAA,CACA,kBAAA,CAGJ,+BACI,cAAA,CACA,eAAA,CACA,eAAA,CACA,iBAAA,CAGJ,kCACI,cAAA,CACA,2BAAA,CACA,eAAA,CAGJ,iDACI,0BAAA,CAGJ,8CACI,YAAA,CACA,sBAAA,CACA,cAAA,CAGJ,uCACI,YAAA,CACA,sFAAA,CACA,QAAA,CAGJ,gDACI,iBAAA,CACA,UAAA,CAGJ,uCACI,iBAAA,CACA,iBAAA,CACA,YAAA,CACA,eAAA,CACA,cAAA,CACA,YAAA,CACA,qBAAA,CACA,qBAAA,CACA,eAAA,CACA,kCAAA,CAGJ,gDACI,YAAA,CACA,kBAAA,CACA,sBAAA,CACA,aAAA,CACA,YAAA,CAGJ,0CACI,UAAA,CACA,WAAA,CACA,YAAA,CACA,kBAAA,CACA,sBAAA,CAGJ,0CACI,cAAA,CACA,kBAAA,CAGJ,2CACI,cAAA,CACA,cAAA,CACA,eAAA,CACA,kBAAA,CACA,sBAAA,CACA,eAAA,CACA,aAAA,CAGJ,sDACI,UAAA,CACA,iBAAA,CACA,OAAA,CACA,wBAAA,CACA,qBAAA,CACA,mBAAA,CAGJ,mDACI,iBAAA,CACA,OAAA,CACA,SAAA,CAGJ,0CACI,YAAA,CACA,kBAAA,CACA,sBAAA,CACA,UAAA,CACA,eAAA,CAGJ,iDACI,iBAAA,CAGJ,2CACI,iBAAA,CACA,OAAA,CACA,QAAA,CACA,SAAA,CACA,SAAA,CACA,mBAAA,CACA,mCAAA,CAGJ,wFACI,SAAA,CACA,mBAAA,CAGJ,4FACI,SAAA,CACA,mBAAA,CAGJ,8CACI,YAAA,CACA,kBAAA,CACA,6BAAA,CACA,QAAA,CACA,UAAA,CACA,qBAAA,CACA,iBAAA,CACA,QAAA,CACA,0CAAA,CAGJ,kDACI,YAAA,CACA,QAAA,CACA,kBAAA,CAGJ,4CACI,eAAA,CACA,eAAA,CACA,+BAAA,CACA,UAAA,CAGJ,+CACI,iBAAA,CAGJ,yDACI,iBAAA,CACA,OAAA,CACA,UAAA,CACA,YAAA,CACA,kBAAA,CACA,sBAAA,CACA,6BAAA,CACA,kBAAA","sourcesContent":[".iconsTab {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n\n &.hasSearch {\n padding-top: 0;\n }\n}\n\n.iconsSearchWrapper {\n width: 100%;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n box-sizing: border-box;\n line-height: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 24px;\n}\n\n.iconsSearchForm {\n display: flex;\n gap: 8px;\n width: 100%;\n margin-bottom: 0;\n}\n\n.iconsSearchFormCenteredContainer {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: flex-start;\n width: 100%;\n padding: 24px 24px 0;\n}\n\n.iconsSearchFormCentered {\n display: flex;\n flex-direction: row;\n width: 100%;\n align-items: flex-start;\n justify-content: center;\n\n .iconsSearchFormInput {\n width: 640px;\n max-width: 100%;\n padding: 0;\n margin: auto auto 12px;\n transition: all 300ms ease;\n }\n\n .iconsSearchFormInputInput {\n max-width: 100%;\n width: 100%;\n }\n}\n\n.iconsSearchFormInput {\n width: 240px;\n padding: 0;\n margin-bottom: 0;\n transition: all 300ms ease;\n}\n\n.iconsSearchResults {\n width: 100%;\n display: flex;\n flex-direction: row;\n gap: 8px;\n align-items: flex-start;\n justify-content: flex-start;\n\n .iconsSearchFormInput {\n width: 240px;\n flex: 0 0 auto;\n margin-bottom: 0;\n }\n}\n\n.iconsControlsControls {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.iconsSearchFormInputInput {\n width: 100%;\n}\n\n\n\n.iconsControls {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n padding: 24px 6px 24px 24px;\n border-bottom: 1px solid var(--colorBorder);\n}\n\n.iconsControlsFamilySlug {\n opacity: 0.7\n}\n\n.iconsControlElement {\n display: flex;\n align-items: center;\n gap: 8px;\n\n & > span {\n color: var(--colorTextTertiary);\n }\n}\n\n.iconsControlsStrokeWidth {\n display: flex;\n align-items: center;\n gap: 8px;\n\n & > span {\n color: var(--colorTextTertiary);\n }\n\n .ant-input-number {\n width: 80px;\n }\n}\n\n.iconsControlsCompact {\n position: relative;\n}\n\n.iconsControlsInputNumber {\n width: 110px;\n}\n\n.iconsControlsInputNumber :global(.ant-input-number),\n.iconsControlsInputNumber :global(.ant-input-number-focused) {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n\n.iconsControlsDropdownBtn {\n padding: 0;\n height: 32px;\n min-width: 36px;\n width: 36px;\n border-top-right-radius: 6px !important;\n border-bottom-right-radius: 6px !important;\n border-top-left-radius: 0 !important;\n border-bottom-left-radius: 0 !important;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--colorTextTertiary);\n\n :global(.anticon) {\n font-size: 12px;\n line-height: 1;\n }\n\n &:hover {\n color: var(--colorTextSecondary);\n }\n}\n\n.iconsControlsCompact .iconsControlsDropdownBtn {\n border-top-right-radius: 6px !important;\n border-bottom-right-radius: 6px !important;\n}\n\n.sliderDropdown {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n top: calc(100% + 6px);\n width: 240px;\n background: #fff;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\n border-radius: 8px;\n padding: 10px 12px;\n z-index: 1000;\n}\n\n.iconsControlsHeader {\n display: flex;\n align-items: center;\n // gap: 24px;\n}\n\n.iconsSearchFormSelect {\n width: 160px !important;\n}\n\n.iconsSearchFormStyleItem {\n margin-bottom: 0;\n animation: fadeInSlide 300ms ease forwards;\n}\n\n@keyframes fadeInSlide {\n from {\n opacity: 0;\n transform: translateX(-10px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n.iconsSearchDivider {\n margin-top: 24px;\n margin-bottom: 0;\n border-color: var(--colorBorder);\n width: 100%;\n}\n\n.iconsSearchFormInputIcon {\n font-size: 16px;\n cursor: pointer;\n}\n\n.iconsGrid {\n width: 100%;\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n overflow-x: hidden;\n box-sizing: border-box;\n padding: 24px;\n}\n\n.iconsBottomBar {\n position: sticky;\n bottom: 0;\n background: var(--colorBgLayout);\n z-index: 5;\n width: 100%;\n}\n\n.iconsBottomBarContent {\n display: flex;\n justify-content: right;\n padding: 17px 24px;\n align-items: center;\n}\n\n.iconsGridEmpty {\n margin: 40px 0px;\n}\n\n.iconsGridEmptyState {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 0\n}\n\n.resultsContainer {\n width: 640px;\n max-width: 100%;\n overflow: auto;\n box-sizing: border-box;\n padding: 60px 16px;\n border-radius: 12px;\n background-color: var(--colorBgContainer);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n text-align: center;\n}\n\n.playButton {\n color: var(--colorPrimary);\n margin-bottom: 16px;\n}\n\n.title {\n font-size: 16px;\n font-weight: 600;\n line-height: 1.2;\n margin-bottom: 4px;\n}\n\n.subtitle {\n font-size: 14px;\n color: var(--colorSecondary);\n line-height: 1.2;\n}\n\n.iconsGridInfiniteScroll {\n overflow: hidden !important;\n}\n\n.iconsGridLoadingMore {\n display: flex;\n justify-content: center;\n padding: 16px 0;\n}\n\n.iconsGridGrid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(var(--icons-grid-min-col, 148px), 1fr));\n gap: 16px;\n}\n\n.iconsGridVirtualCanvas {\n position: relative;\n width: 100%;\n}\n\n.iconsGridItem {\n position: relative;\n border-radius: 8px;\n padding: 12px;\n background: #fff;\n cursor: pointer;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n overflow: hidden;\n box-shadow: inset 0 0 0 1px #f0f0f0;\n}\n\n.iconsGridItemThumbnail {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1 1 auto;\n min-height: 0;\n}\n\n.iconsGridItemSvg {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.iconsGridItemImg {\n max-width: 100%;\n object-fit: contain;\n}\n\n.iconsGridItemName {\n margin-top: 8px;\n font-size: 12px;\n line-height: 1.2;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n flex: 0 0 auto;\n}\n\n.iconsGridItemSelected::after {\n content: '';\n position: absolute;\n inset: 0;\n border: 2px solid #1890ff;\n border-radius: inherit;\n pointer-events: none;\n}\n\n.iconsGridItemInsertButton {\n position: absolute;\n top: 8px;\n right: 8px;\n}\n\n.iconsGridLoading {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n min-height: 50vh;\n}\n\n.iconsControlsBackButton {\n margin-right: 20px;\n}\n\n.iconsGridCheckbox {\n position: absolute;\n top: 8px;\n left: 8px;\n z-index: 2;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n}\n\n.iconsGridItem:hover .iconsGridCheckbox {\n opacity: 1;\n pointer-events: auto;\n}\n\n.iconsGridShowCheckboxes .iconsGridCheckbox {\n opacity: 1;\n pointer-events: auto;\n}\n\n.iconsHeaderContainer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n width: 100%;\n box-sizing: border-box;\n padding: 24px 24px;\n margin: 0;\n border-bottom: 1px solid var(--colorBorder);\n}\n\n.iconsHeaderContainerLeft {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n.iconsHeaderDivider {\n margin-top: 24px;\n margin-bottom: 0;\n border-color: var(--colorBorder);\n width: 100%;\n}\n\n.copyToFolderModalBody {\n position: relative;\n}\n\n.copyToFolderModalLoadingOverlay {\n position: absolute;\n inset: 0;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.6);\n pointer-events: all;\n}\n"],"sourceRoot":""}]);
2238
+ // Exports
2239
+ ___CSS_LOADER_EXPORT___.locals = {
2240
+ "iconsTab": `iconsTab-module__iconsTab__rVCdL`,
2241
+ "hasSearch": `iconsTab-module__hasSearch__eOBPx`,
2242
+ "iconsSearchWrapper": `iconsTab-module__iconsSearchWrapper__Wl05l`,
2243
+ "iconsSearchForm": `iconsTab-module__iconsSearchForm__pOT9P`,
2244
+ "iconsSearchFormCenteredContainer": `iconsTab-module__iconsSearchFormCenteredContainer__EcZ66`,
2245
+ "iconsSearchFormCentered": `iconsTab-module__iconsSearchFormCentered__mBHMX`,
2246
+ "iconsSearchFormInput": `iconsTab-module__iconsSearchFormInput__aOh5i`,
2247
+ "iconsSearchFormInputInput": `iconsTab-module__iconsSearchFormInputInput__P1TM6`,
2248
+ "iconsSearchResults": `iconsTab-module__iconsSearchResults__iMIGw`,
2249
+ "iconsControlsControls": `iconsTab-module__iconsControlsControls__fPlU6`,
2250
+ "iconsControls": `iconsTab-module__iconsControls__U6HDG`,
2251
+ "iconsControlsFamilySlug": `iconsTab-module__iconsControlsFamilySlug__WcZT7`,
2252
+ "iconsControlElement": `iconsTab-module__iconsControlElement___RXMX`,
2253
+ "iconsControlsStrokeWidth": `iconsTab-module__iconsControlsStrokeWidth__p7z65`,
2254
+ "ant-input-number": `iconsTab-module__ant-input-number__gVeff`,
2255
+ "antInputNumber": `iconsTab-module__ant-input-number__gVeff`,
2256
+ "iconsControlsCompact": `iconsTab-module__iconsControlsCompact__kjz5q`,
2257
+ "iconsControlsInputNumber": `iconsTab-module__iconsControlsInputNumber__uJAmX`,
2258
+ "iconsControlsDropdownBtn": `iconsTab-module__iconsControlsDropdownBtn__CsHya`,
2259
+ "sliderDropdown": `iconsTab-module__sliderDropdown__rp1Dw`,
2260
+ "iconsControlsHeader": `iconsTab-module__iconsControlsHeader__Dk5bC`,
2261
+ "iconsSearchFormSelect": `iconsTab-module__iconsSearchFormSelect__wc4Eb`,
2262
+ "iconsSearchFormStyleItem": `iconsTab-module__iconsSearchFormStyleItem__s6wIB`,
2263
+ "fadeInSlide": `iconsTab-module__fadeInSlide__JHeZ6`,
2264
+ "iconsSearchDivider": `iconsTab-module__iconsSearchDivider__baxtd`,
2265
+ "iconsSearchFormInputIcon": `iconsTab-module__iconsSearchFormInputIcon__LGFqD`,
2266
+ "iconsGrid": `iconsTab-module__iconsGrid__fdgZB`,
2267
+ "iconsBottomBar": `iconsTab-module__iconsBottomBar__ZJjsz`,
2268
+ "iconsBottomBarContent": `iconsTab-module__iconsBottomBarContent__9SxMG`,
2269
+ "iconsGridEmpty": `iconsTab-module__iconsGridEmpty__gE6NT`,
2270
+ "iconsGridEmptyState": `iconsTab-module__iconsGridEmptyState__OGcNZ`,
2271
+ "resultsContainer": `iconsTab-module__resultsContainer__u4uoQ`,
2272
+ "playButton": `iconsTab-module__playButton__CS3Kr`,
2273
+ "title": `iconsTab-module__title__X8NPu`,
2274
+ "subtitle": `iconsTab-module__subtitle__k6wsl`,
2275
+ "iconsGridInfiniteScroll": `iconsTab-module__iconsGridInfiniteScroll__x0_E9`,
2276
+ "iconsGridLoadingMore": `iconsTab-module__iconsGridLoadingMore__MJy6W`,
2277
+ "iconsGridGrid": `iconsTab-module__iconsGridGrid__jpJcf`,
2278
+ "iconsGridVirtualCanvas": `iconsTab-module__iconsGridVirtualCanvas__cdbMd`,
2279
+ "iconsGridItem": `iconsTab-module__iconsGridItem__iHBC0`,
2280
+ "iconsGridItemThumbnail": `iconsTab-module__iconsGridItemThumbnail__nz4oB`,
2281
+ "iconsGridItemSvg": `iconsTab-module__iconsGridItemSvg__nMNf2`,
2282
+ "iconsGridItemImg": `iconsTab-module__iconsGridItemImg__uR1rx`,
2283
+ "iconsGridItemName": `iconsTab-module__iconsGridItemName__dxHty`,
2284
+ "iconsGridItemSelected": `iconsTab-module__iconsGridItemSelected__O6f4h`,
2285
+ "iconsGridItemInsertButton": `iconsTab-module__iconsGridItemInsertButton__nuuWZ`,
2286
+ "iconsGridLoading": `iconsTab-module__iconsGridLoading__r5wNu`,
2287
+ "iconsControlsBackButton": `iconsTab-module__iconsControlsBackButton__lHXYH`,
2288
+ "iconsGridCheckbox": `iconsTab-module__iconsGridCheckbox__TebOL`,
2289
+ "iconsGridShowCheckboxes": `iconsTab-module__iconsGridShowCheckboxes__Lwxc6`,
2290
+ "iconsHeaderContainer": `iconsTab-module__iconsHeaderContainer__nlaKy`,
2291
+ "iconsHeaderContainerLeft": `iconsTab-module__iconsHeaderContainerLeft__sqO0_`,
2292
+ "iconsHeaderDivider": `iconsTab-module__iconsHeaderDivider__ujyPd`,
2293
+ "copyToFolderModalBody": `iconsTab-module__copyToFolderModalBody__AkxuH`,
2294
+ "copyToFolderModalLoadingOverlay": `iconsTab-module__copyToFolderModalLoadingOverlay__dd9RB`
2295
+ };
2296
+ module.exports = ___CSS_LOADER_EXPORT___;
2297
+
2298
+
2299
+ /***/ })
2300
+
2301
+ }]);
2302
+ //# sourceMappingURL=fm-icons-tab.0b3920cbbaa6c052568d.js.map