@magmonium/one 0.4.41 → 0.4.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fields/app_color.json +5 -0
- package/assets/fields/logo_glyph_paste.json +7 -0
- package/assets/fields/logo_glyph_upload.json +12 -0
- package/assets/forms/logo_glyph_input.json +13 -0
- package/assets/i18n/ar.json +8 -0
- package/assets/i18n/de.json +8 -0
- package/assets/i18n/en.json +8 -0
- package/assets/i18n/es.json +8 -0
- package/assets/i18n/fr.json +8 -0
- package/assets/i18n/hi.json +8 -0
- package/assets/i18n/it.json +8 -0
- package/assets/i18n/ja.json +8 -0
- package/assets/i18n/ko.json +8 -0
- package/assets/i18n/nl.json +8 -0
- package/assets/i18n/pl.json +8 -0
- package/assets/i18n/pt.json +8 -0
- package/assets/i18n/ru.json +8 -0
- package/assets/i18n/tr.json +8 -0
- package/assets/i18n/zh.json +8 -0
- package/assets/index.json +1 -1
- package/fesm2022/{magmonium-one-attribute-value-DCTXt4Sr.mjs → magmonium-one-attribute-value-C1lqou2L.mjs} +3 -3
- package/fesm2022/{magmonium-one-attribute-value-DCTXt4Sr.mjs.map → magmonium-one-attribute-value-C1lqou2L.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-base-checkbox-BNQAkyYU.mjs → magmonium-one-base-checkbox-CIxAiA4Q.mjs} +2 -2
- package/fesm2022/{magmonium-one-base-checkbox-BNQAkyYU.mjs.map → magmonium-one-base-checkbox-CIxAiA4Q.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-base-dropdown-DU4B4w7c.mjs → magmonium-one-base-dropdown-XpTWe4Ii.mjs} +10 -10
- package/fesm2022/{magmonium-one-base-dropdown-DU4B4w7c.mjs.map → magmonium-one-base-dropdown-XpTWe4Ii.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-base-input-BTxhUtYO.mjs → magmonium-one-base-input-C1Ek0Ezm.mjs} +2 -2
- package/fesm2022/{magmonium-one-base-input-BTxhUtYO.mjs.map → magmonium-one-base-input-C1Ek0Ezm.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-base-text-BCSqKmVs.mjs → magmonium-one-base-text-Di2V2ojp.mjs} +2 -2
- package/fesm2022/{magmonium-one-base-text-BCSqKmVs.mjs.map → magmonium-one-base-text-Di2V2ojp.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-button-BWB3ZKIj.mjs → magmonium-one-button-DZ4wCJgb.mjs} +11 -9
- package/fesm2022/{magmonium-one-button-BWB3ZKIj.mjs.map → magmonium-one-button-DZ4wCJgb.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-checkbox-D5-5WhJ-.mjs → magmonium-one-checkbox-R-hPZrCa.mjs} +5 -5
- package/fesm2022/{magmonium-one-checkbox-D5-5WhJ-.mjs.map → magmonium-one-checkbox-R-hPZrCa.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-color-utl-D86GGpz5.mjs → magmonium-one-color-utl-DI5p24iQ.mjs} +209 -6
- package/fesm2022/magmonium-one-color-utl-DI5p24iQ.mjs.map +1 -0
- package/fesm2022/{magmonium-one-directives-DePukAj8.mjs → magmonium-one-directives-B93p5bAL.mjs} +4 -4
- package/fesm2022/{magmonium-one-directives-DePukAj8.mjs.map → magmonium-one-directives-B93p5bAL.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-group-m41SX_fL.mjs → magmonium-one-group-B7YeUd1u.mjs} +7 -7
- package/fesm2022/{magmonium-one-group-m41SX_fL.mjs.map → magmonium-one-group-B7YeUd1u.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-header-D8CB9CBJ.mjs → magmonium-one-header-DUiBhPUP.mjs} +6 -5
- package/fesm2022/{magmonium-one-header-D8CB9CBJ.mjs.map → magmonium-one-header-DUiBhPUP.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-icon-BTPHGpEN.mjs → magmonium-one-icon-C3jwzbb2.mjs} +80 -9
- package/fesm2022/magmonium-one-icon-C3jwzbb2.mjs.map +1 -0
- package/fesm2022/{magmonium-one-image-editor-Dn0ACfH0.mjs → magmonium-one-image-editor-BRTk8i4O.mjs} +4 -4
- package/fesm2022/{magmonium-one-image-editor-Dn0ACfH0.mjs.map → magmonium-one-image-editor-BRTk8i4O.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-label-DjvJthAB.mjs → magmonium-one-label-D_rU82nD.mjs} +2 -2
- package/fesm2022/{magmonium-one-label-DjvJthAB.mjs.map → magmonium-one-label-D_rU82nD.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-m-ref-C8c4Vf1G.mjs → magmonium-one-m-ref-CEms7B6-.mjs} +2 -2
- package/fesm2022/{magmonium-one-m-ref-C8c4Vf1G.mjs.map → magmonium-one-m-ref-CEms7B6-.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-menu-EIfPlZ4E.mjs → magmonium-one-menu-cO34OcJc.mjs} +8 -7
- package/fesm2022/{magmonium-one-menu-EIfPlZ4E.mjs.map → magmonium-one-menu-cO34OcJc.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-multi-range-o57TiVJU.mjs → magmonium-one-multi-range-Bq3_3NHg.mjs} +3 -3
- package/fesm2022/{magmonium-one-multi-range-o57TiVJU.mjs.map → magmonium-one-multi-range-Bq3_3NHg.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-options-asset-EVsv0DL7.mjs → magmonium-one-options-asset-BMd7W0Mk.mjs} +2 -2
- package/fesm2022/{magmonium-one-options-asset-EVsv0DL7.mjs.map → magmonium-one-options-asset-BMd7W0Mk.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-otp-CE4L1RcG.mjs → magmonium-one-otp-V2tFztLx.mjs} +5 -5
- package/fesm2022/{magmonium-one-otp-CE4L1RcG.mjs.map → magmonium-one-otp-V2tFztLx.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-password-BjqYmT1s.mjs → magmonium-one-password-IdllPMUw.mjs} +6 -6
- package/fesm2022/{magmonium-one-password-BjqYmT1s.mjs.map → magmonium-one-password-IdllPMUw.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-radio-C2wOB_Nb.mjs → magmonium-one-radio-BAL3-3j5.mjs} +3 -3
- package/fesm2022/{magmonium-one-radio-C2wOB_Nb.mjs.map → magmonium-one-radio-BAL3-3j5.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-range-rgDe4O8u.mjs → magmonium-one-range-Cf7yUnhN.mjs} +4 -4
- package/fesm2022/{magmonium-one-range-rgDe4O8u.mjs.map → magmonium-one-range-Cf7yUnhN.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-selector-DeRIUUBA.mjs → magmonium-one-selector-DAEI_0JX.mjs} +4 -4
- package/fesm2022/{magmonium-one-selector-DeRIUUBA.mjs.map → magmonium-one-selector-DAEI_0JX.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-size-converter-C5fG_dgw.mjs → magmonium-one-size-converter-BOBD8nHy.mjs} +8 -1
- package/fesm2022/magmonium-one-size-converter-BOBD8nHy.mjs.map +1 -0
- package/fesm2022/{magmonium-one-text-BL-1lWST.mjs → magmonium-one-text-BnTkYLJe.mjs} +8 -7
- package/fesm2022/{magmonium-one-text-BL-1lWST.mjs.map → magmonium-one-text-BnTkYLJe.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-text-output-Ci93Hi9Y.mjs → magmonium-one-text-output-BZU61QIF.mjs} +4 -4
- package/fesm2022/{magmonium-one-text-output-Ci93Hi9Y.mjs.map → magmonium-one-text-output-BZU61QIF.mjs.map} +1 -1
- package/fesm2022/magmonium-one-theme-DYvNIWmo.mjs +1 -0
- package/fesm2022/{magmonium-one-toggle-BTK2lzqA.mjs → magmonium-one-toggle-V_YnZXx5.mjs} +3 -3
- package/fesm2022/{magmonium-one-toggle-BTK2lzqA.mjs.map → magmonium-one-toggle-V_YnZXx5.mjs.map} +1 -1
- package/fesm2022/magmonium-one.mjs +788 -185
- package/fesm2022/magmonium-one.mjs.map +1 -1
- package/package.json +1 -1
- package/types/magmonium-one.d.ts +355 -53
- package/fesm2022/magmonium-one-color-utl-D86GGpz5.mjs.map +0 -1
- package/fesm2022/magmonium-one-icon-BTPHGpEN.mjs.map +0 -1
- package/fesm2022/magmonium-one-size-converter-C5fG_dgw.mjs.map +0 -1
- package/fesm2022/magmonium-one-theme-CT4cWpe7.mjs +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"magmonium-one-color-utl-D86GGpz5.mjs","names":["map","switchMap"],"sources":["../../../../libs/one/src/lib/shared/lib/theme/api/theme-data.ts","../../../../libs/one/src/lib/shared/lib/theme/lib/theme-detector.ts","../../../../libs/one/src/lib/shared/lib/theme/type/state.ts","../../../../libs/one/src/lib/shared/lib/theme/lib/theme-store.ts","../../../../libs/one/src/lib/shared/functions/css/property-names.ts","../../../../libs/one/src/lib/shared/functions/color/parsers.ts","../../../../libs/one/src/lib/shared/functions/color/converters.ts","../../../../libs/one/src/lib/shared/functions/color/operations.ts","../../../../libs/one/src/lib/shared/lib/theme/lib/color-utl.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { catchError, forkJoin, map, of } from 'rxjs';\nimport { Theme, ThemeList } from '@magmonium/cli';\nimport { AssetStore } from '../../../stores/asset.store';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ThemeDataService {\n private readonly assetStore = inject(AssetStore);\n\n public fetchThemeList = (source: 'one' | 'host') =>\n this.assetStore\n .resolve<ThemeList>('theme', 'theme', source === 'one')\n .pipe(catchError(() => of(<ThemeList>[])));\n\n public fetchThemes = () =>\n forkJoin({\n one: this.fetchThemeList('one'),\n local: this.fetchThemeList('host'),\n }).pipe(\n map(({ one, local }) => {\n const themeMap: Record<string, Theme & { sources: string[] }> = {};\n\n const processList = (list: ThemeList, sourceKey: string) => {\n if (!list || !Array.isArray(list)) return;\n list.forEach((t) => {\n const name = t.name || t.fileName;\n if (name) {\n if (themeMap[name]) {\n if (!themeMap[name].sources.includes(sourceKey)) {\n themeMap[name].sources.push(sourceKey);\n }\n } else {\n themeMap[name] = { ...t, sources: [sourceKey] } as Theme & {\n sources: string[];\n };\n }\n }\n });\n };\n\n processList(one, 'one');\n processList(local, 'host');\n\n return themeMap;\n })\n );\n\n public fetchTheme = (theme: Theme, isOne = false) =>\n theme.fileName\n ? this.assetStore\n .resolve<Theme>('theme', theme.fileName, isOne)\n .pipe(map((data: Theme) => ({ ...theme, ...data })))\n : of(theme);\n}\n","import { Injectable, signal } from '@angular/core';\nimport { OsTheme } from '../type/state';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ThemeDetector {\n public readonly osTheme = signal<OsTheme>('dark');\n private mediaQueryList!: MediaQueryList;\n\n public onInit(): void {\n this.mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');\n this.osTheme.set(this.mediaQueryList.matches ? 'dark' : 'light');\n this.mediaQueryList.addEventListener('change', this.listener);\n }\n\n public onDestroy(): void {\n this.mediaQueryList.removeEventListener('change', this.listener);\n }\n\n private listener = (event: MediaQueryListEvent) => {\n this.osTheme.set(event.matches ? 'dark' : 'light');\n };\n}\n","import { Theme } from '@magmonium/cli';\n\nexport type OsTheme = 'light' | 'dark';\n\nexport type ThemeState = {\n themeMap: Record<string, Theme>;\n selected: string | undefined;\n userAdopted: true | undefined;\n // The theme the app declares it boots with — `theme:` on its\n // WebComponentConfig, read out of `app-wc.json` at bootstrap. Stands in for\n // the OS auto-match rather than for the person's own pick: `userAdopted`\n // still wins, and an app that declares nothing keeps the OS behaviour.\n configDefault: string | undefined;\n sources: string[];\n isReady: boolean;\n};\n\nexport const initialState: ThemeState = {\n themeMap: {},\n selected: 'light',\n userAdopted: undefined,\n configDefault: undefined,\n sources: [],\n isReady: false,\n};\n","import {\n patchState,\n signalStore,\n withComputed,\n withHooks,\n withMethods,\n withState,\n} from '@ngrx/signals';\nimport { computed, DOCUMENT, inject } from '@angular/core';\nimport { ThemeDataService } from '../api/theme-data';\nimport { rxMethod } from '@ngrx/signals/rxjs-interop';\nimport { forkJoin, of, pipe, tap, catchError } from 'rxjs';\nimport { switchMap, map } from 'rxjs/operators';\nimport { Theme } from '@magmonium/cli';\nimport { ThemeDetector } from './theme-detector';\nimport { initialState } from '../type/state';\nimport { ASSET_BASE_URL, ONE_ASSET_BASE_URL } from '../../../config/tokens';\n\nfunction toThemeCssVar(key: string): string {\n return '--m-' + key.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\n\nfunction applyThemeVars(\n colors: Record<string, string>,\n target: HTMLElement\n): void {\n Object.entries(colors).forEach(([key, value]) => {\n target.style.setProperty(toThemeCssVar(key), value);\n });\n}\n\nexport const ThemeStore = signalStore(\n { providedIn: 'root' },\n withState(initialState),\n withComputed((state, themeDetector = inject(ThemeDetector)) => {\n const osTheme = computed(themeDetector.osTheme);\n const theme = computed<Theme | undefined>(() => {\n const themeMap = state.themeMap();\n const selected = state.selected();\n return selected ? themeMap[selected] : undefined;\n });\n const color = computed(() => theme()?.color);\n return {\n theme,\n color,\n osTheme,\n };\n }),\n withMethods(\n (\n state,\n themeDataService = inject(ThemeDataService),\n document = inject(DOCUMENT),\n themeDetector = inject(ThemeDetector),\n oneAssetBaseUrl = inject(ONE_ASSET_BASE_URL, { optional: true }) ||\n '/assets/one',\n assetBaseUrl = inject(ASSET_BASE_URL, { optional: true }) || '/assets'\n ) => {\n const renderTheme = (colors: Record<string, string>) => {\n applyThemeVars(colors, document.documentElement);\n };\n\n const normalizeThemeSources = (\n themeMap: Record<string, Theme & { sources: string[] }>\n ) => {\n const normalized: Record<string, Theme & { sources: string[] }> = {};\n for (const [name, theme] of Object.entries(themeMap)) {\n normalized[name] = {\n ...theme,\n sources: theme.sources.map((s) =>\n s === 'one' ? oneAssetBaseUrl : s === 'host' ? assetBaseUrl : s\n ),\n };\n }\n return normalized;\n };\n\n const fetchAndMergeTheme = (themeName: string) => {\n const themeEntry = state.themeMap()[themeName] as\n | (Theme & { sources: string[] })\n | undefined;\n if (!themeEntry || !themeEntry.sources.length) return of(undefined);\n\n const requests = themeEntry.sources.map((source) =>\n themeDataService\n .fetchTheme(themeEntry, source === oneAssetBaseUrl)\n .pipe(catchError(() => of(undefined)))\n );\n\n return forkJoin(requests).pipe(\n map((results) => {\n const validResults = results.filter((r) => !!r) as Theme[];\n if (validResults.length === 0) return undefined;\n\n const mergedColor = validResults.reduce(\n (acc, curr) => ({\n ...acc,\n ...(curr.color || {}),\n }),\n {} as Record<string, unknown>\n );\n\n return {\n ...validResults[validResults.length - 1],\n color: mergedColor,\n sources: themeEntry.sources,\n } as Theme & { sources: string[] };\n })\n );\n };\n\n return {\n /**\n * Paints a set of DesignTokens straight onto the page without a theme\n * behind them. What a visual editor needs to show a theme it holds in\n * memory and has not written anywhere yet — every other path here\n * resolves a name against an asset first, and an unsaved theme has no\n * asset to resolve.\n */\n applyTheme(colors: Record<string, string>): void {\n renderTheme(colors);\n },\n /**\n * The theme the app declares it boots with (`theme:` on its\n * WebComponentConfig). Read out of `app-wc.json` after bootstrap, so it\n * lands either side of `init` finishing — hence both halves: it is\n * recorded for `init` to prefer, and applied now in case `init` has\n * already chosen the OS theme.\n *\n * Never overrides a person who has picked for themselves: `userAdopted`\n * is checked here the same way `init` checks it.\n */\n setConfigDefault(name: string | undefined): void {\n patchState(state, { configDefault: name });\n if (!name || state.userAdopted()) return;\n if (!state.themeMap()[name] || state.selected() === name) return;\n patchState(state, { selected: name });\n fetchAndMergeTheme(name).subscribe((fullTheme) => {\n if (!fullTheme?.name) return;\n patchState(state, {\n themeMap: { ...state.themeMap(), [fullTheme.name]: fullTheme },\n isReady: true,\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n });\n },\n setTheme: rxMethod<string | undefined>(\n pipe(\n tap((selected) => patchState(state, { selected })),\n switchMap((selected) => {\n if (!selected) return of(undefined);\n return fetchAndMergeTheme(selected);\n }),\n tap((fullTheme: (Theme & { sources: string[] }) | undefined) => {\n if (fullTheme && fullTheme.name) {\n patchState(state, {\n themeMap: {\n ...state.themeMap(),\n [fullTheme.name]: fullTheme as Theme,\n },\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n }\n })\n )\n ),\n addSource: rxMethod<string>(\n pipe(\n tap((baseUrl) => {\n const sources = state.sources();\n if (!sources.includes(baseUrl)) {\n patchState(state, { sources: [...sources, baseUrl] });\n }\n }),\n switchMap((baseUrl) => {\n const source = baseUrl === oneAssetBaseUrl ? 'one' : 'host';\n return themeDataService\n .fetchThemeList(source)\n .pipe(map((list) => ({ list, baseUrl })));\n }),\n tap(({ list, baseUrl }) => {\n const themeMap = { ...state.themeMap() } as Record<\n string,\n Theme & { sources: string[] }\n >;\n list.forEach((t) => {\n const name = t.name || t.fileName;\n if (name) {\n if (themeMap[name]) {\n if (!themeMap[name].sources.includes(baseUrl)) {\n themeMap[name].sources.push(baseUrl);\n }\n } else {\n themeMap[name] = { ...t, sources: [baseUrl] } as Theme & {\n sources: string[];\n };\n }\n }\n });\n patchState(state, {\n themeMap: themeMap as Record<string, Theme>,\n });\n\n const selected = state.selected();\n if (selected && themeMap[selected]?.sources.includes(baseUrl)) {\n fetchAndMergeTheme(selected).subscribe(\n (fullTheme: (Theme & { sources: string[] }) | undefined) => {\n if (fullTheme && fullTheme.name) {\n patchState(state, {\n themeMap: {\n ...state.themeMap(),\n [fullTheme.name]: fullTheme as Theme,\n },\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n }\n }\n );\n }\n })\n )\n ),\n init$: () => {\n return themeDataService.fetchThemes().pipe(\n map((themeMap) =>\n normalizeThemeSources(\n themeMap as Record<string, Theme & { sources: string[] }>\n )\n ),\n tap((themeMap) => {\n patchState(state, {\n themeMap: themeMap as Record<string, Theme>,\n });\n })\n );\n },\n init: rxMethod<void>(\n pipe(\n switchMap(() => themeDataService.fetchThemes()),\n map((map) =>\n normalizeThemeSources(\n map as Record<string, Theme & { sources: string[] }>\n )\n ),\n tap((map) =>\n patchState(state, { themeMap: map as Record<string, Theme> })\n ),\n switchMap((map) => {\n if (state.userAdopted()) return of(undefined);\n // The app's own declaration stands in for the OS auto-match, and\n // only for it — a name naming nothing falls through to the OS\n // rather than leaving the app unthemed.\n const declared = state.configDefault();\n const preferred = themeDetector.osTheme();\n const name =\n declared && map[declared]\n ? declared\n : preferred && map[preferred]\n ? preferred\n : Object.keys(map)[0];\n if (!name) return of(undefined);\n patchState(state, { selected: name });\n return fetchAndMergeTheme(name);\n }),\n tap((fullTheme: (Theme & { sources: string[] }) | undefined) => {\n if (fullTheme && fullTheme.name) {\n patchState(state, {\n themeMap: {\n ...state.themeMap(),\n [fullTheme.name]: fullTheme as Theme,\n },\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n patchState(state, { isReady: true });\n }\n })\n )\n ),\n };\n }\n ),\n withHooks((store) => {\n const themeDetector = inject(ThemeDetector);\n return {\n onInit() {\n themeDetector.onInit();\n\n store.init$().subscribe((map) => {\n if (!store.userAdopted()) {\n const declared = store.configDefault();\n const preferred = store.osTheme();\n const name =\n declared && map[declared]\n ? declared\n : preferred && map[preferred]\n ? preferred\n : Object.keys(map)[0];\n if (name) store.setTheme(name);\n }\n });\n },\n onDestroy() {\n themeDetector.onDestroy();\n },\n };\n })\n);\n","export type ColorPropertyType = 'color' | 'color-contrast' | 'color-opposite';\n\nexport function derivePropertyName(\n inputString: string,\n type: ColorPropertyType\n): string {\n const tagName = inputString.toLowerCase();\n\n const match = tagName.match(/^m(?:-one)?-(.+)$/);\n\n if (match) {\n const componentName = match[1];\n return `--m-${componentName}-${type}`;\n } else {\n return `--m-${type}`;\n }\n}\n\nexport function setProperty(\n element: HTMLElement,\n key: string,\n value: string | null\n) {\n element.style.setProperty(key, value);\n}\n\nexport function getProperty(element: HTMLElement, key: string) {\n return getComputedStyle(element).getPropertyValue(key);\n}\n","import { RgbColor, HslColor } from './types';\n\nexport function parseColor(color: string): RgbColor | null {\n const trimmedColor = color.trim();\n\n // Handle hex colors\n if (trimmedColor.startsWith('#')) {\n return hexToRgb(trimmedColor);\n }\n\n // Handle rgb() colors\n const rgbMatch = trimmedColor.match(\n /rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/\n );\n if (rgbMatch) {\n return {\n r: parseInt(rgbMatch[1], 10),\n g: parseInt(rgbMatch[2], 10),\n b: parseInt(rgbMatch[3], 10),\n };\n }\n\n // Handle rgba() colors (ignore alpha)\n const rgbaMatch = trimmedColor.match(\n /rgba\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*[\\d.]+\\s*\\)/\n );\n if (rgbaMatch) {\n return {\n r: parseInt(rgbaMatch[1], 10),\n g: parseInt(rgbaMatch[2], 10),\n b: parseInt(rgbaMatch[3], 10),\n };\n }\n\n // Handle hsl() colors\n const hslMatch = trimmedColor.match(\n /hsl\\(\\s*(\\d+)\\s*,\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*\\)/\n );\n if (hslMatch) {\n const hsl: HslColor = {\n h: parseInt(hslMatch[1], 10),\n s: parseInt(hslMatch[2], 10),\n l: parseInt(hslMatch[3], 10),\n };\n return hslToRgb(hsl);\n }\n\n return null;\n}\n\nexport function hexToRgb(hex: string): RgbColor | null {\n const cleanHex = hex.replace('#', '');\n\n if (cleanHex.length === 3) {\n // Short hex format (e.g., #fff)\n return {\n r: parseInt(cleanHex[0] + cleanHex[0], 16),\n g: parseInt(cleanHex[1] + cleanHex[1], 16),\n b: parseInt(cleanHex[2] + cleanHex[2], 16),\n };\n } else if (cleanHex.length === 6) {\n // Long hex format (e.g., #ffffff)\n return {\n r: parseInt(cleanHex.slice(0, 2), 16),\n g: parseInt(cleanHex.slice(2, 4), 16),\n b: parseInt(cleanHex.slice(4, 6), 16),\n };\n }\n\n return null;\n}\n\nexport function hslToRgb(hsl: HslColor): RgbColor {\n // Normalize HSL values - handle both integer (0-360, 0-100, 0-100) and float inputs\n const h = (hsl.h % 360) / 360; // Ensure hue is in 0-1 range\n const s = Math.max(0, Math.min(100, hsl.s)) / 100; // Clamp saturation to 0-100, then normalize\n const l = Math.max(0, Math.min(100, hsl.l)) / 100; // Clamp lightness to 0-100, then normalize\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return {\n r: Math.round(Math.max(0, Math.min(255, r * 255))),\n g: Math.round(Math.max(0, Math.min(255, g * 255))),\n b: Math.round(Math.max(0, Math.min(255, b * 255))),\n };\n}\n","import { RgbColor, HslColor } from './types';\n\nexport function rgbToHex(rgb: RgbColor): string {\n const toHex = (n: number) => {\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;\n}\n\nexport function rgbToHsl(rgb: RgbColor): HslColor {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return {\n h: h * 360,\n s: s * 100,\n l: l * 100,\n };\n}\n\nexport function calculateLuminance(rgb: RgbColor): number {\n // Convert to linear RGB\n const toLinear = (c: number): number => {\n const normalized = c / 255;\n return normalized <= 0.03928\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n };\n\n const r = toLinear(rgb.r);\n const g = toLinear(rgb.g);\n const b = toLinear(rgb.b);\n\n // Calculate relative luminance using WCAG formula\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n","import { parseColor } from './parsers';\nimport { rgbToHex, rgbToHsl, calculateLuminance } from './converters';\nimport { hslToRgb } from './parsers';\n\nexport function deriveContrastColor(color: string): string {\n try {\n // Input validation\n if (!color || color.trim() === '') {\n return '#ffffff'; // fallback to white for invalid input\n }\n\n const rgb = parseColor(color);\n if (!rgb) {\n return '#ffffff'; // fallback to white if parsing fails\n }\n\n // Validate RGB values\n if (\n rgb.r < 0 ||\n rgb.r > 255 ||\n rgb.g < 0 ||\n rgb.g > 255 ||\n rgb.b < 0 ||\n rgb.b > 255\n ) {\n return '#ffffff'; // fallback to white for invalid RGB values\n }\n\n // Calculate relative luminance using WCAG formula\n const luminance = calculateLuminance(rgb);\n\n // WCAG contrast ratio threshold: use white text on dark backgrounds, black on light\n return luminance > 0.5 ? '#000000' : '#ffffff';\n } catch (error) {\n console.warn('Error in deriveContrastColor:', error);\n return '#ffffff'; // fallback to white on error\n }\n}\n\nexport function deriveOppositeColor(color: string): string {\n try {\n // Input validation\n if (!color || color.trim() === '') {\n return color; // return original for invalid input\n }\n\n const rgb = parseColor(color);\n if (!rgb) {\n return color; // return original if parsing fails\n }\n\n // Validate RGB values\n if (\n rgb.r < 0 ||\n rgb.r > 255 ||\n rgb.g < 0 ||\n rgb.g > 255 ||\n rgb.b < 0 ||\n rgb.b > 255\n ) {\n return color; // return original if invalid RGB values\n }\n\n const hsl = rgbToHsl(rgb);\n\n // Rotate hue 180 degrees for complementary color\n // Handle the floating-point hue value properly\n const oppositeHsl = {\n h: (hsl.h + 180) % 360,\n s: hsl.s,\n l: hsl.l,\n };\n\n const oppositeRgb = hslToRgb(oppositeHsl);\n return rgbToHex(oppositeRgb);\n } catch (error) {\n console.warn('Error in deriveOppositeColor:', error);\n return color; // return original on error\n }\n}\n","import { ThemeColor } from '@magmonium/cli';\nimport {\n ColorPropertyType,\n derivePropertyName,\n} from '../../../functions/css/property-names';\nimport {\n deriveContrastColor,\n deriveOppositeColor,\n} from '../../../functions/color/operations';\n\nconst colorPalletMap = new Map();\n\nexport interface ColorPallet {\n color: string;\n contrastColor: string;\n oppositeColor: string;\n}\n\nexport function resolvePallet(\n currentColor: string | keyof ThemeColor,\n themeColors?: ThemeColor\n): ColorPallet {\n // An unset colour is `mm` *before* the theme lookup, not after: falling back\n // afterwards leaves the literal key `mm` as the resolved colour, which is not\n // a CSS colour — the element then keeps whatever it painted last, and picking\n // `default` in a colour dropdown reads as the change not landing.\n const key = (currentColor || 'mm') as keyof ThemeColor;\n let color = (themeColors?.[key] ?? key) as string;\n\n // Prepend # if it's a hex code without the hash\n if (/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(color)) {\n color = `#${color}`;\n }\n\n const savedPallet = colorPalletMap.get(color);\n if (savedPallet) {\n return savedPallet;\n }\n const pallet = {\n color,\n contrastColor: deriveContrastColor(color),\n oppositeColor: deriveOppositeColor(color),\n };\n colorPalletMap.set(color, pallet);\n return pallet;\n}\n\nexport function applyColorsToElement(\n inputColor: keyof ThemeColor | string = 'mm',\n themeColors: ThemeColor | undefined,\n element: HTMLElement\n): ColorPallet | undefined {\n const pallet = resolvePallet(inputColor, themeColors),\n { color, contrastColor, oppositeColor } = pallet;\n \n const colorProp = derivePropertyName(element.tagName, 'color');\n const contrastProp = derivePropertyName(element.tagName, 'color-contrast');\n const oppositeProp = derivePropertyName(element.tagName, 'color-opposite');\n\n element.style.setProperty(colorProp, color);\n element.style.setProperty(contrastProp, contrastColor);\n element.style.setProperty(oppositeProp, oppositeColor);\n\n return pallet;\n}\n\nexport function addColorProperty(\n key: ColorPropertyType,\n value: string,\n element: HTMLElement\n): void {\n const inputString = element.tagName;\n element.style.setProperty(derivePropertyName(inputString, key), value);\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"magmonium-one-icon-BTPHGpEN.mjs","names":["catchError"],"sources":["../../../../libs/one/src/lib/shared/ui/icon/type/magmonium.ts","../../../../libs/one/src/lib/shared/ui/icon/model/shared-icons.ts","../../../../libs/one/src/lib/shared/ui/icon/lib/lib-icon.ts","../../../../libs/one/src/lib/shared/config/size-context.token.ts","../../../../libs/one/src/lib/shared/ui/icon/ui/icon.ts","../../../../libs/one/src/lib/shared/ui/icon/lib/custom-icon.ts","../../../../libs/one/src/lib/shared/ui/icon/ui/custom-icon.ts","../../../../libs/one/src/lib/shared/ui/icon/ui/custom-icon-edit.ts"],"sourcesContent":["export const MAGMONIUM = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-15 -15 120 165\">\n <g>\n <path fill=\"#color\" style=\"opacity: 0.7;\" d=\"M5 5 L5 65 L85 65 Z\" />\n <path fill=\"#color\" style=\"opacity: 0.3;\" d=\"M85 5 L5 65 L85 65 Z\" />\n </g>\n <g>\n <path fill=\"#color\" style=\"opacity: 0.3;\" d=\"M5 70 L85 70 L5 130 Z\" />\n <path fill=\"#color\" style=\"opacity: 0.7;\" d=\"M85 70 L5 70 L85 130 Z\" />\n </g>\n </svg>\n `;\n","// AUTO-GENERATED by assets:compile — do not edit manually\nexport const SHARED_ICONS = [\n 'accordion_chevron',\n 'account_balance_wallet',\n 'activity',\n 'add-image',\n 'adjust',\n 'alert-circle',\n 'analytics',\n 'apps',\n 'arrow-down',\n 'arrow-left',\n 'arrow-left-right',\n 'arrow-right',\n 'arrow-up',\n 'arrow_back',\n 'bell',\n 'bold',\n 'books',\n 'calendar',\n 'calendar-open',\n 'camera',\n 'chat',\n 'check',\n 'chevron-down',\n 'chevron-left',\n 'chevron-right',\n 'chevron-up',\n 'chevron_left',\n 'chevrons-down',\n 'chevrons-left',\n 'chevrons-right',\n 'chevrons-up',\n 'clipboard',\n 'code',\n 'coins',\n 'color-picker',\n 'copy',\n 'copyright',\n 'corner-left-up',\n 'currency_exchange',\n 'dot',\n 'download',\n 'ellipsis-vertical',\n 'exclamation-triangle',\n 'eye',\n 'eye_close',\n 'file-code',\n 'file-data',\n 'file-image',\n 'file-markup',\n 'file-style',\n 'file-text',\n 'fixed',\n 'flower',\n 'folder',\n 'games',\n 'gear',\n 'heading',\n 'heart',\n 'heart_filled',\n 'help',\n 'hero',\n 'info',\n 'install',\n 'instrument',\n 'investments',\n 'italic',\n 'language',\n 'layers',\n 'layouts',\n 'link',\n 'link-broken',\n 'list',\n 'loading',\n 'loading-bars',\n 'loading-dots',\n 'loading-logo',\n 'loading-pulse',\n 'location',\n 'lock',\n 'logo',\n 'magazines',\n 'mail',\n 'menu',\n 'mic',\n 'minus',\n 'monitor',\n 'more',\n 'notification',\n 'notification_off',\n 'open',\n 'pause',\n 'pencil',\n 'play',\n 'plus',\n 'posts',\n 'quote',\n 'redo',\n 'reload',\n 'reset',\n 'save',\n 'scissors',\n 'search',\n 'section',\n 'security',\n 'settings',\n 'shield',\n 'smartphone',\n 'sort-alpha-asc',\n 'sort-alpha-desc',\n 'sparkles',\n 'square',\n 'star',\n 'store',\n 'strategies',\n 'strikethrough',\n 'sun',\n 'table',\n 'tablet',\n 'target',\n 'theme',\n 'trash',\n 'trash-2',\n 'trending-down',\n 'trending-up',\n 'undo',\n 'user',\n 'users',\n 'wallet_manager',\n 'wallet_owner',\n 'wallet_shareholder',\n 'wand',\n 'wifi',\n 'x',\n 'zap',\n];\n","import { Icon, MAGMONIUM } from '../type/icon';\nimport { ElementRef } from '@angular/core';\nimport { SHARED_ICONS } from '../model/shared-icons';\nexport { SHARED_ICONS };\n\nexport function isOneIcon(element: ElementRef<HTMLElement>, config?: Icon) {\n if (typeof config?.one !== 'undefined') {\n return !!config.one;\n }\n\n // cast SHARED_ICONS to a generic string array for runtime includes check\n if (config?.name && (SHARED_ICONS as readonly string[]).includes(config.name)) {\n return true;\n }\n\n const tagName = element.nativeElement.tagName;\n return tagName === 'M-ONE-ICON';\n}\n\nfunction textToSvg(str = MAGMONIUM, color: string): string {\n if (typeof str !== 'string') return str as unknown as string;\n return str.replace(/#color/g, color).replace(/currentColor/g, color);\n}\n\nexport function svgElementFromString(str: string, color: string): SVGElement {\n const parser = new DOMParser();\n const doc = parser.parseFromString(textToSvg(str, color), 'image/svg+xml');\n const svg = doc.documentElement;\n\n if (svg && svg.nodeName === 'svg') {\n return svg as unknown as SVGElement;\n }\n\n const errorSvg = parser.parseFromString(textToSvg(MAGMONIUM, color), 'image/svg+xml');\n return errorSvg.documentElement as unknown as SVGElement;\n}\n","import { inject, InjectionToken, Provider, Signal, Type } from '@angular/core';\nimport { Size } from '../enum/scaling/size';\n\n/**\n * The Size in force for a subtree. Provided by the only components that may\n * declare one — Section, ButtonGroup, and the markup-composed SectionButtonGroup\n * (the last two are one seat, ADR 0008) — and injected `{ optional: true }` by\n * each of them (so a declarer falls back to the nearest one above it) and by\n * the few primitives whose size is a box dimension rather than a font size.\n *\n * Most components need nothing: a declarer also sets `font-size` on its own\n * host, so anything measured in `em` follows through ordinary CSS inheritance.\n * The token exists for what inheritance cannot do — a ButtonGroup or\n * SectionButtonGroup overriding its Section, and Icon sizing a square glyph.\n * See ADR 0008.\n */\nexport interface SizeContext {\n readonly size: Signal<Size>;\n}\n\nexport const SIZE_CONTEXT = new InjectionToken<SizeContext>('SIZE_CONTEXT');\n\nexport interface SizeDeclarer {\n readonly resolvedSize: Signal<Size>;\n}\n\n/**\n * Publishes a declarer's resolved Size to its subtree. Goes in `providers` and\n * never `viewProviders`: a Section's Cols and a ButtonGroup's Buttons are\n * projected content, which only `providers` reaches.\n */\nexport function provideSizeContext(\n declarer: Type<SizeDeclarer>\n): Provider {\n return {\n provide: SIZE_CONTEXT,\n useFactory: (): SizeContext => ({ size: inject(declarer).resolvedSize }),\n };\n}\n\n/**\n * The Size in force above a declarer. `skipSelf` because a declarer provides\n * SIZE_CONTEXT itself, and injecting its own provider would be circular — what\n * it wants is the nearest declarer *above* it, so that a Section with no Size\n * of its own takes its parent Section's and a ButtonGroup takes its Section's.\n */\nexport function injectParentSize(): SizeContext | null {\n return inject(SIZE_CONTEXT, { optional: true, skipSelf: true });\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n inject,\n input,\n model,\n untracked,\n} from '@angular/core';\nimport { Icon, MAGMONIUM } from '../type/icon';\nimport { isOneIcon, svgElementFromString } from '../lib/lib-icon';\nimport { SIZE_CONTEXT } from '../../../config/size-context.token';\nimport { resolveIconSize } from '../../../functions/size/size-converter';\nimport { AssetStore } from '../../../stores/asset.store';\nimport { HttpService } from '../../../services/http';\nimport { rxResource } from '@angular/core/rxjs-interop';\nimport { catchError } from 'rxjs/operators';\nimport { of } from 'rxjs';\nimport { applyColorsToElement, ThemeStore } from '../../../lib/theme';\nimport { ICON_SOURCE } from '../../../config/tokens';\n\n@Component({\n selector: 'm-icon, m-one-icon',\n template: `<ng-content></ng-content>`,\n styleUrls: ['./icon.sass'],\n host: {\n '[class.has-color]': 'resolvedConfig()?.color',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IconComponent {\n // Kept for the callers that hand an Icon a whole object rather than write it\n // out — a Button naming its own glyph, a SectionFormItem passing a Field's.\n config = model<Icon | undefined>(undefined);\n\n // `name` is the SVG's filename in `mag_assets/icons/`, not a config asset:\n // an Icon resolves artwork, so it is the one primitive whose name points at\n // a picture rather than at a description of itself (ADR 0010). `size` is a\n // free length (number → em), not a Size — Size stays on Section / ButtonGroup\n // (ADR 0008); set here only to overwrite the box SIZE_CONTEXT would give.\n readonly name = input<string | undefined>();\n readonly color = input<string | undefined>();\n readonly size = input<number | string | undefined>();\n readonly one = input<boolean | undefined>();\n readonly baseUrl = input<string | undefined>();\n readonly remote = input<string | undefined>();\n\n // Attributes win over the bound object, and an omitted one leaves the\n // object's key standing rather than blanking it.\n protected readonly resolvedConfig = computed<Icon | undefined>(() => {\n const config = this.config();\n const overrides: Icon = {};\n const name = this.name();\n if (name !== undefined) overrides.name = name;\n const color = this.color();\n if (color !== undefined) overrides.color = color;\n const one = this.one();\n if (one !== undefined) overrides.one = one;\n const baseUrl = this.baseUrl();\n if (baseUrl !== undefined) overrides.baseUrl = baseUrl;\n const remote = this.remote();\n if (remote !== undefined) overrides.remote = remote;\n if (!config && !Object.keys(overrides).length) return undefined;\n return { ...config, ...overrides };\n });\n\n private readonly elementRef = inject(ElementRef);\n // Icon sizes a square glyph through width/height, which no amount of\n // inherited font-size can set — so it is one of the few primitives that\n // reads the Size in force directly (ADR 0008).\n private readonly sizeContext = inject(SIZE_CONTEXT, { optional: true });\n private readonly assetStore = inject(AssetStore);\n private readonly http = inject(HttpService);\n private currentSvgElement: SVGElement | null = null;\n private readonly themeStore = inject(ThemeStore);\n private readonly isOneIcon = computed(() =>\n isOneIcon(this.elementRef, this.resolvedConfig())\n );\n private readonly remoteBaseUrl = computed<string | undefined>(() => {\n const remoteId = this.resolvedConfig()?.remote;\n return remoteId ? this.http.buildWcAssetBaseUrl(remoteId) : undefined;\n });\n\n // Icons supplied by name from memory (e.g. a visual editor's unsaved glyphs).\n // Read as a signal rather than through the resource below so that changing the\n // markup under an unchanged name repaints every icon already using it.\n private readonly iconSource = inject(ICON_SOURCE, { optional: true });\n private readonly inlineSvg = computed(() => {\n const name = this.resolvedConfig()?.name;\n return name ? this.iconSource?.()?.[name] : undefined;\n });\n\n private readonly text = rxResource({\n params: computed(\n () => ({\n name: this.resolvedConfig()?.name,\n isOneIcon: untracked(() => this.isOneIcon()),\n remoteBaseUrl: this.remoteBaseUrl(),\n }),\n { equal: (a, b) => a?.name === b?.name && a?.remoteBaseUrl === b?.remoteBaseUrl }\n ),\n stream: ({ params: { name, isOneIcon, remoteBaseUrl } }) => {\n if (!name) return untracked(() =>\n this.assetStore.resolve<string>('icons', 'logo', true).pipe(catchError(() => of(MAGMONIUM)))\n );\n // Skips the request entirely for an in-memory glyph — there is no asset\n // behind it, so fetching only ever produces a 404 and the fallback logo.\n const inline = untracked(() => this.inlineSvg());\n if (inline) return of(inline);\n return untracked(() =>\n this.assetStore\n .resolve<string>('icons', name, isOneIcon, remoteBaseUrl)\n .pipe(catchError(() => of(MAGMONIUM)))\n );\n },\n });\n\n private readonly pallet = computed(() =>\n applyColorsToElement(\n this.resolvedConfig()?.color ?? this.themeStore.color()?.mm ?? '#fff',\n this.themeStore.color(),\n this.elementRef.nativeElement\n )\n );\n\n constructor() {\n effect(this.updateElement);\n effect(this.applySize);\n }\n\n private readonly applySize = (): void => {\n this.elementRef.nativeElement.style.setProperty(\n '--m-icon-size',\n resolveIconSize(this.size(), this.sizeContext?.size())\n );\n };\n\n private readonly updateElement = (): void => {\n const element = this.elementRef.nativeElement;\n if (this.currentSvgElement) {\n this.currentSvgElement.remove();\n this.currentSvgElement = null;\n }\n const svg = svgElementFromString(\n this.inlineSvg() ?? (this.text.value() as string),\n this.pallet()?.color ?? this.themeStore.color()?.mm ?? '#fff'\n );\n if (!svg) return;\n this.currentSvgElement = svg;\n svg.removeAttribute('width');\n svg.removeAttribute('height');\n svg.style.width = 'var(--m-icon-size, 1em)';\n svg.style.height = 'var(--m-icon-size, 1em)';\n svg.style.flexShrink = '0';\n svg.removeAttribute('stroke-width');\n svg.style.setProperty('stroke-width', '2px');\n svg.querySelectorAll('*').forEach((el) => {\n el.removeAttribute('stroke-width');\n if (el instanceof HTMLElement || el instanceof SVGElement) {\n el.style.removeProperty('stroke-width');\n }\n });\n element.prepend(svg);\n };\n}\n","import { CustomIcon } from '../type/icon';\nimport { ThemeColor } from '@magmonium/cli';\n\nfunction genColor(colors: ThemeColor, color: string) {\n return colors[color as keyof ThemeColor] ?? color;\n}\n\nexport function isLargeImage(svg: CustomIcon): boolean {\n const width = svg.width || 0;\n const height = svg.height || 0;\n const area = width * height;\n return area > 2000000 || width > 2000 || height > 2000;\n}\n\nexport function genViewPort(svg: CustomIcon | undefined) {\n if (!svg) return '0 0 0 0';\n const width = svg.width || 0;\n const height = svg.height || 0;\n return `0 0 ${width} ${height}`;\n}\n\nexport function computedFillColor(\n svg: CustomIcon,\n colors?: ThemeColor,\n fillColor?: string\n) {\n const { lineColor, backgroundColor, invertSvg } = svg.edit;\n if (!colors) {\n return fillColor ?? backgroundColor;\n }\n return genColor(\n colors,\n invertSvg ? lineColor : (fillColor ?? backgroundColor)\n );\n}\n\nexport function computeLineColor(\n svg: CustomIcon,\n colors?: ThemeColor,\n strokeColor?: string\n) {\n const { lineColor, backgroundColor, invertSvg } = svg.edit;\n if (!colors) {\n return strokeColor ?? lineColor;\n }\n return genColor(\n colors,\n invertSvg ? backgroundColor : (strokeColor ?? lineColor)\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { CustomIcon } from '../type/icon';\nimport {\n computedFillColor,\n computeLineColor,\n genViewPort,\n isLargeImage,\n} from '../lib/custom-icon';\nimport { ThemeStore } from '../../../lib/theme';\n\n@Component({\n selector: 'm-custom-icon',\n template: `\n <!-- eslint-disable local/no-raw-svg -->\n @if (svg(); as svg) {\n <svg\n xmlns=\"http:/www.w3.org/2000/svg\"\n [attr.viewBox]=\"viewBox()\"\n [attr.width]=\"svg.width\"\n [attr.height]=\"svg.height\"\n preserveAspectRatio=\"xMidYMid meet\"\n >\n @if (_fillColor(); as fillColor) {\n <rect\n [attr.width]=\"svg.width\"\n [attr.height]=\"svg.height\"\n [attr.fill]=\"fillColor\"\n />\n }\n @if (_strokeColor(); as stroke) {\n @for (path of svg?.paths; track $index) {\n <path\n class=\"svg-path\"\n [attr.d]=\"path\"\n [attr.fill]=\"'none'\"\n [attr.stroke]=\"stroke\"\n [attr.stroke-linecap]=\"svg?.edit?.linecap\"\n [attr.stroke-linejoin]=\"svg?.edit?.linejoin\"\n [attr.stroke-width]=\"svg.edit.strokeWidth\"\n [attr.vector-effect]=\"vectorEffect()\"\n />\n }\n }\n </svg>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CustomIconClass {\n svg = input.required<CustomIcon>();\n strokeColor = input<string | undefined>(undefined);\n fillColor = input<string | undefined>(undefined);\n strokeWidth = input<number | undefined>(undefined);\n\n protected readonly viewBox = computed(() => genViewPort(this.svg()));\n protected readonly vectorEffect = computed(() => {\n return isLargeImage(this.svg()) ? 'non-scaling-stroke' : null;\n });\n private readonly themeStore = inject(ThemeStore);\n protected readonly _fillColor = computed(() =>\n computedFillColor(this.svg(), this.themeStore.color(), this.fillColor())\n );\n protected readonly _strokeColor = computed(() => {\n return computeLineColor(\n this.svg(),\n this.themeStore.color(),\n this.strokeColor()\n );\n });\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n HostListener,\n computed,\n inject,\n input,\n model,\n} from '@angular/core';\nimport { CustomIcon } from '../type/icon';\nimport {\n computedFillColor,\n computeLineColor,\n genViewPort,\n isLargeImage,\n} from '../lib/custom-icon';\nimport { ThemeStore } from '../../../lib/theme';\n\n@Component({\n selector: 'm-custom-icon-edit',\n imports: [],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- eslint-disable local/no-raw-svg -->\n @if (svg(); as svg) {\n <svg\n xmlns=\"http:/www.w3.org/2000/svg\"\n [attr.viewBox]=\"_viewBox()\"\n [attr.width]=\"svg.width\"\n [attr.height]=\"svg.height\"\n preserveAspectRatio=\"xMidYMid meet\"\n >\n @if (_fillColor(); as fillColor) {\n <rect\n [attr.width]=\"svg.width\"\n [attr.height]=\"svg.height\"\n [attr.fill]=\"fillColor\"\n />\n }\n @for (path of svg.paths; track $index) {\n <path\n class=\"svg-path\"\n (click)=\"_onPathClick($index)\"\n [class.interactive]=\"svg.edit.canInteract\"\n [class.selected]=\"_selectedIndex.includes($index)\"\n [attr.d]=\"path\"\n [attr.fill]=\"'none'\"\n [attr.stroke]=\"_strokeColor()\"\n [attr.stroke-linecap]=\"svg.edit.linecap\"\n [attr.stroke-linejoin]=\"svg.edit.linejoin\"\n [attr.stroke-width]=\"svg.edit.strokeWidth\"\n [attr.vector-effect]=\"_vectorEffect()\"\n />\n }\n </svg>\n }\n `,\n styleUrl: './custom-icon-edit.sass',\n})\nexport class CustomIconEditComponent {\n svg = model<CustomIcon | undefined>(undefined);\n strokeColor = input<string | undefined>(undefined);\n fillColor = input<string | undefined>(undefined);\n\n private readonly themeStore = inject(ThemeStore);\n\n @HostListener('window:keydown', ['$event'])\n onKeydown(event: KeyboardEvent) {\n if (!this.svg()?.edit?.canInteract || this._selectedIndex.length === 0) {\n return;\n }\n if (event.key === ' ') {\n event.preventDefault();\n this.deleteSelectedPaths();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n this._selectedIndex = [];\n }\n }\n\n protected readonly _viewBox = computed(() => genViewPort(this.svg()));\n\n protected readonly _vectorEffect = computed(() => {\n const svg = this.svg();\n return svg && isLargeImage(svg) ? 'non-scaling-stroke' : null;\n });\n\n protected readonly _fillColor = computed(() => {\n const svg = this.svg();\n if (!svg) return undefined;\n return computedFillColor(svg, this.themeStore.color(), this.fillColor());\n });\n\n protected readonly _strokeColor = computed(() => {\n const svg = this.svg();\n if (!svg) return undefined;\n return computeLineColor(svg, this.themeStore.color(), this.strokeColor());\n });\n\n protected readonly _onPathClick = (index: number) => {\n if (!this.svg()?.edit?.canInteract) return;\n this._selectedIndex = Array.from(new Set([...this._selectedIndex, index]));\n };\n\n readonly deleteSelectedPaths = () => {\n this.svg.update((prev) => {\n if (!prev) return prev;\n return {\n ...prev,\n paths: prev.paths.filter((_, i) => !this._selectedIndex.includes(i)),\n };\n });\n this._selectedIndex = [];\n };\n\n protected _selectedIndex: number[] = [];\n}\n"],"mappings":";;;;;;;;AAAA,MAAa,YAAY;;;;;;;;;;;;ACCzB,MAAa,eAAe;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;ACnID,SAAgB,UAAU,SAAkC,QAAa;CACvE,IAAI,OAAO,QAAQ,QAAQ,aACzB,OAAO,CAAC,CAAC,OAAO;CAIlB,IAAI,QAAQ,QAAS,aAAmC,SAAS,OAAO,IAAI,GAC1E,OAAO;CAIT,OADgB,QAAQ,cAAc,YACnB;AACrB;AAEA,SAAS,UAAU,MAAM,WAAW,OAAa;CAC/C,IAAI,OAAO,QAAQ,UAAU,OAAO;CACpC,OAAO,IAAI,QAAQ,WAAW,KAAK,CAAC,CAAC,QAAQ,iBAAiB,KAAK;AACrE;AAEA,SAAgB,qBAAqB,KAAa,OAAa;CAC7D,MAAM,SAAS,IAAI,UAAS;CAE5B,MAAM,MADM,OAAO,gBAAgB,UAAU,KAAK,KAAK,GAAG,eAC9C,CAAA,CAAI;CAEhB,IAAI,OAAO,IAAI,aAAa,OAC1B,OAAO;CAIT,OADiB,OAAO,gBAAgB,UAAU,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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"magmonium-one-size-converter-C5fG_dgw.mjs","names":[],"sources":["../../../../libs/one/src/lib/shared/enum/scaling/size.ts","../../../../libs/one/src/lib/shared/enum/assets/assets.ts","../../../../libs/one/src/lib/shared/enum/assets/layout-asset-folder.ts","../../../../libs/one/src/lib/shared/enum/assets/form-asset-folder.ts","../../../../libs/one/src/lib/shared/config/tokens.ts","../../../../libs/one/src/lib/shared/lib/remote/web-util.ts","../../../../libs/one/src/lib/shared/functions/remote-url.ts","../../../../libs/one/src/lib/shared/services/http.ts","../../../../libs/one/src/lib/shared/functions/object/json.ts","../../../../libs/one/src/lib/shared/services/storage.ts","../../../../libs/one/src/lib/shared/config/service-registry.ts","../../../../libs/one/src/lib/shared/stores/asset.store.ts","../../../../libs/one/src/lib/shared/functions/text/mini-mark.ts","../../../../libs/one/src/lib/shared/functions/browser-locale.ts","../../../../libs/one/src/lib/shared/services/browser-locale.ts","../../../../libs/one/src/lib/shared/services/translate.ts","../../../../libs/one/src/lib/shared/pipe/translate.ts","../../../../libs/one/src/lib/shared/functions/size/size-converter.ts"],"sourcesContent":["/**\n * The three scale steps the design system renders, and the only ones — see\n * GLOSSARY.md `Size` and ADR 0008. Declarable on a Section or a ButtonGroup and\n * nowhere else (a SectionButtonGroup shares the latter seat, being its\n * markup-composed variant); everything below one renders at its Size.\n */\nexport enum Size {\n SMALL = 'sm',\n MEDIUM = 'md',\n LARGE = 'lg',\n}\n\nexport const DEFAULT_SIZE = Size.MEDIUM;\n","export enum Assets {\n JSON = 'json',\n SVG = 'svg',\n PNG = 'png',\n CSS = 'css',\n /** A DocAsset — markdown, copied verbatim rather than compiled. */\n MD = 'md',\n}\n","// Single source for the layout primitives' asset subFolder — each\n// primitive's ConfigComponent.subFolder reads from here, and the m-one-ui\n// Design editor's codegen reads the same const when emitting ControlAssets,\n// so the two never drift apart (see libs/one ADR 0004).\nexport const LAYOUT_ASSET_FOLDER = {\n section: 'sections',\n row: 'rows',\n col: 'cols',\n flex: 'flex_containers',\n flex_item: 'flex_items',\n // Not `button_groups` — those files carry `names`, `buttons`, `isContext`,\n // `primary` and `size`, none of which a SectionButtonGroup reads (ADR 0009).\n section_button_group: 'section_button_groups',\n section_hero: 'section_heroes',\n section_carousel: 'section_carousels',\n text_output: 'text_outputs',\n list: 'lists',\n section_table: 'section_tables',\n} as const;\n","// Single source for the asset subFolders a form and its Fields resolve by —\n// FormGroupComponent and WrapperInputComponent read from here, and the\n// m-one-ui Design editor's codegen reads the same const when emitting a\n// FormControl's and a FieldControl's assets, so the two never drift apart\n// (same reason as LAYOUT_ASSET_FOLDER, libs/one ADR 0004).\nexport const FORM_ASSET_FOLDER = {\n form: 'forms',\n field: 'fields',\n // Choices a Field points at by name, shared across every form that names\n // the same list (AssetOptions).\n options: 'options',\n // Shapes a Field's value may take, named the same way and resolved at build\n // rather than at runtime (AssetPatterns, libs/one ADR 0017).\n patterns: 'patterns',\n} as const;\n","import {\n InjectionToken,\n Signal,\n Type,\n WritableSignal,\n signal,\n} from '@angular/core';\nimport type { MountRoute, RemoteMount } from '../lib/remote/model';\nimport type { LoadingActionsApi } from './service-registry';\n\nexport interface NavStoreRef {\n /** Current NavId — route's NavId plus any open Murl segments. */\n id: Signal<string | undefined>;\n /**\n * The Nav the open panel *is*, once an anchored Murl has fallen through to\n * the panel that answered it — or the Nav a Browse moved it onto. What a\n * toggle compares itself against: `id` is the address's own key and names no\n * node when a panel was opened over a page.\n */\n panelNavId?: Signal<string | undefined>;\n /**\n * `panelNavId` with any Browse left out — where the User stands rather than\n * where they are looking (GLOSSARY.md Browse). What a row marks itself\n * against, so the row they came through stays marked while they Browse.\n * Optional: a host built before it existed provides none.\n */\n standingNavId?: Signal<string | undefined>;\n /** Open Murl segments. Empty means no panel is addressed. */\n murl: Signal<string[]>;\n /**\n * Whether the panel is up — an open Murl or one the User raised. What a move\n * reads to keep an open panel without raising a closed one. Optional: a host\n * built before it existed provides none.\n */\n isNavOpened?: Signal<boolean>;\n /**\n * The Router's current path parameters. A row of a `dynamic` Nav names the\n * node like every other row of that Nav, so this is the only thing that\n * tells the one being stood on from its siblings.\n */\n routeParams?: Signal<Record<string, string>>;\n /**\n * Follows a NavRef by NavId; `undefined` closes the panel. `params` supplies\n * values for any dynamic segment on the way — a NavRef names the node, the\n * instance is data.\n */\n setSelected: (\n navId?: string,\n params?: Record<string, string | number>,\n options?: { keepPanel?: boolean }\n ) => void;\n /**\n * Moves the open panel onto a Nav without moving the User — the Address and\n * the Page stay put (GLOSSARY.md Browse). `params` names the instance of a\n * `dynamic` Nav. Optional: a host built before it existed provides none.\n */\n browse?: (navId: string, params?: Record<string, string | number>) => void;\n /**\n * Follows a NavRef whose dynamic segments are keyed by the Nav contributing\n * each one rather than by parameter name — what an emitted OutcomeNav calls\n * (m-one-ui GLOSSARY.md OutcomeNav). Optional: a host built before it existed\n * provides none, and the gesture then does nothing rather than throwing.\n */\n followNav?: (\n navId: string,\n byNav?: Record<string, string | number>,\n options?: { replaceUrl?: boolean; keepPanel?: boolean }\n ) => void;\n /** Up to the nearest ancestor of the current page that routes. */\n goToParentNav?: (options?: { replaceUrl?: boolean }) => void;\n /** The current value of the route parameter one dynamic Nav contributes. */\n routeParamOf?: (navId: string) => string | undefined;\n /**\n * Whether the routed page is this Nav or one below it. Signal-backed, so a\n * `computed` reading it follows navigation. Optional for `followNav`'s reason.\n */\n isNavActive?: (navId: string) => boolean;\n /** A mounted Remote announcing itself, and leaving (ADR 0036). */\n registerMount?: (mount: RemoteMount) => void;\n unregisterMount?: (name: string, navigate?: RemoteMount['navigate']) => void;\n /**\n * Where a mount's own Router stands, reported on each move; `undefined`\n * forgets it. Optional: a host built before it existed provides none.\n */\n setMountRoute?: (name: string, route: MountRoute | undefined) => void;\n}\n\nexport enum AppRelationType {\n OWNER = 1,\n COLLABORATOR = 2,\n USER = 3,\n COLLABORATE_REQUESTED = 4,\n INSTALL_REQUESTED = 5,\n INSTALL_REJECTED = 6,\n COLLABORATE_REJECTED = 7,\n}\n\nexport type AppRelation = {\n id: string;\n user: string;\n app: string;\n type: AppRelationType;\n validTill: string | null;\n};\n\n/**\n * One Permission an App may declare — a catalog entry naming a kind of\n * cross-context data access (store ADR 0006). `nameKey` is the short code an\n * App stores in its Declared Permissions (`wr`) and is never translated;\n * `descriptionKey` is the i18n key users see.\n */\nexport interface AppPermission {\n nameKey: string;\n descriptionKey: string;\n}\n\n/** The caller's Relation to one App as `store/app/<link>/relation` answers it. */\nexport interface AppRelationView {\n app: string;\n type: AppRelationType | null;\n /** Open App: asks no Relation, Agreement or Country Restriction — the App just opens. */\n open?: boolean;\n /** The App's apis refuse until the caller agrees to its Declared Permissions again. */\n needsAgreement: boolean;\n /** The App's Declared Permissions — what an Agreement accepts, all at once. */\n permissions: AppPermission[];\n /**\n * Relation Language as resolved — the language the App runs in for the\n * caller; null when nothing resolves and the client picks from the Browser\n * Locale and `supportedLanguages`.\n */\n language: string | null;\n /**\n * The App's Default Language — where its keys come from when it ships none\n * for `language`; null when the Owner named none.\n */\n defaultLanguage: string | null;\n /** The App's Supported Languages in platform order. */\n supportedLanguages: string[];\n /** The App's Country Restriction refuses the caller; the App must not open. */\n countryBlocked: boolean;\n}\n\n/**\n * A mode + list rule — `allow` keeps only the listed codes, `block` drops\n * them; an empty `block` list is All. Country Restriction lists ISO 3166-1\n * alpha-2 codes, Supported Languages platform language codes.\n */\nexport interface AppCodeRule {\n mode: 'allow' | 'block';\n list: string[];\n}\n\n/** Who may use an App, stored and sent as its number. `OPEN` Apps are embedded by other Apps as their own. */\nexport enum AppAvailability {\n EVERYONE = 1,\n TEAM_ONLY = 2,\n ONLY_ME = 3,\n OPEN = 4,\n}\n\n/** What every user of an App is bound by, as `store/app/<id>/permission` answers it. */\nexport interface AppRules {\n availability: AppAvailability;\n permissions: AppPermission[];\n countries: AppCodeRule;\n languages: AppCodeRule & { default: string | null };\n}\n\nexport interface AppContextRef {\n user: Signal<SharedUser | undefined>;\n isVisitor: Signal<boolean>;\n isUser: Signal<boolean>;\n isCollaborator: Signal<boolean>;\n isManager: Signal<boolean>;\n}\n\nexport interface SharedToken {\n auth: string;\n refresh: string;\n}\n\nexport interface SharedUser {\n firstName: string;\n lastName: string;\n profilePic?: string;\n lang?: string;\n id: string;\n username?: string;\n dob?: string;\n}\n\nexport interface LoginStoreContract {\n tokens: Signal<SharedToken | undefined>;\n userId: Signal<string | undefined>;\n initApp(data: {\n navs: string[];\n tokens?: SharedToken;\n user?: SharedUser;\n }): void;\n setTokens(tokens: SharedToken): void;\n clearAuth(): void;\n loadSavedLoginIds(): void;\n isLoggedIn: Signal<boolean>;\n // The signed-in User's Deploy Token, shared with remotes (the design editor)\n // so every app reads the one the host minted this session.\n deployToken: Signal<string | undefined>;\n hasDeployToken: Signal<boolean>;\n ensureDeployToken: () => void;\n rotateDeployToken: () => void;\n}\n\nexport const LOGIN_COMPONENT = new InjectionToken<Type<unknown>>(\n 'LOGIN_COMPONENT'\n);\nexport const LOGIN_STORE = new InjectionToken<LoginStoreContract>(\n 'LOGIN_STORE'\n);\n/**\n * True inside a Remote's own bundle (`provideMagWcConfig`). Where it is mounted\n * is the host's MountPattern, so the base href no longer tells a Remote apart.\n */\nexport const WC_BUNDLE = new InjectionToken<boolean>('WC_BUNDLE');\nexport const ASSET_BASE_URL = new InjectionToken<string>('ASSET_BASE_URL');\nexport const ONE_ASSET_BASE_URL = new InjectionToken<string>(\n 'ONE_ASSET_BASE_URL'\n);\nexport const SEARCH_QUERY = new InjectionToken<WritableSignal<string>>(\n 'SEARCH_QUERY'\n);\nexport const SEARCH_RESULTS_EVENT = '__mag_search_results__';\nexport const WC_SEARCH_GROUPS = new InjectionToken<\n Signal<{ key: string; label: string; items: unknown[] }[]>\n>('WC_SEARCH_GROUPS');\nexport const NAV_STORE_REF = new InjectionToken<NavStoreRef>('NAV_STORE_REF');\n\nexport interface ModalStoreTrigger {\n component: Type<unknown>;\n bindings?: unknown[];\n name?: string;\n one?: boolean;\n id?: string;\n providers?: unknown[];\n config?: unknown;\n}\n\nexport interface ModalStoreRef {\n modalTriggerMap: Signal<Record<string, unknown>>;\n open: (trigger: ModalStoreTrigger) => string;\n // Same trigger shape as `open`, presented as a SidePanel instead. On the\n // contract because a field can now choose its presentation, and the token is\n // all a ComponentInput sees of the store.\n openPanel: (trigger: ModalStoreTrigger & { width?: string }) => string;\n close: (id?: string) => void;\n closePanel: (id?: string) => void;\n}\n\nexport const MODAL_STORE_REF = new InjectionToken<ModalStoreRef>(\n 'MODAL_STORE_REF'\n);\n\nexport interface UserStoreRef {\n get: (\n id: string\n ) => Signal<\n { firstName?: string; lastName?: string; username?: string } | undefined\n >;\n}\n\nexport const USER_STORE_REF = new InjectionToken<UserStoreRef>(\n 'USER_STORE_REF'\n);\n\nexport const APP_CONTEXT_REF = new InjectionToken<AppContextRef>(\n 'APP_CONTEXT_REF'\n);\n\n/**\n * This application's own AppLink. `root` is per bootstrapped app, so a Remote\n * never reads its host's — unlike NavStore's `appLink`, which is the host's\n * active app. The interceptor names the App in `X-Mag-App` with it (api ADR\n * 0007) and init asks for Agreement to it.\n */\nexport const APP_LINK = new InjectionToken<WritableSignal<string | undefined>>(\n 'APP_LINK',\n { providedIn: 'root', factory: () => signal<string | undefined>(undefined) }\n);\n\n/**\n * The loading counter this application's requests move, ahead of the host's\n * shared one. A Plugin provides its own so its requests never turn the host's\n * `busy` on (libs/one GLOSSARY.md Plugin); unset, the host's counter is used.\n */\nexport const LOADING_ACTIONS_REF = new InjectionToken<LoadingActionsApi>(\n 'LOADING_ACTIONS_REF'\n);\n\nexport const IS_SIDE_PANEL = new InjectionToken<boolean>('IS_SIDE_PANEL');\n\n// SVG markup supplied by name from memory instead of fetched as an asset.\n// `m-icon` reads it before its own resource, so a glyph that exists only in a\n// host app's state still renders everywhere an asset-backed one would. Signal\n// valued on purpose: editing the markup under an unchanged name repaints every\n// icon using it, which a one-shot fetch could never do.\nexport const ICON_SOURCE = new InjectionToken<\n Signal<Record<string, string> | undefined>\n>('ICON_SOURCE');\n\n// Translations supplied by key from memory instead of fetched as an asset,\n// for the language currently being rendered. `TranslateService` reads it ahead\n// of its own fetched map, so a key that exists only in a host app's state — a\n// visual editor's unsaved messages, say — resolves everywhere a fetched one\n// would. Signal valued for the same reason as ICON_SOURCE: editing the text\n// under an unchanged key repaints every string using it.\nexport const TRANSLATION_SOURCE = new InjectionToken<\n Signal<Record<string, string> | undefined>\n>('TRANSLATION_SOURCE');\n\n// Option lists supplied by name from memory instead of fetched as an\n// `options/<name>` asset. Every Field that names an OptionsSource (`mOptions`\n// / `optionsAsset:`) reads this ahead of its own fetch, so a list that exists\n// only in a host app's state — a visual editor's unsaved OptionSets — fills the\n// same Fields a shipped asset would. Rows carry the asset's own shape, flat or\n// rows-of-rows. Signal valued for the same reason as ICON_SOURCE: editing rows\n// under an unchanged name repaints every Field using it.\nexport const OPTIONS_SOURCE = new InjectionToken<\n Signal<Record<string, unknown> | undefined>\n>('OPTIONS_SOURCE');\n\n// Maps a `component:` name in a field asset to the component that field opens,\n// so a ComponentInput stays YAML-declared like every other field instead of\n// needing the class threaded down through `[elements]` at every call site.\nexport const COMPONENT_INPUT_REGISTRY = new InjectionToken<\n Record<string, Type<unknown>>\n>('COMPONENT_INPUT_REGISTRY');\n\n/** Optional hook when a FileUploadInput in folder mode picks a directory handle. */\nexport type FolderPickListener = (handle: unknown, name: string) => void;\nexport const FOLDER_PICK_LISTENER = new InjectionToken<FolderPickListener>(\n 'FOLDER_PICK_LISTENER'\n);\n\n// DesignMode: marks a subtree as rendered inside a visual editor's canvas rather\n// than on a real page. Carries no payload — presence is the whole signal. Provided\n// only by the editor's renderer, so every consumer must inject it as optional.\nexport const IS_DESIGN_MODE = new InjectionToken<boolean>('IS_DESIGN_MODE');\n","import { WebComponentConfig } from './model';\n\nexport function isWebComponent(config: unknown): config is WebComponentConfig {\n if (!config || typeof config !== 'object') {\n return false;\n }\n return 'selector' in config;\n}\n\nconst PREVIEW_PATH_RE = /\\/pwa\\/(draft|beta|published)(?:\\/|$)/;\nconst PREVIEW_TIERS = new Set(['draft', 'beta', 'published']);\n\nfunction getTierFromSearch(search: string): string | null {\n const tier = new URLSearchParams(search).get('tier');\n return tier && PREVIEW_TIERS.has(tier) ? tier : null;\n}\n\nexport function isTierPreview(pathname?: string, search?: string): boolean {\n if (pathname !== undefined && PREVIEW_PATH_RE.test(pathname)) return true;\n if (search !== undefined && !!getTierFromSearch(search)) return true;\n return false;\n}\n\nexport function getTierFromPreviewPath(pathname: string, search?: string): string | null {\n return PREVIEW_PATH_RE.exec(pathname)?.[1] ?? (search ? getTierFromSearch(search) : null);\n}\n\nexport const isLocalhost =\n typeof window !== 'undefined' &&\n (window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.hostname === '0.0.0.0');\n\nexport function isUrlLocalhost(url: string): boolean {\n try {\n const host = new URL(url).hostname;\n return host === 'localhost' || host === '127.0.0.1' || host === '0.0.0.0';\n } catch {\n return false;\n }\n}\n\n","import { isLocalhost } from '../lib/remote/web-util';\n\n/**\n * Where an app is mounted from instead of its status folder: the Store's beta\n * tier, or a dev server on this machine (`local`, at the port pinned beside it).\n */\nexport type WcTier = 'beta' | 'local';\n\ntype TierWindow = Window & {\n __MAGMONIUM_STANDALONE__?: boolean;\n /**\n * The tier each AppLink is mounted from. On `window` rather than a service:\n * the host and every Remote bundle carry their own libs/one, and all of them\n * build that Remote's URLs.\n */\n __MAGMONIUM_WC_TIERS__?: Record<string, WcTier>;\n /** The dev-server port each AppLink pinned to `local` is served from. */\n __MAGMONIUM_WC_LOCAL_PORTS__?: Record<string, number>;\n /**\n * The tier whose bundle defined each custom-element tag. A page has one\n * registry and a tag defines once, so a second tier of one app cannot load\n * beside the first — it can only be noticed.\n */\n __MAGMONIUM_WC_DEFINED_TIERS__?: Record<string, WcTier | 'status'>;\n /**\n * The bundle file — hash and all — that defined each tag. Two tiers serving\n * one bundle (an app in Beta: its status folder *is* its beta folder) are\n * the same code, so the tag already defined is the one asked for.\n */\n __MAGMONIUM_WC_DEFINED_BUNDLES__?: Record<string, string>;\n};\n\nconst tierWindow = (): TierWindow | undefined =>\n typeof window !== 'undefined' ? (window as TierWindow) : undefined;\n\n/** Pins an AppLink to a tier, or back to its status folder with `undefined`. */\nexport function setWcTier(remoteId: string, tier: WcTier | undefined): void {\n const win = tierWindow();\n if (!win) return;\n const tiers = { ...(win.__MAGMONIUM_WC_TIERS__ ?? {}) };\n if (tier) tiers[remoteId] = tier;\n else delete tiers[remoteId];\n win.__MAGMONIUM_WC_TIERS__ = tiers;\n}\n\n/** Pins an AppLink's `local` tier to a dev-server port, or unpins it. */\nexport function setWcLocalPort(remoteId: string, port: number | undefined): void {\n const win = tierWindow();\n if (!win) return;\n const ports = { ...(win.__MAGMONIUM_WC_LOCAL_PORTS__ ?? {}) };\n if (port) ports[remoteId] = port;\n else delete ports[remoteId];\n win.__MAGMONIUM_WC_LOCAL_PORTS__ = ports;\n}\n\n/**\n * Where an AppLink pinned to `local` is served: the app's own dev server, whose\n * `assets/` holds `remote/app-wc.json`, the bundle and every asset. Undefined\n * when it is not pinned there, or has no usable port.\n */\nexport function wcLocalBaseOf(remoteId: string): string | undefined {\n const win = tierWindow();\n if (win?.__MAGMONIUM_WC_TIERS__?.[remoteId] !== 'local') return undefined;\n const port = win.__MAGMONIUM_WC_LOCAL_PORTS__?.[remoteId];\n return port && Number.isInteger(port) && port > 0 && port < 65536\n ? `http://localhost:${port}/assets`\n : undefined;\n}\n\nexport function wcTierOf(remoteId: string): WcTier | undefined {\n return tierWindow()?.__MAGMONIUM_WC_TIERS__?.[remoteId];\n}\n\n/** Which tier's bundle defined a tag — `status` for the app's status folder. */\nexport function definedWcTierOf(selector: string): WcTier | 'status' | undefined {\n return tierWindow()?.__MAGMONIUM_WC_DEFINED_TIERS__?.[selector];\n}\n\n/** The bundle file that defined a tag, when the loader that defined it said. */\nexport function definedWcBundleOf(selector: string): string | undefined {\n return tierWindow()?.__MAGMONIUM_WC_DEFINED_BUNDLES__?.[selector];\n}\n\nexport function recordDefinedWcTier(\n selector: string,\n tier: WcTier | 'status',\n bundle?: string\n): void {\n const win = tierWindow();\n if (!win) return;\n win.__MAGMONIUM_WC_DEFINED_TIERS__ = {\n ...(win.__MAGMONIUM_WC_DEFINED_TIERS__ ?? {}),\n [selector]: tier,\n };\n if (bundle)\n win.__MAGMONIUM_WC_DEFINED_BUNDLES__ = {\n ...(win.__MAGMONIUM_WC_DEFINED_BUNDLES__ ?? {}),\n [selector]: bundle,\n };\n}\n\nexport function buildWcBaseUrl(apiUrl: string, remoteId: string): string {\n // Asked for by name, so it wins over every guess below.\n const local = wcLocalBaseOf(remoteId);\n if (local) return local;\n if (tierWindow()?.__MAGMONIUM_STANDALONE__) {\n return '/assets';\n }\n if (isLocalhost) {\n return `/local-dist/m-${remoteId}-wc`;\n }\n const tier = wcTierOf(remoteId);\n return `${apiUrl}/store/v1/wc/${remoteId}${tier === 'beta' ? '/beta' : ''}`;\n}\n","import { inject, Injectable } from '@angular/core';\nimport { HttpClient, HttpEvent, HttpParams } from '@angular/common/http';\nimport { firstValueFrom, Observable } from 'rxjs';\nimport { Assets } from '../enum';\nimport { ASSET_BASE_URL, ONE_ASSET_BASE_URL } from '../config/tokens';\nimport { isLocalhost } from '../lib/remote/web-util';\nimport {\n buildWcBaseUrl,\n wcLocalBaseOf,\n wcTierOf,\n} from '../functions/remote-url';\n\nexport type Version = undefined | 'v2';\n\nexport type QueryValue = string | number | boolean;\n\n/**\n * A query string, as an operation declares it. `undefined` and `null` are\n * dropped rather than serialised — an optional query parameter left unset is\n * absent from the url, never `?q=undefined`.\n */\nexport type QueryParams = Record<\n string,\n QueryValue | readonly QueryValue[] | null | undefined\n>;\n\n/** Access domains — routed to Auth URL when it differs from Backend URL (ADR 0012). */\nexport const ACCESS_DOMAINS = new Set(['auth', 'user', 'admin']);\n\n@Injectable({\n providedIn: 'root',\n})\nexport class HttpService {\n private readonly http: HttpClient = inject(HttpClient);\n private url = 'http://localhost:8000';\n private authUrl = 'http://localhost:8000';\n private assetUrl = inject(ASSET_BASE_URL, { optional: true }) ?? './assets';\n private oneAssetUrl =\n inject(ONE_ASSET_BASE_URL, { optional: true }) ?? './assets';\n private publicUrl = './';\n\n get<T>(\n domain: string,\n path: (string | number)[],\n version?: Version,\n params?: QueryParams\n ): Observable<T> {\n return this.http.get<T>(this.createUrl(domain, path, version), {\n params: this.toParams(params),\n });\n }\n\n // The writing verbs take a query alongside their body: a path templates its\n // ids, the body carries the payload, and a filter or a mode rides on the\n // query — one operation can declare all three and none of them substitutes.\n put<T>(\n domain: string,\n path: (string | number)[],\n data?: unknown,\n version?: Version,\n params?: QueryParams\n ): Observable<T> {\n return this.http.put<T>(this.createUrl(domain, path, version), data, {\n params: this.toParams(params),\n });\n }\n\n post<T>(\n domain: string,\n path: (string | number)[],\n data?: unknown,\n version?: Version,\n params?: QueryParams\n ): Observable<T> {\n return this.http.post<T>(this.createUrl(domain, path, version), data, {\n params: this.toParams(params),\n });\n }\n\n patch<T>(\n domain: string,\n path: (string | number)[],\n data?: unknown,\n version?: Version,\n params?: QueryParams\n ): Observable<T> {\n return this.http.patch<T>(this.createUrl(domain, path, version), data, {\n params: this.toParams(params),\n });\n }\n\n patchEvents(\n domain: string,\n path: (string | number)[],\n data?: unknown,\n version?: Version\n ): Observable<HttpEvent<string>> {\n return this.http.patch(this.createUrl(domain, path, version), data, {\n observe: 'events',\n responseType: 'text',\n reportProgress: true,\n });\n }\n\n postEvents(\n domain: string,\n path: (string | number)[],\n data?: unknown,\n version?: Version\n ): Observable<HttpEvent<string>> {\n return this.http.post(this.createUrl(domain, path, version), data, {\n observe: 'events',\n responseType: 'text',\n reportProgress: true,\n });\n }\n\n delete<T>(\n domain: string,\n path: (string | number)[],\n version?: Version,\n params?: QueryParams\n ): Observable<T> {\n return this.http.delete<T>(this.createUrl(domain, path, version), {\n params: this.toParams(params),\n });\n }\n\n deleteWithBody<T>(\n domain: string,\n path: (string | number)[],\n body: unknown,\n version?: Version,\n params?: QueryParams\n ): Observable<T> {\n return this.http.delete<T>(this.createUrl(domain, path, version), {\n body,\n params: this.toParams(params),\n });\n }\n\n setUrl(url: string) {\n this.url = url;\n }\n\n getUrl(): string {\n return this.url;\n }\n\n setAuthUrl(url: string) {\n this.authUrl = url;\n }\n\n getAuthUrl(): string {\n return this.authUrl;\n }\n\n buildUrl(\n domain: string,\n path: (string | number)[],\n version?: Version\n ): string {\n return this.createUrl(domain, path, version);\n }\n\n setAssetUrl(url: string) {\n this.assetUrl = url;\n }\n\n setOneAssetUrl(url: string) {\n this.oneAssetUrl = url;\n }\n\n setPublicUrl(url: string) {\n this.publicUrl = url;\n }\n\n blob(url: string): Observable<Blob> {\n return this.http.get(url, { responseType: 'blob' });\n }\n\n /** A whole url read as text — what a document fetched from a Remote needs. */\n text(url: string): Observable<string> {\n return this.http.get(url, { responseType: 'text' });\n }\n\n wc<T>(link: string, filePath: string[]): Observable<T> {\n const local = wcLocalBaseOf(link);\n if (local) return this.http.get<T>(`${local}/${filePath.join('/')}`);\n if (isLocalhost) {\n return this.http.get<T>(`/local-dist/m-${link}-wc/${filePath.join('/')}`);\n }\n const tier = wcTierOf(link);\n return this.get<T>('store', ['wc', link, ...(tier === 'beta' ? [tier] : []), ...filePath]);\n }\n\n buildWcUrl(link: string): string {\n return buildWcBaseUrl(this.url, link);\n }\n\n public buildWcAssetBaseUrl(link: string): string {\n return this.buildWcUrl(link);\n }\n\n public buildWcAssetUrl(link: string, path: string): string {\n const normalized = path.startsWith('assets/')\n ? path.slice('assets/'.length)\n : path;\n return this.join(this.buildWcAssetBaseUrl(link), normalized);\n }\n\n public getAssetUrl(\n path: string | null | undefined,\n isPublic = false\n ): string {\n if (!path) return '';\n if (\n path.startsWith('http') ||\n path.startsWith('data:') ||\n path.startsWith('blob:')\n ) {\n return path;\n }\n const base = isPublic ? this.assetUrl : this.url;\n return this.join(base, path);\n }\n\n public getPublicUrl(path: string | null | undefined): string {\n if (!path) return '';\n if (path.startsWith('http')) return path;\n return this.join(this.publicUrl, path);\n }\n\n /**\n * Loads a worker from a URL.\n * If the URL is cross-origin, it fetches the script and creates a Blob worker.\n * This avoids 'importScripts' NetworkErrors in cross-origin environments like Web Components.\n */\n public async loadWorker(url: string): Promise<Worker> {\n if (url.startsWith('http') && !url.startsWith(window.location.origin)) {\n try {\n const script = await firstValueFrom(\n this.http.get(url, { responseType: 'text' })\n );\n const blob = new Blob([script], { type: 'application/javascript' });\n return new Worker(URL.createObjectURL(blob));\n } catch (error) {\n console.warn(\n `Failed to fetch worker cross-origin, falling back to importScripts shim:`,\n error\n );\n // Fallback to the old shim if fetch fails (e.g. CORS not configured but importScripts might work)\n const shim = new Blob([`importScripts(\"${url}\")`], {\n type: 'application/javascript',\n });\n return new Worker(URL.createObjectURL(shim));\n }\n }\n return new Worker(url);\n }\n\n private join(base: string, path: string): string {\n const b = base.endsWith('/') ? base.slice(0, -1) : base;\n const p = path.startsWith('/') ? path.slice(1) : path;\n return `${b}/${p}`;\n }\n\n asset<T>(\n tree: string[],\n type: Assets,\n options?: Record<string, unknown>,\n baseUrl?: string\n ): Observable<T> {\n const resolvedBase =\n baseUrl ?? (tree[0] === 'one' ? this.oneAssetUrl : this.assetUrl);\n const url = this.join(resolvedBase, `${tree.join('/')}.${type}`);\n\n const requestOptions = {\n ...options,\n responseType: this.fromAssetToResponseType(type) as 'json',\n };\n\n return this.http.get<T>(url, requestOptions) as Observable<T>;\n }\n\n private createUrl(\n domain: string,\n path: (string | number)[],\n version?: Version\n ) {\n const base = ACCESS_DOMAINS.has(domain) ? this.authUrl : this.url;\n return `${base}/${domain}/${version ?? 'v1'}/${path.join('/')}`;\n }\n\n /**\n * The query, built by hand rather than handed to `fromObject`: an unset\n * optional parameter is absent from the url, and a repeated one appends\n * instead of replacing.\n */\n private toParams(params?: QueryParams): HttpParams | undefined {\n if (!params) return undefined;\n let built = new HttpParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const item of value) built = built.append(key, String(item));\n } else {\n built = built.set(key, String(value));\n }\n }\n return built.keys().length ? built : undefined;\n }\n\n private fromAssetToResponseType = (assets: Assets) => {\n let responseType: 'text' | 'json' | 'blob' = 'json';\n switch (assets) {\n case Assets.SVG:\n case Assets.CSS:\n case Assets.MD:\n responseType = 'text';\n break;\n case Assets.PNG:\n responseType = 'blob';\n break;\n case Assets.JSON:\n default:\n responseType = 'json';\n break;\n }\n return responseType;\n };\n}\n","export function isJson(data: unknown) {\n if (typeof data === 'string') {\n try {\n JSON.parse(data);\n } catch {\n return false;\n }\n }\n return true;\n}\n","import { Injectable } from '@angular/core';\nimport { isJson } from '../functions/object/json';\n\n/** Which shelf a HeldValue lives on. The caller's pick, never derived. */\nexport type HeldShelf = 'local' | 'session';\n\n@Injectable({ providedIn: 'root' })\nexport class StorageService {\n /**\n * Write a HeldValue (GLOSSARY.md HeldValue, ADR 0019). Always a JSON envelope,\n * so a `string` holding `'3'` reads back a `string` and not the `3` that\n * `getLocal` answers; `undefined` deletes the key rather than storing the\n * word; and falsiness is never a reason to skip the write, so a `false`, a\n * `0` and an empty string land like any other value.\n */\n public setHeld<T>(key: string, value: T, shelf: HeldShelf = 'local'): void {\n const shelfStore = this.shelf(shelf);\n if (value === undefined) {\n shelfStore.removeItem(key);\n return;\n }\n shelfStore.setItem(key, JSON.stringify(value));\n }\n\n /**\n * Read a HeldValue back at the type it was written. An absent key and an\n * unreadable one both answer `undefined` — a store that cannot say what it\n * holds holds nothing, which is the same answer the caller's initial state\n * already gives.\n */\n public getHeld<T>(key: string, shelf: HeldShelf = 'local'): T | undefined {\n const raw = this.shelf(shelf).getItem(key);\n if (raw === null) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return undefined;\n }\n }\n\n private shelf(shelf: HeldShelf): Storage {\n return shelf === 'session' ? sessionStorage : localStorage;\n }\n\n public setSession(key: string, value: unknown): void {\n if (value) {\n if (isJson(value)) {\n sessionStorage.setItem(key, JSON.stringify(value));\n } else {\n sessionStorage.setItem(key, String(value));\n }\n }\n }\n\n public getSession(key: string): unknown {\n const data = sessionStorage.getItem(key);\n if (data && isJson(data)) {\n return JSON.parse(data);\n } else {\n return data;\n }\n }\n\n public deleteSession(key: string): void {\n sessionStorage.removeItem(key);\n }\n\n public setLocal(key: string, value: unknown): void {\n if (isJson(value)) {\n localStorage.setItem(key, JSON.stringify(value));\n } else {\n localStorage.setItem(key, String(value));\n }\n }\n\n public getLocal(key: string): unknown {\n const data = localStorage.getItem(key);\n if (data && isJson(data)) {\n return JSON.parse(data);\n } else {\n return data;\n }\n }\n\n public deleteLocal(key: string): void {\n localStorage.removeItem(key);\n }\n}\n","import { Injector } from '@angular/core';\n\nexport interface LoadingActionsApi {\n startLoading: () => void;\n stopLoading: () => void;\n setError: () => void;\n clearError: () => void;\n reset: () => void;\n cancelLoading: () => void;\n}\n\n// Extend Window interface for shared stores\ninterface SharedStores {\n themeStore?: unknown;\n translateService?: unknown;\n hostInjector?: Injector;\n loadingActions?: LoadingActionsApi;\n socketUrl?: string;\n navStore?: unknown;\n loginStore?: unknown;\n notificationStore?: unknown;\n}\n\ndeclare const window: Window & { sharedStores: SharedStores };\n\nexport class SharedStoreRegistry {\n static setNavStore(store: unknown): void {\n this.check();\n if (!window.sharedStores.navStore) {\n window.sharedStores.navStore = store;\n }\n }\n\n static getNavStore(): unknown {\n return window.sharedStores?.navStore;\n }\n\n static setLoginStore(store: unknown): void {\n this.check();\n if (!window.sharedStores.loginStore) {\n window.sharedStores.loginStore = store;\n }\n }\n\n static getLoginStore(): unknown {\n return window.sharedStores?.loginStore;\n }\n\n /** First-write-wins: host registers its store; WC bundles reuse it so popups render in the host outlet. */\n static setNotificationStore(store: unknown): void {\n this.check();\n if (!window.sharedStores.notificationStore) {\n window.sharedStores.notificationStore = store;\n }\n }\n\n static getNotificationStore(): unknown {\n return window.sharedStores?.notificationStore;\n }\n static setHostInjector(injector: Injector): void {\n this.check();\n window.sharedStores.hostInjector = injector;\n }\n\n static getHostInjector(): Injector | undefined {\n return window.sharedStores?.hostInjector;\n }\n\n static getThemeStore(): unknown {\n return window.sharedStores?.themeStore;\n }\n\n static getTranslateService(): unknown {\n return window.sharedStores?.translateService;\n }\n\n static setThemeStore(store: unknown): void {\n this.check();\n window.sharedStores.themeStore = store;\n }\n\n /** First-write-wins: host registers its service; WC bundles reuse it instead of creating a new one. */\n static setTranslateService(service: unknown): void {\n this.check();\n if (!window.sharedStores.translateService) {\n window.sharedStores.translateService = service;\n }\n }\n\n /** First-write-wins: the host app registers its actions; WC bundles skip if already set. */\n static setLoadingActions(actions: LoadingActionsApi): void {\n this.check();\n if (!window.sharedStores.loadingActions) {\n window.sharedStores.loadingActions = actions;\n }\n }\n\n static getLoadingActions(): LoadingActionsApi | undefined {\n return window.sharedStores?.loadingActions;\n }\n\n /** First-write-wins: host sets this; WCs skip socket init when truthy. */\n static setSocketUrl(url: string): void {\n this.check();\n if (!window.sharedStores.socketUrl) {\n window.sharedStores.socketUrl = url;\n }\n }\n\n static isHostSocketActive(): boolean {\n return !!window.sharedStores?.socketUrl;\n }\n\n private static check() {\n if (!window.sharedStores) {\n window.sharedStores = {};\n }\n }\n}\n","import { inject } from '@angular/core';\nimport {\n patchState,\n signalStore,\n withHooks,\n withMethods,\n withState,\n} from '@ngrx/signals';\nimport { catchError, finalize, Observable, of, shareReplay, tap, throwError } from 'rxjs';\nimport { Assets } from '../enum';\nimport { HttpService } from '../services/http';\nimport { StorageService } from '../services/storage';\nimport { SharedStoreRegistry } from '../config/service-registry';\n\ntype AssetMap = Record<string, Record<string, Record<string, unknown>>>;\n\ninterface AssetState {\n map: AssetMap;\n isCachingDisabled: boolean;\n appLink: string | undefined;\n /** The host path this app is mounted under, as the mounting m-remote said. */\n hostBase: string | undefined;\n /**\n * Whether an m-remote mounted this app: the host then writes the page\n * address from its reports, and this app's Router never writes it itself.\n */\n hosted: boolean;\n}\n\nconst STORAGE_KEY = 'mag_assets';\n\nconst inferAssetType = (folder: string): Assets =>\n folder === 'icons' ? Assets.SVG : Assets.JSON;\n\nexport const AssetStore = signalStore(\n { providedIn: 'root' },\n withState<AssetState>({\n map: {},\n isCachingDisabled: false,\n appLink: undefined,\n hostBase: undefined,\n hosted: false,\n }),\n withMethods(\n (store, http = inject(HttpService), storage = inject(StorageService)) => {\n const pending = new Map<string, Observable<unknown>>();\n const buildKey = (ns: string, type: string, name: string) =>\n `${ns}:${type}:${name}`;\n\n const getCached = (\n ns: string,\n type: string,\n name: string\n ): unknown | undefined => store.map()[ns]?.[type]?.[name];\n\n const setCached = (\n ns: string,\n type: string,\n name: string,\n value: unknown\n ): void => {\n // Skip update if value is the same reference\n const current = store.map()[ns]?.[type]?.[name];\n if (current === value) {\n return;\n }\n\n const updated = {\n ...store.map(),\n [ns]: {\n ...store.map()[ns],\n [type]: { ...store.map()[ns]?.[type], [name]: value },\n },\n };\n patchState(store, { map: updated });\n\n if (store.isCachingDisabled()) {\n return;\n }\n try {\n storage.setSession(STORAGE_KEY, updated);\n } catch {\n // quota exceeded — caching skipped\n }\n };\n\n return {\n setAppLink: (appLink: string) => patchState(store, { appLink }),\n setHostBase: (hostBase: string) => patchState(store, { hostBase }),\n setHosted: () => patchState(store, { hosted: true }),\n setCachingDisabled: (isDisabled: boolean) =>\n patchState(store, { isCachingDisabled: isDisabled }),\n\n resolve<T>(\n type: string,\n name: string,\n isOne = false,\n remoteBaseUrl?: string\n ): Observable<T> {\n const ns = isOne\n ? 'one'\n : remoteBaseUrl\n ? `remote:${remoteBaseUrl}`\n : (store.appLink() ?? 'host');\n\n const cached = getCached(ns, type, name);\n if (cached !== undefined) return of(cached as T);\n\n const key = buildKey(ns, type, name);\n const existingPending = pending.get(key);\n if (existingPending) {\n return existingPending as Observable<T>;\n }\n\n const assetType = inferAssetType(type);\n\n const fetchFromHost = (): Observable<T> => {\n const hostNs = store.appLink() ?? 'host';\n const isEmbeddedInHost = !!SharedStoreRegistry.getHostInjector();\n const baseUrl = remoteBaseUrl ?? (isEmbeddedInHost && store.appLink() ? http.buildWcAssetBaseUrl(store.appLink() as string) : undefined);\n return http\n .asset<T>([type, name], assetType, undefined, baseUrl)\n .pipe(tap((value) => setCached(hostNs, type, name, value)));\n };\n\n let request$: Observable<T>;\n\n if (isOne) {\n const oneTree = ['one', type, name];\n const oneFetch = http\n .asset<T>(oneTree, assetType)\n .pipe(tap((value) => setCached('one', type, name, value)));\n\n request$ = oneFetch.pipe(\n catchError((error) => {\n // If it's from one but not found, try host as fallback\n // only if it's not already a remote request (which has its own fallback)\n if (!remoteBaseUrl) {\n return fetchFromHost();\n }\n throw error;\n }),\n catchError(() => {\n // Remote fallback logic\n if (remoteBaseUrl) {\n const remoteNs = `remote:${remoteBaseUrl}`;\n if (!store.isCachingDisabled()) {\n const cached = getCached(remoteNs, type, name);\n if (cached !== undefined) return of(cached as T);\n }\n return http\n .asset<T>([type, name], assetType, undefined, remoteBaseUrl)\n .pipe(tap((value) => setCached(remoteNs, type, name, value)));\n }\n return throwError(() => new Error(`Asset not found: ${type}/${name}`));\n }),\n shareReplay(1),\n finalize(() => pending.delete(key))\n );\n } else {\n request$ = fetchFromHost().pipe(\n shareReplay(1),\n finalize(() => pending.delete(key))\n );\n }\n\n pending.set(key, request$);\n return request$;\n },\n };\n }\n ),\n withHooks({\n onInit(store, storage = inject(StorageService)) {\n const isLocal =\n typeof window !== 'undefined' &&\n (window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.hostname === '0.0.0.0');\n patchState(store, { isCachingDisabled: isLocal });\n\n if (!isLocal) {\n const saved = storage.getSession(STORAGE_KEY) as AssetMap | null;\n if (saved) patchState(store, { map: saved });\n }\n },\n })\n\n);\n","// MiniMark: closed-vocabulary text markup, not CommonMark. See libs/one/GLOSSARY.md\n// and docs/adr/0002-rich-text-output-minimark-plus-angular-sanitizer.md. Deliberately\n// supports only h1-h6, p, **bold**/__bold__, *italic*/_italic_, ~~strike~~, > blockquote, - list\n// (flat — indented bullets are siblings, indented non-bullet lines continue the\n// item above), [text](url) links, emoji passthrough. No images/tables/code/raw HTML — all `&<>`\n// from source text is escaped, so callers can bind the result with a plain\n// [innerHTML] and rely on Angular's own sanitizer as the only safety net.\n\nconst escapeHtml = (text: string): string =>\n text.replace(/&(?!#?\\w+;)/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst HEADING_RE = /^(#{1,6})\\s+(.*)$/;\nconst QUOTE_RE = /^>\\s?(.*)$/;\n// A leading indent is tolerated on a bullet: the list stays flat, so an indented\n// `- x` is a sibling item, never a nested list. An indented line without a bullet\n// is a wrapped continuation of the item above it (see CONTINUATION_RE).\nconst LIST_RE = /^[ \\t]*-[ \\t]+(.*)$/;\nconst CONTINUATION_RE = /^[ \\t]+(\\S.*)$/;\nconst LINK_RE = /\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g;\n\n// `__bold__` / `_italic_` are accepted as aliases of the `*` forms, but only at word\n// boundaries: an identifier like snake_case_name must stay literal text, so the\n// delimiter may not sit against a word character on the outside.\nconst UNDERSCORE_BOLD_RE = /(?<!\\w)__(.+?)__(?!\\w)/g;\nconst UNDERSCORE_ITALIC_RE = /(?<!\\w)_(.+?)_(?!\\w)/g;\n\n// Links are parsed before bold/italic/strike so those passes can never rewrite\n// characters inside an href. Each rendered anchor is parked behind a NUL-delimited\n// index token and spliced back once every other inline rule has run. Source text is\n// escaped upstream, so a NUL can only come from here.\n// eslint-disable-next-line no-control-regex\nconst TOKEN_RE = /\\u0000(\\d+)\\u0000/g;\n// eslint-disable-next-line no-control-regex\nconst CONTROL_RE = /[\\u0000-\\u001f\\u007f]/g;\n\nconst SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;\nconst ALLOWED_SCHEME_RE = /^(?:https?|mailto|tel):/i;\nconst EXTERNAL_RE = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\n\n/**\n * Accept http/https/mailto/tel plus protocol-relative and relative URLs; reject\n * every other scheme (javascript:, data:, vbscript:, file:). Angular's sanitizer\n * would drop those too, but the parser must not emit them in the first place.\n */\nconst sanitizeUrl = (raw: string): string | null => {\n const url = raw.replace(CONTROL_RE, '').trim();\n if (!url) return null;\n if (SCHEME_RE.test(url) && !ALLOWED_SCHEME_RE.test(url)) return null;\n return url.replace(/\"/g, '%22');\n};\n\nconst renderInline = (text: string, links: string[]): string => {\n let html = text.replace(LINK_RE, (match, label: string, url: string) => {\n const href = sanitizeUrl(url);\n if (!href) return match;\n const rel = EXTERNAL_RE.test(href)\n ? ' target=\"_blank\" rel=\"noopener noreferrer\"'\n : '';\n links.push(\n `<a href=\"${href}\"${rel}>${renderInline(label, links) || href}</a>`\n );\n return `\\u0000${links.length - 1}\\u0000`;\n });\n html = html.replace(\n /\\*\\*(.+?)\\*\\*/g,\n (_, inner: string) => `<strong>${renderInline(inner, links)}</strong>`\n );\n html = html.replace(\n UNDERSCORE_BOLD_RE,\n (_, inner: string) => `<strong>${renderInline(inner, links)}</strong>`\n );\n html = html.replace(\n /~~(.+?)~~/g,\n (_, inner: string) => `<s>${renderInline(inner, links)}</s>`\n );\n html = html.replace(\n /\\*(.+?)\\*/g,\n (_, inner: string) => `<em>${renderInline(inner, links)}</em>`\n );\n html = html.replace(\n UNDERSCORE_ITALIC_RE,\n (_, inner: string) => `<em>${renderInline(inner, links)}</em>`\n );\n return html;\n};\n\nconst parseInline = (text: string): string => {\n const links: string[] = [];\n return renderInline(text, links).replace(\n TOKEN_RE,\n (_, index: string) => links[Number(index)]\n );\n};\n\ntype BlockType = 'p' | 'blockquote' | 'ul';\n\n/**\n * Render MiniMark source text to an HTML string.\n */\nexport function miniMarkToHtml(source?: string): string {\n if (!source) return '';\n\n const blocks: string[] = [];\n let bufferType: BlockType | null = null;\n // One group per rendered unit: a group is a single `<li>` in a list, a single\n // source line elsewhere. Lines within a group are joined by <br>, matching how\n // MiniMark treats a single newline everywhere else.\n let buffer: string[][] = [];\n\n const renderGroup = (group: string[]): string =>\n group.map(parseInline).join('<br>');\n\n const flush = (): void => {\n if (bufferType && buffer.length) {\n if (bufferType === 'ul') {\n blocks.push(\n `<ul>${buffer.map((group) => `<li>${renderGroup(group)}</li>`).join('')}</ul>`\n );\n } else {\n const joined = buffer.map(renderGroup).join('<br>');\n blocks.push(\n bufferType === 'p'\n ? `<p>${joined}</p>`\n : `<blockquote>${joined}</blockquote>`\n );\n }\n }\n bufferType = null;\n buffer = [];\n };\n\n for (const rawLine of source.replace(/\\r\\n?/g, '\\n').split('\\n')) {\n if (!rawLine.trim()) {\n flush();\n continue;\n }\n\n const heading = HEADING_RE.exec(rawLine);\n if (heading) {\n flush();\n const level = heading[1].length;\n blocks.push(\n `<h${level}>${parseInline(escapeHtml(heading[2]))}</h${level}>`\n );\n continue;\n }\n\n const quote = QUOTE_RE.exec(rawLine);\n if (quote) {\n if (bufferType !== 'blockquote') flush();\n bufferType = 'blockquote';\n buffer.push([escapeHtml(quote[1])]);\n continue;\n }\n\n const item = LIST_RE.exec(rawLine);\n if (item) {\n if (bufferType !== 'ul') flush();\n bufferType = 'ul';\n buffer.push([escapeHtml(item[1])]);\n continue;\n }\n\n // An indented line inside a list is a wrapped item, not a new paragraph —\n // without this a soft-wrapped bullet would close the <ul> mid-list.\n const continuation =\n bufferType === 'ul' && buffer.length\n ? CONTINUATION_RE.exec(rawLine)\n : null;\n if (continuation) {\n buffer[buffer.length - 1].push(escapeHtml(continuation[1]));\n continue;\n }\n\n if (bufferType !== 'p') flush();\n bufferType = 'p';\n buffer.push([escapeHtml(rawLine)]);\n }\n flush();\n\n return blocks.join('');\n}\n","/**\n * The language and country the visitor's browser declares (GLOSSARY.md\n * Browser Locale). A hint that pre-fills and breaks ties, never an authority —\n * callers clamp `language` to their own list, and `country` is null rather\n * than guessed from the language (`en` is not `US`).\n */\nexport interface BrowserLocale {\n language: string | undefined;\n country: string | null;\n}\n\nconst COUNTRY = /^[A-Z]{2}$/;\n\nconst parseTag = (tag: string | undefined): BrowserLocale => {\n const [language, region] = (tag ?? '').split('-');\n const country = region?.toUpperCase();\n return {\n language: language ? language.toLowerCase() : undefined,\n country: country && COUNTRY.test(country) ? country : null,\n };\n};\n\n/**\n * Reads `navigator.language`; when that tag carries no region, the first of\n * `navigator.languages` that does supplies the country.\n */\nexport const browserLocale = (\n nav:\n | Pick<Navigator, 'language' | 'languages'>\n | undefined = typeof navigator === 'undefined' ? undefined : navigator\n): BrowserLocale => {\n const primary = parseTag(nav?.language);\n if (primary.country) return primary;\n const country =\n (nav?.languages ?? []).map(parseTag).find((locale) => locale.country)\n ?.country ?? null;\n return { language: primary.language, country };\n};\n","import { DestroyRef, inject, Injectable, signal } from '@angular/core';\nimport { BrowserLocale, browserLocale } from '../functions/browser-locale';\n\n/**\n * The Browser Locale as a signal — read once at start and again whenever the\n * visitor changes their browser languages (`languagechange`).\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class BrowserLocaleService {\n private readonly current = signal<BrowserLocale>(browserLocale());\n readonly locale = this.current.asReadonly();\n\n constructor() {\n if (typeof window === 'undefined') return;\n const handler = (): void => this.current.set(browserLocale());\n window.addEventListener('languagechange', handler);\n inject(DestroyRef).onDestroy(() =>\n window.removeEventListener('languagechange', handler)\n );\n }\n}\n","import { computed, inject, Injectable, linkedSignal, signal } from '@angular/core';\nimport { HttpService } from './http';\nimport { rxResource, toObservable } from '@angular/core/rxjs-interop';\nimport { catchError, forkJoin, map, of } from 'rxjs';\nimport { Assets } from '../enum/assets/assets';\nimport { AssetStore } from '../stores/asset.store';\nimport { miniMarkToHtml } from '../functions/text/mini-mark';\nimport { TRANSLATION_SOURCE } from '../config/tokens';\nimport { BrowserLocaleService } from './browser-locale';\n\n/** The language every key is authored in first — what a missing one reads as. */\nconst FALLBACK_LANG = 'en';\n\n/** The `@magmonium/one` half and the project half of one language. */\ntype TranslationPair = [Record<string, unknown>?, Record<string, unknown>?];\n\n@Injectable({\n providedIn: 'root',\n})\nexport class TranslateService {\n private readonly browserLocale = inject(BrowserLocaleService).locale;\n /** Set once the visitor picks a language — the Browser Locale stops leading. */\n private picked = false;\n /**\n * The visitor's pick, else their Browser Locale language — following it when\n * they change their browser languages, until they pick one here.\n */\n public readonly lang = linkedSignal<string | undefined, string>({\n source: () => this.browserLocale().language,\n computation: (language, previous) =>\n this.picked && previous ? previous.value : (language ?? 'en'),\n });\n private readonly path = signal<string[] | undefined>(['i18n'], {\n equal: (a, b) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n return a.every((v, i) => v === b[i]);\n },\n });\n private readonly country = computed(() => this.browserLocale().country);\n public readonly remoteAppId = signal<string | undefined>(undefined);\n /**\n * The mounted App's Default Language (store GLOSSARY.md): its keys load from\n * this file when the App ships none for `lang` — library keys still follow\n * `lang`.\n */\n public readonly remoteFallbackLang = signal<string | undefined>(undefined);\n\n private readonly httpService = inject(HttpService);\n private readonly assetStore = inject(AssetStore);\n\n /**\n * Every Remote mounted beside m-ui's single slot, counted per link so one\n * app mounted twice stays loaded until both mounts leave (ADR 0036).\n */\n private readonly mountedApps = signal<Record<string, number>>({});\n\n readonly mountRemoteApp = (link: string) =>\n this.mountedApps.update((apps) => ({ ...apps, [link]: (apps[link] ?? 0) + 1 }));\n\n readonly unmountRemoteApp = (link: string) =>\n this.mountedApps.update(({ [link]: count = 0, ...rest }) =>\n count > 1 ? { ...rest, [link]: count - 1 } : rest\n );\n\n private readonly remoteAppIds = computed(\n () => [\n ...new Set([\n ...(this.remoteAppId() ? [this.remoteAppId() as string] : []),\n ...Object.keys(this.mountedApps()),\n ]),\n ],\n { equal: (a, b) => a.length === b.length && a.every((v, i) => v === b[i]) }\n );\n\n private readonly remoteTranslation = rxResource({\n params: () => ({\n lang: this.lang(),\n appIds: this.remoteAppIds(),\n fallback: this.remoteFallbackLang(),\n }),\n stream: ({ params: { lang, appIds, fallback } }) => {\n if (!appIds.length) return of({});\n const bundle = (appId: string, name: string) =>\n this.httpService.asset<Record<string, unknown>>(\n ['i18n', name],\n Assets.JSON,\n undefined,\n this.httpService.buildWcAssetBaseUrl(appId)\n );\n return forkJoin(\n appIds.map((appId) =>\n bundle(appId, lang).pipe(\n catchError(() =>\n fallback && fallback !== lang\n ? bundle(appId, fallback).pipe(catchError(() => of({})))\n : of({})\n )\n )\n )\n ).pipe(map((bundles) => Object.assign({}, ...bundles)));\n },\n });\n\n private readonly langs = rxResource({\n params: this.path,\n stream: ({ params }) =>\n this.assetStore\n .resolve<\n Record<'langs', Record<string, string>>\n >((params ?? ['i18n']).join('/'), 'lang', true)\n .pipe(catchError(() => of({ langs: {} }))),\n });\n\n public readonly allLangs = computed(() => this.langs.value()?.langs ?? {});\n private readonly countryLangSource = rxResource({\n params: () => ({ country: this.country(), path: this.path() }),\n stream: ({ params: { country, path } }) =>\n country\n ? this.assetStore\n .resolve<string[]>((path ?? []).join('/'), `country-${country}`, true)\n .pipe(catchError(() => []))\n : of([]),\n });\n\n public readonly countryLangs = computed(() => {\n const countryLangs = {} as Record<string, string>;\n for (const [key, value] of Object.entries(this.allLangs())) {\n if (this.countryLangSource.value()?.includes(key)) {\n countryLangs[key] = value as string;\n }\n }\n return countryLangs;\n });\n\n private readonly translation = rxResource({\n params: () => ({\n lang: this.lang(),\n path: this.path(),\n remote: this.remoteTranslation.value(),\n }),\n // A language ships a share of `en`'s keys, so `en` lies underneath it: a\n // key the language lacks reads in English rather than as the bare key.\n // Language beats layer — a library key in `lang` wins a project one in `en`.\n stream: ({ params: { path, lang, remote } }) =>\n forkJoin([\n lang === FALLBACK_LANG\n ? of([{}, {}])\n : this.fetchTranslations([...(path ?? []), FALLBACK_LANG]),\n this.fetchTranslations([...(path ?? []), lang]),\n ]).pipe(\n map((results) => {\n const [[enOne = {}, enProject = {}], [one = {}, project = {}]] =\n results as [TranslationPair, TranslationPair];\n return {\n ...enOne,\n ...enProject,\n ...one,\n ...project,\n ...(remote as Record<string, unknown>),\n };\n })\n ),\n });\n\n public readonly translations$ = toObservable(this.translation.value);\n\n // Keys supplied from memory by a host app rather than fetched (see\n // TRANSLATION_SOURCE). Optional everywhere: only a visual editor provides it.\n private readonly translationSource = inject(TRANSLATION_SOURCE, {\n optional: true,\n });\n\n // What every lookup reads. The in-memory source wins over the fetched map so\n // that a key being edited right now beats the copy last fetched from disk.\n private readonly mergedTranslations = computed(() => ({\n ...((this.translation.value() ?? {}) as Record<string, unknown>),\n ...(this.translationSource?.() ?? {}),\n }));\n\n // The `@magmonium/one` half of the merge, on its own. A host app that lets a\n // User invent keys needs it to refuse the ones the library already ships:\n // project keys win the merge above, so inventing one silently rewords a\n // library string everywhere it appears.\n private readonly libraryTranslation = rxResource({\n params: () => ({ lang: this.lang(), path: this.path() }),\n stream: ({ params: { lang, path } }) =>\n this.assetStore\n .resolve<Record<string, unknown>>((path ?? []).join('/'), lang, true)\n .pipe(catchError(() => of({}))),\n });\n\n public readonly libraryKeys = computed(\n () => new Set(Object.keys(this.libraryTranslation.value() ?? {}))\n );\n\n private readonly links = rxResource({\n params: this.path,\n stream: ({ params }) =>\n this.fetchTranslations([...params, 'links']).pipe(\n map((result: [unknown, unknown] | unknown) => {\n const [one = {}, project = {}] = result as [\n Record<string, Record<string, string>>,\n Record<string, Record<string, string>>,\n ];\n return { ...one?.['links'], ...project?.['links'] };\n })\n ),\n });\n\n public setLang(lang: string): void {\n this.picked = true;\n if (lang !== this.lang()) {\n this.lang.set(lang);\n }\n }\n\n /**\n * Translate a key and return plain text\n * If no translation found in JSON, it will process the value directly\n */\n public readonly translate = (\n value?: string | number,\n config?: Record<string, string>\n ): string => {\n if (value == null) return '';\n if (typeof value === 'number') return value.toString();\n // YAML `label: true`/`false` compile to booleans; those names are also\n // real i18n keys (\"Yes\"/\"No\"), so coerce rather than throw. Any other\n // non-string used to crash in parseTranslationKey / key.split.\n if (typeof value === 'boolean') value = String(value);\n else if (typeof value !== 'string') return '';\n\n const { key, params } = this.parseTranslationKey(value);\n\n const translations = this.mergedTranslations();\n const result = key\n .split('.')\n .reduce(\n (obj: unknown, keyPart) =>\n typeof obj === 'object' && obj !== null\n ? ((obj as Record<string, unknown>)?.[keyPart] ?? '')\n : obj,\n translations\n );\n\n const mergedParams = { ...params, ...(config ?? {}) };\n\n // If translation found in JSON, use it\n if (typeof result === 'string' && result) {\n const textWithParams = this.replacePlaceholders(result, mergedParams);\n return this.addLink(textWithParams, config);\n }\n\n // If no translation found, process the original key directly\n // This allows direct translation like: \"$month,$year?month=january&year=2006\"\n const directTranslation = this.replacePlaceholders(key, mergedParams);\n return this.addLink(directTranslation, config);\n };\n\n /**\n * Translate a key and render the result as MiniMark HTML.\n * Returns a plain string — bind with a plain [innerHTML], not bypassSecurityTrustHtml.\n * Angular's own sanitizer is the safety net; see ADR 0002.\n */\n public readonly translateToHtml = (\n value?: string | number,\n config?: Record<string, string>\n ): string => {\n const translatedText = this.translate(value, config);\n return translatedText ? miniMarkToHtml(translatedText) : '';\n };\n\n public init(path: string[] = ['i18n']): void {\n this.path.set(path);\n }\n\n /**\n * Parse query string from translation key\n * Example: \"min_length?len=6&max=10\" => { key: \"min_length\", params: { len: \"6\", max: \"10\" } }\n */\n private parseTranslationKey(value: string): {\n key: string;\n params: Record<string, string>;\n } {\n if (!value.includes('?')) {\n return { key: value, params: {} };\n }\n\n const [key, queryString] = value.split('?');\n const params: Record<string, string> = {};\n\n const urlParams = new URLSearchParams(queryString);\n urlParams.forEach((val, paramKey) => {\n params[paramKey] = val;\n });\n\n return { key, params };\n }\n\n /**\n * Replace placeholders in translated text with actual values.\n *\n * Two forms, and the `$` is the whole difference:\n * - `<$len>` — the value is itself a translation key. It is looked up in the\n * translation JSON and the translation is substituted, so the text reads in\n * the User's language. Falls back to the raw value when the lookup misses.\n * `\"Should contain at least <$len> characters.\"` + `{ len: \"6\" }` → \"…at\n * least 6 characters.\"\n * - `<name>` — the value is substituted verbatim, no lookup. For data that\n * has no translation and must not acquire one by accident: a username, an\n * ID, a number already formatted by the caller.\n *\n * A placeholder with no matching param is left untouched for `addLink`, which\n * reads `<...>` as its own link-template markup.\n */\n private replacePlaceholders(\n text: string,\n params: Record<string, string>\n ): string {\n return text.replace(\n /<(\\$?)(\\w+)>/g,\n (match, dollar: string, placeholder: string) => {\n const value = params[placeholder];\n if (!Object.prototype.hasOwnProperty.call(params, placeholder)) {\n return match;\n }\n\n const resolved = dollar ? this.translateParameterValue(value) : value;\n\n // Escape HTML and markdown control characters in parameter values for security and formatting stability\n return this.escapeParam(resolved);\n }\n );\n }\n\n private escapeParam(text: string): string {\n const escapedHtml = this.escapeHtml(text);\n return escapedHtml\n .replace(/\\*/g, '*')\n .replace(/_/g, '_')\n .replace(/~/g, '~')\n .replace(/\\[/g, '[')\n .replace(/\\]/g, ']');\n }\n\n /**\n * Try to translate a parameter value by looking it up in translation JSON\n * If not found, return the original value\n */\n private translateParameterValue(value: string): string {\n if (!value) return value;\n\n const translations = this.mergedTranslations();\n\n // Try to look up the value in translations\n const result = value\n .split('.')\n .reduce(\n (obj: unknown, keyPart) =>\n typeof obj === 'object' && obj !== null\n ? (obj as Record<string, unknown>)?.[keyPart]\n : obj,\n translations\n );\n\n // If found and is a string, use it. Otherwise, return original value\n return typeof result === 'string' && result ? result : value;\n }\n\n private fetchTranslations(path: string[]) {\n const type = path.slice(0, -1).join('/');\n const name = path[path.length - 1];\n return forkJoin([\n this.assetStore.resolve(type, name, true).pipe(catchError(() => of({}))),\n this.assetStore.resolve(type, name).pipe(catchError(() => of({}))),\n ]).pipe(catchError(() => of([{}, {}])));\n }\n\n private formatDate(date: Date): string {\n return `${this.translate(\n `day.${date.getDay()}`\n )} ${date.getDate()} ${this.translate(\n `month.${date.getMonth()}`\n )},${date.getFullYear()}`;\n }\n\n private toReadableTime(date: string): string {\n return this.formatDate(new Date(date));\n }\n\n private getLink(key: string): string {\n return this.links.value()?.[key] ?? '';\n }\n\n private applyRule(text: string, type: string): string {\n return type === 'date' ? this.toReadableTime(text) : text;\n }\n\n private processLinkContent(\n content: string,\n config: Record<string, string>\n ): string {\n if (content.includes('~')) {\n const [text, linkKey] = content.split('~');\n const displayText =\n text.startsWith('$') && config[text]\n ? this.translate(config[text])\n : text;\n const link = this.getLink(linkKey) ?? config[linkKey];\n // Sanitize link URL to prevent XSS\n const sanitizedLink = link ? this.sanitizeUrl(link) : null;\n return sanitizedLink\n ? `<a href=\"${sanitizedLink}\">${this.escapeHtml(displayText)}</a>`\n : this.escapeHtml(displayText);\n }\n\n if (content.includes('%')) {\n const [key, type] = content.split('%');\n return this.escapeHtml(this.applyRule(config[key], type));\n }\n\n if (content.includes('@')) {\n const [text, alt] = content.split('@');\n const displayText =\n text.startsWith('$') && config[text]\n ? this.translate(config[text])\n : text;\n return `<a alt=\"${this.escapeHtml(alt)}\">${this.escapeHtml(\n displayText\n )}</a>`;\n }\n\n if (content.startsWith('$')) {\n const param = config[content] ?? config[content.substring(1)];\n // An unfilled slot stays visible rather than resolving to nothing.\n // `translate(undefined)` returns '', so `Found <$count> apps` rendered\n // as `Found apps` — the slot deleted itself and the sentence read as a\n // typo. `replacePlaceholders` already promises the opposite (\"a\n // placeholder with no matching param is left untouched\"), and every\n // caller documents `<$name>` as what an unfilled slot draws.\n if (param === undefined) return `<${content}>`;\n return this.escapeHtml(this.translate(param));\n }\n\n return `<${content}>`;\n }\n\n private readonly addLink = (\n text: string,\n config: Record<string, string> = {}\n ): string => {\n return text.replace(/<.+?>/g, (elem) =>\n this.processLinkContent(elem.slice(1, -1), config)\n );\n };\n\n /**\n * Render already-resolved MiniMark text to HTML, skipping translate()'s key\n * lookup / placeholder / addLink processing. Use this when the source is\n * literal authored content rather than a translation key (e.g. a\n * `noTranslate` config flag). Returns a plain string — see ADR 0002.\n */\n public readonly toSafeHtml = (text?: string): string => miniMarkToHtml(text);\n\n /**\n * Escape HTML special characters to prevent XSS\n */\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n /**\n * Sanitize URLs to prevent javascript: and data: URI XSS attacks\n */\n private sanitizeUrl(url: string): string {\n const trimmedUrl = url.trim().toLowerCase();\n\n // Block dangerous protocols\n const dangerousProtocols = ['javascript:', 'data:', 'vbscript:', 'file:'];\n if (\n dangerousProtocols.some((protocol) => trimmedUrl.startsWith(protocol))\n ) {\n return '#';\n }\n\n // Allow only http, https, mailto, and relative URLs\n if (\n trimmedUrl.startsWith('http:/') ||\n trimmedUrl.startsWith('https:/') ||\n trimmedUrl.startsWith('mailto:') ||\n trimmedUrl.startsWith('/') ||\n trimmedUrl.startsWith('#') ||\n trimmedUrl.startsWith('.')\n ) {\n return url;\n }\n\n // If no protocol specified, treat as relative URL\n if (!trimmedUrl.includes(':')) {\n return url;\n }\n\n // Block everything else\n return '#';\n }\n}\n","import { inject, Pipe, PipeTransform } from '@angular/core';\nimport { TranslateService } from '../services/translate';\n\n@Pipe({\n name: 'translate',\n pure: false,\n})\nexport class TranslatePipe implements PipeTransform {\n private readonly translateService = inject(TranslateService);\n\n transform(\n value?: string | number,\n config?: Record<string, string> | undefined\n ): string {\n // Only nullish / empty-string skip — boolean `false` and `0` are not\n // translation keys, and TranslateService already rejects non-strings.\n if (value == null || value === '') return '';\n return this.translateService.translate(value, config);\n }\n}\n","import { DEFAULT_SIZE, Size } from '../../enum/scaling/size';\n\n/**\n * The three Sizes as absolute lengths. Absolute rather than relative is what\n * makes a Size idempotent: a `sm` Section nested inside a `sm` Section renders\n * at 0.75rem, not at 0.75 of it (ADR 0008).\n */\nconst SIZE_LENGTH: Record<Size, string> = {\n [Size.SMALL]: '0.75rem',\n [Size.MEDIUM]: '1rem',\n [Size.LARGE]: '1.5rem',\n};\n\n/**\n * Total over the three Sizes. Deliberately accepts nothing else — the old\n * `derivedSize` ended in `default: return size`, which is how `1.3rem` and\n * `full-width` ended up in the assets. Lengths that are not Sizes go through\n * `toLength` instead.\n *\n * Non-Size values (empty string, legacy options like `xxs`/`n`) must not win\n * over the default: `size ?? DEFAULT` still picks them, and callers then write\n * `calc(undefined * 1.1)` onto Icons — glyph in the DOM, size zero on screen.\n */\nexport function resolveSize(size: Size | string | undefined): string {\n return SIZE_LENGTH[isSize(size) ? size : DEFAULT_SIZE];\n}\n\nexport function isSize(value: unknown): value is Size {\n return (\n value === Size.SMALL || value === Size.MEDIUM || value === Size.LARGE\n );\n}\n\n/**\n * First real Size among the candidates, else the default. Used by Section /\n * SectionForm / ButtonGroup so a bad `configs.size` (empty string, legacy\n * option) never becomes SIZE_CONTEXT and zero out every Icon underneath.\n */\nexport function coerceSize(\n ...candidates: Array<Size | string | undefined | null>\n): Size {\n for (const candidate of candidates) {\n if (isSize(candidate)) return candidate;\n }\n return DEFAULT_SIZE;\n}\n\n/**\n * A free CSS length for the things that are spacing or geometry rather than\n * Size — FlexContainer's gap, Jumbotron's margin and radius. Knows nothing\n * about Size, so the enum can no longer be borrowed for lengths.\n */\nexport function toLength(\n value: number | string | undefined,\n isNone?: true\n): string {\n if (value === undefined || value === null || value === '') {\n return isNone ? 'none' : '0';\n }\n return typeof value === 'number' ? `${value}em` : value;\n}\n\n/**\n * Box length for an Icon's square glyph. An explicit override wins over the\n * Size in force; otherwise the SizeContext length scaled by 1.1 — the same box\n * Icons paint at when they only inherit. A bare number (or a unitless numeric\n * string, the form attributes take) becomes `em`; any other string is a CSS\n * length as written. This is a length, not a Size: Size stays on Section /\n * ButtonGroup (ADR 0008); the Icon just opts out of that box when it must.\n */\nexport function resolveIconSize(\n override: number | string | undefined | null,\n contextSize?: Size | string | undefined\n): string {\n if (override === undefined || override === null || override === '') {\n return `calc(${resolveSize(contextSize)} * 1.1)`;\n }\n if (typeof override === 'number') return `${override}em`;\n const trimmed = override.trim();\n if (trimmed === '') return `calc(${resolveSize(contextSize)} * 1.1)`;\n if (/^\\d+(\\.\\d+)?$/.test(trimmed)) return `${trimmed}em`;\n return trimmed;\n}\n\n/**\n * A box dimension — min/max width and height. Unitless means px here, not em:\n * these read as box dimensions, matching Section's `height`, whereas `toLength`\n * serves spacing and defaults a bare number to `em`. Any other CSS length\n * (`50%`, `20vh`, `10em`) passes through untouched, and an empty value returns\n * `undefined` so the style binding is dropped rather than written as `''`.\n */\nexport function toCssLength(\n value: number | string | undefined\n): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'number') return `${value}px`;\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n return /^\\d+(\\.\\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed;\n}\n\n// `toLength` only appends `em` to real numbers — a numeric string comes back\n// bare, yielding `gap: 2`. Design-editor text fields, YAML and plain tag\n// attributes all hand over strings, so narrow before converting.\nconst toSpacingValue = (value: number | string): number | string => {\n if (typeof value !== 'string') return value;\n const trimmed = value.trim();\n if (trimmed === '' || Number.isNaN(Number(trimmed))) return value;\n return Number(trimmed);\n};\n\n/**\n * Spacing on the em scale — gap, padding, margin — or nothing at all: an unset\n * value drops the style binding rather than writing `toLength`'s `0` over what\n * CSS would have done.\n */\nexport function resolveSpacing(\n value: number | string | undefined | null\n): string | undefined {\n return value === undefined || value === null || value === ''\n ? undefined\n : toLength(toSpacingValue(value));\n}\n"],"mappings":";;;;;;AAMA,IAAY;CAAZ,SAAY,MAAI;CACd,KAAA,WAAA;CACA,KAAA,YAAA;CACA,KAAA,WAAA;AACF,EAAA,CAJY,SAAA,OAAI,CAAA,EAAA;AAMhB,MAAa,eAAe,KAAK;ACZjC,IAAY;CAAZ,SAAY,QAAM;CAChB,OAAA,UAAA;CACA,OAAA,SAAA;CACA,OAAA,SAAA;CACA,OAAA,SAAA;CAEA,OAAA,QAAA;AACF,EAAA,CAPY,WAAA,SAAM,CAAA,EAAA;ACIlB,MAAa,sBAAsB;CACjC,SAAS;CACT,KAAK;CACL,KAAK;CACL,MAAM;CACN,WAAW;CAGX,sBAAsB;CACtB,cAAc;CACd,kBAAkB;CAClB,aAAa;CACb,MAAM;CACN,eAAe;AACP;ACbV,MAAa,oBAAoB;CAC/B,MAAM;CACN,OAAO;CAGP,SAAS;CAGT,UAAU;AACF;ACyEV,IAAY;CAAZ,SAAY,iBAAe;CACzB,gBAAA,gBAAA,WAAA,KAAA;CACA,gBAAA,gBAAA,kBAAA,KAAA;CACA,gBAAA,gBAAA,UAAA,KAAA;CACA,gBAAA,gBAAA,2BAAA,KAAA;CACA,gBAAA,gBAAA,uBAAA,KAAA;CACA,gBAAA,gBAAA,sBAAA,KAAA;CACA,gBAAA,gBAAA,0BAAA,KAAA;AACF,EAAA,CARY,oBAAA,kBAAe,CAAA,EAAA;AAmE3B,IAAY;CAAZ,SAAY,iBAAe;CACzB,gBAAA,gBAAA,cAAA,KAAA;CACA,gBAAA,gBAAA,eAAA,KAAA;CACA,gBAAA,gBAAA,aAAA,KAAA;CACA,gBAAA,gBAAA,UAAA,KAAA;AACF,EAAA,CALY,oBAAA,kBAAe,CAAA,EAAA;AA0D3B,MAAa,kBAAkB,IAAI,eACjC,iBAAiB;AAEnB,MAAa,cAAc,IAAI,eAC7B,aAAa;AAMf,MAAa,YAAY,IAAI,eAAwB,WAAW;AAChE,MAAa,iBAAiB,IAAI,eAAuB,gBAAgB;AACzE,MAAa,qBAAqB,IAAI,eACpC,oBAAoB;AAEtB,MAAa,eAAe,IAAI,eAC9B,cAAc;AAEhB,MAAa,uBAAuB;AACpC,MAAa,mBAAmB,IAAI,eAElC,kBAAkB;AACpB,MAAa,gBAAgB,IAAI,eAA4B,eAAe;AAuB5E,MAAa,kBAAkB,IAAI,eACjC,iBAAiB;AAWnB,MAAa,iBAAiB,IAAI,eAChC,gBAAgB;AAGlB,MAAa,kBAAkB,IAAI,eACjC,iBAAiB;AASnB,MAAa,WAAW,IAAI,eAC1B,YACA;CAAE,YAAY;CAAQ,eAAe,OAA2B,MAAS;AAAC,CAAE;AAQ9E,MAAa,sBAAsB,IAAI,eACrC,qBAAqB;AAGvB,MAAa,gBAAgB,IAAI,eAAwB,eAAe;AAOxE,MAAa,cAAc,IAAI,eAE7B,aAAa;AAQf,MAAa,qBAAqB,IAAI,eAEpC,oBAAoB;AAStB,MAAa,iBAAiB,IAAI,eAEhC,gBAAgB;AAKlB,MAAa,2BAA2B,IAAI,eAE1C,0BAA0B;AAI5B,MAAa,uBAAuB,IAAI,eACtC,sBAAsB;AAMxB,MAAa,iBAAiB,IAAI,eAAwB,gBAAgB;ACvV1E,SAAgB,eAAe,QAAe;CAC5C,IAAI,CAAC,UAAU,OAAO,WAAW,UAC/B,OAAO;CAET,OAAO,cAAc;AACvB;AAEA,MAAM,kBAAkB;AACxB,MAAM,gCAAgB,IAAI,IAAI;CAAC;CAAS;CAAQ;AAAW,CAAC;AAE5D,SAAS,kBAAkB,QAAc;CACvC,MAAM,OAAO,IAAI,gBAAgB,MAAM,CAAC,CAAC,IAAI,MAAM;CACnD,OAAO,QAAQ,cAAc,IAAI,IAAI,IAAI,OAAO;AAClD;AAEA,SAAgB,cAAc,UAAmB,QAAe;CAC9D,IAAI,aAAa,UAAa,gBAAgB,KAAK,QAAQ,GAAG,OAAO;CACrE,IAAI,WAAW,UAAa,CAAC,CAAC,kBAAkB,MAAM,GAAG,OAAO;CAChE,OAAO;AACT;AAEA,SAAgB,uBAAuB,UAAkB,QAAe;CACtE,OAAO,gBAAgB,KAAK,QAAQ,CAAC,GAAG,OAAO,SAAS,kBAAkB,MAAM,IAAI;AACtF;AAEA,MAAa,cACX,OAAO,WAAW,gBACjB,OAAO,SAAS,aAAa,eAC5B,OAAO,SAAS,aAAa,eAC7B,OAAO,SAAS,aAAa;AAEjC,SAAgB,eAAe,KAAW;CACxC,IAAI;EACF,MAAM,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC;EAC1B,OAAO,SAAS,eAAe,SAAS,eAAe,SAAS;CAClE,QAAQ;EACN,OAAO;CACT;AACF;ACRA,MAAM,mBACJ,OAAO,WAAW,cAAe,SAAwB;AAG3D,SAAgB,UAAU,UAAkB,MAAwB;CAClE,MAAM,MAAM,WAAU;CACtB,IAAI,CAAC,KAAK;CACV,MAAM,QAAQ,EAAE,GAAI,IAAI,0BAA0B,CAAA,EAAG;CACrD,IAAI,MAAM,MAAM,YAAY;MACvB,OAAO,MAAM;CAClB,IAAI,yBAAyB;AAC/B;AAGA,SAAgB,eAAe,UAAkB,MAAwB;CACvE,MAAM,MAAM,WAAU;CACtB,IAAI,CAAC,KAAK;CACV,MAAM,QAAQ,EAAE,GAAI,IAAI,gCAAgC,CAAA,EAAG;CAC3D,IAAI,MAAM,MAAM,YAAY;MACvB,OAAO,MAAM;CAClB,IAAI,+BAA+B;AACrC;AAOA,SAAgB,cAAc,UAAgB;CAC5C,MAAM,MAAM,WAAU;CACtB,IAAI,KAAK,yBAAyB,cAAc,SAAS,OAAO;CAChE,MAAM,OAAO,IAAI,+BAA+B;CAChD,OAAO,QAAQ,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,QACxD,oBAAoB,KAAI,WACxB;AACN;AAEA,SAAgB,SAAS,UAAgB;CACvC,OAAO,WAAU,CAAE,EAAE,yBAAyB;AAChD;AAGA,SAAgB,gBAAgB,UAAgB;CAC9C,OAAO,WAAU,CAAE,EAAE,iCAAiC;AACxD;AAGA,SAAgB,kBAAkB,UAAgB;CAChD,OAAO,WAAU,CAAE,EAAE,mCAAmC;AAC1D;AAEA,SAAgB,oBACd,UACA,MACA,QAAe;CAEf,MAAM,MAAM,WAAU;CACtB,IAAI,CAAC,KAAK;CACV,IAAI,iCAAiC;EACnC,GAAI,IAAI,kCAAkC,CAAA;GACzC,WAAW;CACb;CACD,IAAI,QACF,IAAI,mCAAmC;EACrC,GAAI,IAAI,oCAAoC,CAAA;GAC3C,WAAW;CACb;AACL;AAEA,SAAgB,eAAe,QAAgB,UAAgB;CAE7D,MAAM,QAAQ,cAAc,QAAQ;CACpC,IAAI,OAAO,OAAO;CAClB,IAAI,WAAU,CAAE,EAAE,0BAChB,OAAO;CAET,IAAI,aACF,OAAO,iBAAiB,SAAQ;CAGlC,OAAO,GAAG,OAAM,eAAgB,WADnB,SAAS,QACqB,MAAS,SAAS,UAAU;AACzE;ACtFA,MAAa,iCAAiB,IAAI,IAAI;CAAC;CAAQ;CAAQ;AAAO,CAAC;AAK/D,IAAa,cAAb,MAAa,YAAW;CACL,OAAmB,OAAO,UAAU;CAC7C,MAAM;CACN,UAAU;CACV,WAAW,OAAO,gBAAgB,EAAE,UAAU,KAAI,CAAE,KAAK;CACzD,cACN,OAAO,oBAAoB,EAAE,UAAU,KAAI,CAAE,KAAK;CAC5C,YAAY;CAEpB,IACE,QACA,MACA,SACA,QAAoB;EAEpB,OAAO,KAAK,KAAK,IAAO,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,EAC7D,QAAQ,KAAK,SAAS,MAAM,EAC7B,CAAA;CACH;CAKA,IACE,QACA,MACA,MACA,SACA,QAAoB;EAEpB,OAAO,KAAK,KAAK,IAAO,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,MAAM,EACnE,QAAQ,KAAK,SAAS,MAAM,EAC7B,CAAA;CACH;CAEA,KACE,QACA,MACA,MACA,SACA,QAAoB;EAEpB,OAAO,KAAK,KAAK,KAAQ,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,MAAM,EACpE,QAAQ,KAAK,SAAS,MAAM,EAC7B,CAAA;CACH;CAEA,MACE,QACA,MACA,MACA,SACA,QAAoB;EAEpB,OAAO,KAAK,KAAK,MAAS,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,MAAM,EACrE,QAAQ,KAAK,SAAS,MAAM,EAC7B,CAAA;CACH;CAEA,YACE,QACA,MACA,MACA,SAAiB;EAEjB,OAAO,KAAK,KAAK,MAAM,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,MAAM;GAClE,SAAS;GACT,cAAc;GACd,gBAAgB;EACjB,CAAA;CACH;CAEA,WACE,QACA,MACA,MACA,SAAiB;EAEjB,OAAO,KAAK,KAAK,KAAK,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,MAAM;GACjE,SAAS;GACT,cAAc;GACd,gBAAgB;EACjB,CAAA;CACH;CAEA,OACE,QACA,MACA,SACA,QAAoB;EAEpB,OAAO,KAAK,KAAK,OAAU,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG,EAChE,QAAQ,KAAK,SAAS,MAAM,EAC7B,CAAA;CACH;CAEA,eACE,QACA,MACA,MACA,SACA,QAAoB;EAEpB,OAAO,KAAK,KAAK,OAAU,KAAK,UAAU,QAAQ,MAAM,OAAO,GAAG;GAChE;GACA,QAAQ,KAAK,SAAS,MAAM;EAC7B,CAAA;CACH;CAEA,OAAO,KAAW;EAChB,KAAK,MAAM;CACb;CAEA,SAAM;EACJ,OAAO,KAAK;CACd;CAEA,WAAW,KAAW;EACpB,KAAK,UAAU;CACjB;CAEA,aAAU;EACR,OAAO,KAAK;CACd;CAEA,SACE,QACA,MACA,SAAiB;EAEjB,OAAO,KAAK,UAAU,QAAQ,MAAM,OAAO;CAC7C;CAEA,YAAY,KAAW;EACrB,KAAK,WAAW;CAClB;CAEA,eAAe,KAAW;EACxB,KAAK,cAAc;CACrB;CAEA,aAAa,KAAW;EACtB,KAAK,YAAY;CACnB;CAEA,KAAK,KAAW;EACd,OAAO,KAAK,KAAK,IAAI,KAAK,EAAE,cAAc,OAAM,CAAE;CACpD;CAGA,KAAK,KAAW;EACd,OAAO,KAAK,KAAK,IAAI,KAAK,EAAE,cAAc,OAAM,CAAE;CACpD;CAEA,GAAM,MAAc,UAAkB;EACpC,MAAM,QAAQ,cAAc,IAAI;EAChC,IAAI,OAAO,OAAO,KAAK,KAAK,IAAO,GAAG,MAAK,GAAI,SAAS,KAAK,GAAG,GAAG;EACnE,IAAI,aACF,OAAO,KAAK,KAAK,IAAO,iBAAiB,KAAI,MAAO,SAAS,KAAK,GAAG,GAAG;EAE1E,MAAM,OAAO,SAAS,IAAI;EAC1B,OAAO,KAAK,IAAO,SAAS;GAAC;GAAM;GAAM,GAAI,SAAS,SAAS,CAAC,IAAI,IAAI,CAAA;GAAK,GAAG;EAAQ,CAAC;CAC3F;CAEA,WAAW,MAAY;EACrB,OAAO,eAAe,KAAK,KAAK,IAAI;CACtC;CAEO,oBAAoB,MAAY;EACrC,OAAO,KAAK,WAAW,IAAI;CAC7B;CAEO,gBAAgB,MAAc,MAAY;EAC/C,MAAM,aAAa,KAAK,WAAW,SAAS,IACxC,KAAK,MAAM,CAAgB,IAC3B;EACJ,OAAO,KAAK,KAAK,KAAK,oBAAoB,IAAI,GAAG,UAAU;CAC7D;CAEO,YACL,MACA,WAAW,OAAK;EAEhB,IAAI,CAAC,MAAM,OAAO;EAClB,IACE,KAAK,WAAW,MAAM,KACtB,KAAK,WAAW,OAAO,KACvB,KAAK,WAAW,OAAO,GAEvB,OAAO;EAET,MAAM,OAAO,WAAW,KAAK,WAAW,KAAK;EAC7C,OAAO,KAAK,KAAK,MAAM,IAAI;CAC7B;CAEO,aAAa,MAA+B;EACjD,IAAI,CAAC,MAAM,OAAO;EAClB,IAAI,KAAK,WAAW,MAAM,GAAG,OAAO;EACpC,OAAO,KAAK,KAAK,KAAK,WAAW,IAAI;CACvC;CAOO,MAAM,WAAW,KAAW;EACjC,IAAI,IAAI,WAAW,MAAM,KAAK,CAAC,IAAI,WAAW,OAAO,SAAS,MAAM,GAClE,IAAI;GACF,MAAM,SAAS,MAAM,eACnB,KAAK,KAAK,IAAI,KAAK,EAAE,cAAc,OAAM,CAAE,CAAC;GAE9C,MAAM,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,yBAAwB,CAAE;GAClE,OAAO,IAAI,OAAO,IAAI,gBAAgB,IAAI,CAAC;EAC7C,SAAS,OAAO;GACd,QAAQ,KACN,4EACA,KAAK;GAGP,MAAM,OAAO,IAAI,KAAK,CAAC,kBAAkB,IAAG,GAAI,GAAG,EACjD,MAAM,yBACP,CAAA;GACD,OAAO,IAAI,OAAO,IAAI,gBAAgB,IAAI,CAAC;EAC7C;EAEF,OAAO,IAAI,OAAO,GAAG;CACvB;CAEQ,KAAK,MAAc,MAAY;EAGrC,OAAO,GAFG,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,KAExC,GADD,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI;CAEnD;CAEA,MACE,MACA,MACA,SACA,SAAgB;EAEhB,MAAM,eACJ,YAAY,KAAK,OAAO,QAAQ,KAAK,cAAc,KAAK;EAC1D,MAAM,MAAM,KAAK,KAAK,cAAc,GAAG,KAAK,KAAK,GAAG,EAAC,GAAI,MAAM;EAE/D,MAAM,iBAAiB;GACrB,GAAG;GACH,cAAc,KAAK,wBAAwB,IAAI;EAChD;EAED,OAAO,KAAK,KAAK,IAAO,KAAK,cAAc;CAC7C;CAEQ,UACN,QACA,MACA,SAAiB;EAGjB,OAAO,GADM,eAAe,IAAI,MAAM,IAAI,KAAK,UAAU,KAAK,IAChD,GAAI,OAAM,GAAI,WAAW,KAAI,GAAI,KAAK,KAAK,GAAG;CAC9D;CAOQ,SAAS,QAAoB;EACnC,IAAI,CAAC,QAAQ,OAAO;EACpB,IAAI,QAAQ,IAAI,WAAU;EAC1B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;GACjD,IAAI,UAAU,UAAa,UAAU,MAAM;GAC3C,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,QAAQ,OAAO,QAAQ,MAAM,OAAO,KAAK,OAAO,IAAI,CAAC;QAEhE,QAAQ,MAAM,IAAI,KAAK,OAAO,KAAK,CAAC;EAExC;EACA,OAAO,MAAM,KAAI,CAAE,CAAC,SAAS,QAAQ;CACvC;CAEQ,2BAA2B,WAAkB;EACnD,IAAI,eAAyC;EAC7C,QAAQ,QAAR;GACE,KAAK,OAAO;GACZ,KAAK,OAAO;GACZ,KAAK,OAAO;IACV,eAAe;IACf;GACF,KAAK,OAAO;IACV,eAAe;IACf;GACF,KAAK,OAAO;GACZ,SACE,eAAe;EAEnB;EACA,OAAO;CACT;CA1SW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAW,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAX,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAW,YAFV;CAAM,CAAA;;AAEP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAW,YAAA,CAAA;EAHvB,MAAA;EAAW,MAAA,CAAA,EACV,YAAY,OACb,CAAA;;;AC/BD,SAAgB,OAAO,MAAa;CAClC,IAAI,OAAO,SAAS,UAClB,IAAI;EACF,KAAK,MAAM,IAAI;CACjB,QAAQ;EACN,OAAO;CACT;CAEF,OAAO;AACT;ACFA,IAAa,iBAAb,MAAa,eAAc;CAQlB,QAAW,KAAa,OAAU,QAAmB,SAAO;EACjE,MAAM,aAAa,KAAK,MAAM,KAAK;EACnC,IAAI,UAAU,QAAW;GACvB,WAAW,WAAW,GAAG;GACzB;EACF;EACA,WAAW,QAAQ,KAAK,KAAK,UAAU,KAAK,CAAC;CAC/C;CAQO,QAAW,KAAa,QAAmB,SAAO;EACvD,MAAM,MAAM,KAAK,MAAM,KAAK,CAAC,CAAC,QAAQ,GAAG;EACzC,IAAI,QAAQ,MAAM,OAAO;EACzB,IAAI;GACF,OAAO,KAAK,MAAM,GAAG;EACvB,QAAQ;GACN;EACF;CACF;CAEQ,MAAM,OAAgB;EAC5B,OAAO,UAAU,YAAY,iBAAiB;CAChD;CAEO,WAAW,KAAa,OAAc;EAC3C,IAAI,OAAO;GACT,IAAI,OAAO,KAAK,GACd,eAAe,QAAQ,KAAK,KAAK,UAAU,KAAK,CAAC;QAEjD,eAAe,QAAQ,KAAK,OAAO,KAAK,CAAC;EAE7C;CACF;CAEO,WAAW,KAAW;EAC3B,MAAM,OAAO,eAAe,QAAQ,GAAG;EACvC,IAAI,QAAQ,OAAO,IAAI,GACrB,OAAO,KAAK,MAAM,IAAI;OAEtB,OAAO;CAEX;CAEO,cAAc,KAAW;EAC9B,eAAe,WAAW,GAAG;CAC/B;CAEO,SAAS,KAAa,OAAc;EACzC,IAAI,OAAO,KAAK,GACd,aAAa,QAAQ,KAAK,KAAK,UAAU,KAAK,CAAC;OAE/C,aAAa,QAAQ,KAAK,OAAO,KAAK,CAAC;CAE3C;CAEO,SAAS,KAAW;EACzB,MAAM,OAAO,aAAa,QAAQ,GAAG;EACrC,IAAI,QAAQ,OAAO,IAAI,GACrB,OAAO,KAAK,MAAM,IAAI;OAEtB,OAAO;CAEX;CAEO,YAAY,KAAW;EAC5B,aAAa,WAAW,GAAG;CAC7B;CA/EW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,YADD;CAAM,CAAA;;AACnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EAD1B,MAAA;EAAW,MAAA,CAAA,EAAE,YAAY,OAAM,CAAE;;;ACmBlC,IAAa,sBAAb,MAAgC;CAC9B,OAAO,YAAY,OAAc;EAC/B,KAAK,MAAK;EACV,IAAI,CAAC,OAAO,aAAa,UACvB,OAAO,aAAa,WAAW;CAEnC;CAEA,OAAO,cAAW;EAChB,OAAO,OAAO,cAAc;CAC9B;CAEA,OAAO,cAAc,OAAc;EACjC,KAAK,MAAK;EACV,IAAI,CAAC,OAAO,aAAa,YACvB,OAAO,aAAa,aAAa;CAErC;CAEA,OAAO,gBAAa;EAClB,OAAO,OAAO,cAAc;CAC9B;CAGA,OAAO,qBAAqB,OAAc;EACxC,KAAK,MAAK;EACV,IAAI,CAAC,OAAO,aAAa,mBACvB,OAAO,aAAa,oBAAoB;CAE5C;CAEA,OAAO,uBAAoB;EACzB,OAAO,OAAO,cAAc;CAC9B;CACA,OAAO,gBAAgB,UAAkB;EACvC,KAAK,MAAK;EACV,OAAO,aAAa,eAAe;CACrC;CAEA,OAAO,kBAAe;EACpB,OAAO,OAAO,cAAc;CAC9B;CAEA,OAAO,gBAAa;EAClB,OAAO,OAAO,cAAc;CAC9B;CAEA,OAAO,sBAAmB;EACxB,OAAO,OAAO,cAAc;CAC9B;CAEA,OAAO,cAAc,OAAc;EACjC,KAAK,MAAK;EACV,OAAO,aAAa,aAAa;CACnC;CAGA,OAAO,oBAAoB,SAAgB;EACzC,KAAK,MAAK;EACV,IAAI,CAAC,OAAO,aAAa,kBACvB,OAAO,aAAa,mBAAmB;CAE3C;CAGA,OAAO,kBAAkB,SAA0B;EACjD,KAAK,MAAK;EACV,IAAI,CAAC,OAAO,aAAa,gBACvB,OAAO,aAAa,iBAAiB;CAEzC;CAEA,OAAO,oBAAiB;EACtB,OAAO,OAAO,cAAc;CAC9B;CAGA,OAAO,aAAa,KAAW;EAC7B,KAAK,MAAK;EACV,IAAI,CAAC,OAAO,aAAa,WACvB,OAAO,aAAa,YAAY;CAEpC;CAEA,OAAO,qBAAkB;EACvB,OAAO,CAAC,CAAC,OAAO,cAAc;CAChC;CAEQ,OAAO,QAAK;EAClB,IAAI,CAAC,OAAO,cACV,OAAO,eAAe,CAAA;CAE1B;AACD;ACzFD,MAAM,cAAc;AAEpB,MAAM,kBAAkB,WACtB,WAAW,UAAU,OAAO,MAAM,OAAO;AAE3C,MAAa,aAAa,YACxB,EAAE,YAAY,OAAM,GACpB,UAAsB;CACpB,KAAK,CAAA;CACL,mBAAmB;CACnB,SAAS;CACT,UAAU;CACV,QAAQ;AACT,CAAA,GACD,aACG,OAAO,OAAO,OAAO,WAAW,GAAG,UAAU,OAAO,cAAc,MAAK;CACtE,MAAM,0BAAU,IAAI,IAAG;CACvB,MAAM,YAAY,IAAY,MAAc,SAC1C,GAAG,GAAE,GAAI,KAAI,GAAI;CAEnB,MAAM,aACJ,IACA,MACA,SACwB,MAAM,IAAG,CAAE,CAAC,GAAG,GAAG,KAAK,GAAG;CAEpD,MAAM,aACJ,IACA,MACA,MACA,UACQ;EAGR,IADgB,MAAM,IAAG,CAAE,CAAC,GAAG,GAAG,KAAK,GAAG,UAC1B,OACd;EAGF,MAAM,UAAU;GACd,GAAG,MAAM,IAAG;IACX,KAAK;IACJ,GAAG,MAAM,IAAG,CAAE,CAAC;KACd,OAAO;KAAE,GAAG,MAAM,IAAG,CAAE,CAAC,GAAG,GAAG;MAAQ,OAAO;IAAK;GACpD;EACF;EACD,WAAW,OAAO,EAAE,KAAK,QAAO,CAAE;EAElC,IAAI,MAAM,kBAAiB,GACzB;EAEF,IAAI;GACF,QAAQ,WAAW,aAAa,OAAO;EACzC,QAAQ,CAER;CACF;CAEA,OAAO;EACL,aAAa,YAAoB,WAAW,OAAO,EAAE,QAAO,CAAE;EAC9D,cAAc,aAAqB,WAAW,OAAO,EAAE,SAAQ,CAAE;EACjE,iBAAiB,WAAW,OAAO,EAAE,QAAQ,KAAI,CAAE;EACnD,qBAAqB,eACnB,WAAW,OAAO,EAAE,mBAAmB,WAAU,CAAE;EAErD,QACE,MACA,MACA,QAAQ,OACR,eAAsB;GAEtB,MAAM,KAAK,QACP,QACA,gBACE,UAAU,kBACT,MAAM,QAAO,KAAM;GAE1B,MAAM,SAAS,UAAU,IAAI,MAAM,IAAI;GACvC,IAAI,WAAW,QAAW,OAAO,GAAG,MAAW;GAE/C,MAAM,MAAM,SAAS,IAAI,MAAM,IAAI;GACnC,MAAM,kBAAkB,QAAQ,IAAI,GAAG;GACvC,IAAI,iBACF,OAAO;GAGT,MAAM,YAAY,eAAe,IAAI;GAErC,MAAM,sBAAoC;IACxC,MAAM,SAAS,MAAM,QAAO,KAAM;IAClC,MAAM,mBAAmB,CAAC,CAAC,oBAAoB,gBAAe;IAC9D,MAAM,UAAU,kBAAkB,oBAAoB,MAAM,QAAO,IAAK,KAAK,oBAAoB,MAAM,QAAO,CAAY,IAAI;IAC9H,OAAO,KACJ,MAAS,CAAC,MAAM,IAAI,GAAG,WAAW,QAAW,OAAO,CAAC,CACrD,KAAK,KAAK,UAAU,UAAU,QAAQ,MAAM,MAAM,KAAK,CAAC,CAAC;GAC9D;GAEA,IAAI;GAEJ,IAAI,OAAO;IACT,MAAM,UAAU;KAAC;KAAO;KAAM;IAAI;IAKlC,WAJiB,KACd,MAAS,SAAS,SAAS,CAAC,CAC5B,KAAK,KAAK,UAAU,UAAU,OAAO,MAAM,MAAM,KAAK,CAAC,CAE/C,CAAA,CAAS,KAClB,YAAY,UAAS;KAGnB,IAAI,CAAC,eACH,OAAO,cAAa;KAEtB,MAAM;IACR,CAAC,GACD,iBAAgB;KAEd,IAAI,eAAe;MACjB,MAAM,WAAW,UAAU;MAC3B,IAAI,CAAC,MAAM,kBAAiB,GAAI;OAC9B,MAAM,SAAS,UAAU,UAAU,MAAM,IAAI;OAC7C,IAAI,WAAW,QAAW,OAAO,GAAG,MAAW;MACjD;MACA,OAAO,KACJ,MAAS,CAAC,MAAM,IAAI,GAAG,WAAW,QAAW,aAAa,CAAC,CAC3D,KAAK,KAAK,UAAU,UAAU,UAAU,MAAM,MAAM,KAAK,CAAC,CAAC;KAChE;KACA,OAAO,iCAAiB,IAAI,MAAM,oBAAoB,KAAI,GAAI,MAAM,CAAC;IACvE,CAAC,GACD,YAAY,CAAC,GACb,eAAe,QAAQ,OAAO,GAAG,CAAC,CAAC;GAEvC,OACE,WAAW,cAAa,CAAE,CAAC,KACzB,YAAY,CAAC,GACb,eAAe,QAAQ,OAAO,GAAG,CAAC,CAAC;GAIvC,QAAQ,IAAI,KAAK,QAAQ;GACzB,OAAO;EACT;CACD;AACH,CAAC,GAEH,UAAU,EACR,OAAO,OAAO,UAAU,OAAO,cAAc,GAAC;CAC5C,MAAM,UACJ,OAAO,WAAW,gBACjB,OAAO,SAAS,aAAa,eAC5B,OAAO,SAAS,aAAa,eAC7B,OAAO,SAAS,aAAa;CACjC,WAAW,OAAO,EAAE,mBAAmB,QAAO,CAAE;CAEhD,IAAI,CAAC,SAAS;EACZ,MAAM,QAAQ,QAAQ,WAAW,WAAW;EAC5C,IAAI,OAAO,WAAW,OAAO,EAAE,KAAK,MAAK,CAAE;CAC7C;AACF,EACD,CAAA,CAAC;AClLJ,MAAM,cAAc,SAClB,KAAK,QAAQ,gBAAgB,OAAO,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAM;AAElF,MAAM,aAAa;AACnB,MAAM,WAAW;AAIjB,MAAM,UAAU;AAChB,MAAM,kBAAkB;AACxB,MAAM,UAAU;AAKhB,MAAM,qBAAqB;AAC3B,MAAM,uBAAuB;AAO7B,MAAM,WAAW;AAEjB,MAAM,aAAa;AAEnB,MAAM,YAAY;AAClB,MAAM,oBAAoB;AAC1B,MAAM,cAAc;AAOpB,MAAM,eAAe,QAA8B;CACjD,MAAM,MAAM,IAAI,QAAQ,YAAY,EAAE,CAAC,CAAC,KAAI;CAC5C,IAAI,CAAC,KAAK,OAAO;CACjB,IAAI,UAAU,KAAK,GAAG,KAAK,CAAC,kBAAkB,KAAK,GAAG,GAAG,OAAO;CAChE,OAAO,IAAI,QAAQ,MAAM,KAAK;AAChC;AAEA,MAAM,gBAAgB,MAAc,UAA2B;CAC7D,IAAI,OAAO,KAAK,QAAQ,UAAU,OAAO,OAAe,QAAe;EACrE,MAAM,OAAO,YAAY,GAAG;EAC5B,IAAI,CAAC,MAAM,OAAO;EAClB,MAAM,MAAM,YAAY,KAAK,IAAI,IAC7B,mDACA;EACJ,MAAM,KACJ,YAAY,KAAI,GAAI,IAAG,GAAI,aAAa,OAAO,KAAK,KAAK,KAAI,KAAM;EAErE,OAAO,SAAS,MAAM,SAAS,EAAC;CAClC,CAAC;CACD,OAAO,KAAK,QACV,mBACC,GAAG,UAAkB,WAAW,aAAa,OAAO,KAAK,EAAC,UAAW;CAExE,OAAO,KAAK,QACV,qBACC,GAAG,UAAkB,WAAW,aAAa,OAAO,KAAK,EAAC,UAAW;CAExE,OAAO,KAAK,QACV,eACC,GAAG,UAAkB,MAAM,aAAa,OAAO,KAAK,EAAC,KAAM;CAE9D,OAAO,KAAK,QACV,eACC,GAAG,UAAkB,OAAO,aAAa,OAAO,KAAK,EAAC,MAAO;CAEhE,OAAO,KAAK,QACV,uBACC,GAAG,UAAkB,OAAO,aAAa,OAAO,KAAK,EAAC,MAAO;CAEhE,OAAO;AACT;AAEA,MAAM,eAAe,SAAwB;CAC3C,MAAM,QAAkB,CAAA;CACxB,OAAO,aAAa,MAAM,KAAK,CAAC,CAAC,QAC/B,WACC,GAAG,UAAkB,MAAM,OAAO,KAAK,EAAE;AAE9C;AAOA,SAAgB,eAAe,QAAe;CAC5C,IAAI,CAAC,QAAQ,OAAO;CAEpB,MAAM,SAAmB,CAAA;CACzB,IAAI,aAA+B;CAInC,IAAI,SAAqB,CAAA;CAEzB,MAAM,eAAe,UACnB,MAAM,IAAI,WAAW,CAAC,CAAC,KAAK,MAAM;CAEpC,MAAM,cAAmB;EACvB,IAAI,cAAc,OAAO,QAAQ;GAC/B,IAAI,eAAe,MACjB,OAAO,KACL,OAAO,OAAO,KAAK,UAAU,OAAO,YAAY,KAAK,EAAC,MAAO,CAAC,CAAC,KAAK,EAAE,EAAC,MAAO;QAE3E;IACL,MAAM,SAAS,OAAO,IAAI,WAAW,CAAC,CAAC,KAAK,MAAM;IAClD,OAAO,KACL,eAAe,MACX,MAAM,OAAM,QACZ,eAAe,OAAM,cAAe;GAE5C;EACF;EACA,aAAa;EACb,SAAS,CAAA;CACX;CAEA,KAAK,MAAM,WAAW,OAAO,QAAQ,UAAU,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG;EAChE,IAAI,CAAC,QAAQ,KAAI,GAAI;GACnB,MAAK;GACL;EACF;EAEA,MAAM,UAAU,WAAW,KAAK,OAAO;EACvC,IAAI,SAAS;GACX,MAAK;GACL,MAAM,QAAQ,QAAQ,EAAE,CAAC;GACzB,OAAO,KACL,KAAK,MAAK,GAAI,YAAY,WAAW,QAAQ,EAAE,CAAC,EAAC,KAAM,MAAK,EAAG;GAEjE;EACF;EAEA,MAAM,QAAQ,SAAS,KAAK,OAAO;EACnC,IAAI,OAAO;GACT,IAAI,eAAe,cAAc,MAAK;GACtC,aAAa;GACb,OAAO,KAAK,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;GAClC;EACF;EAEA,MAAM,OAAO,QAAQ,KAAK,OAAO;EACjC,IAAI,MAAM;GACR,IAAI,eAAe,MAAM,MAAK;GAC9B,aAAa;GACb,OAAO,KAAK,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC;GACjC;EACF;EAIA,MAAM,eACJ,eAAe,QAAQ,OAAO,SAC1B,gBAAgB,KAAK,OAAO,IAC5B;EACN,IAAI,cAAc;GAChB,OAAO,OAAO,SAAS,EAAE,CAAC,KAAK,WAAW,aAAa,EAAE,CAAC;GAC1D;EACF;EAEA,IAAI,eAAe,KAAK,MAAK;EAC7B,aAAa;EACb,OAAO,KAAK,CAAC,WAAW,OAAO,CAAC,CAAC;CACnC;CACA,MAAK;CAEL,OAAO,OAAO,KAAK,EAAE;AACvB;AC1KA,MAAM,UAAU;AAEhB,MAAM,YAAY,QAA0C;CAC1D,MAAM,CAAC,UAAU,WAAW,OAAO,GAAA,CAAI,MAAM,GAAG;CAChD,MAAM,UAAU,QAAQ,YAAW;CACnC,OAAO;EACL,UAAU,WAAW,SAAS,YAAW,IAAK;EAC9C,SAAS,WAAW,QAAQ,KAAK,OAAO,IAAI,UAAU;CACvD;AACH;AAMA,MAAa,iBACX,MAEgB,OAAO,cAAc,cAAc,SAAY,cAC9C;CACjB,MAAM,UAAU,SAAS,KAAK,QAAQ;CACtC,IAAI,QAAQ,SAAS,OAAO;CAC5B,MAAM,WACH,KAAK,aAAa,CAAA,EAAA,CAAI,IAAI,QAAQ,CAAC,CAAC,MAAM,WAAW,OAAO,OAAO,CAAC,EACjE,WAAW;CACjB,OAAO;EAAE,UAAU,QAAQ;EAAU;CAAO;AAC9C;AC3BA,IAAa,uBAAb,MAAa,qBAAoB;CACd,UAAU,OAAsB,cAAa,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACxD,SAAS,KAAK,QAAQ,WAAU;CAEzC,cAAA;EACE,IAAI,OAAO,WAAW,aAAa;EACnC,MAAM,gBAAsB,KAAK,QAAQ,IAAI,cAAa,CAAE;EAC5D,OAAO,iBAAiB,kBAAkB,OAAO;EACjD,OAAO,UAAU,CAAC,CAAC,gBACjB,OAAO,oBAAoB,kBAAkB,OAAO,CAAC;CAEzD;CAXW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAApB,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,YAFnB;CAAM,CAAA;;AAEP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAoB,YAAA,CAAA;EAHhC,MAAA;EAAW,MAAA,CAAA,EACV,YAAY,OACb,CAAA;;;;ACED,MAAM,gBAAgB;AAQtB,IAAa,mBAAb,MAAa,iBAAgB;CACV,gBAAgB,OAAO,oBAAoB,CAAC,CAAC;CAEtD,SAAS;CAKD,OAAO,aAAY;EAAA,GAAA,YAAA,EAAA,WAAA,OAAA,+BAAA,CAAA;EACjC,cAAc,KAAK,cAAa,CAAE,CAAC;EACnC,cAAc,UAAU,aACtB,KAAK,UAAU,WAAW,SAAS,QAAS,YAAY;CAAK,CAAA;CAEhD,OAAO,OAA6B,CAAC,MAAM,GAAC;EAAA,GAAA,YAAA,EAAA,WAAA,OAAA,+BAAA,CAAA;EAC3D,QAAQ,GAAG,MAAK;GACd,IAAI,MAAM,GAAG,OAAO;GACpB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,OAAO;GAC9C,OAAO,EAAE,OAAO,GAAG,MAAM,MAAM,EAAE,EAAE;EACrC;CAAC,CAAA;CAEc,UAAU,eAAe,KAAK,cAAa,CAAE,CAAC,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;CACvD,cAAc,OAA2B,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAMnD,qBAAqB,OAA2B,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CAEzD,cAAc,OAAO,WAAW;CAChC,aAAa,OAAO,UAAU;CAM9B,cAAc,OAA+B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAExD,kBAAkB,SACzB,KAAK,YAAY,QAAQ,UAAU;EAAE,GAAG;GAAO,QAAQ,KAAK,SAAS,KAAK;CAAC,EAAG;CAEvE,oBAAoB,SAC3B,KAAK,YAAY,QAAQ,GAAG,OAAO,QAAQ,GAAG,GAAG,WAC/C,QAAQ,IAAI;EAAE,GAAG;GAAO,OAAO,QAAQ;CAAC,IAAK,IAAI;CAGpC,eAAe,eACxB,CACJ,mBAAG,IAAI,IAAI,CACT,GAAI,KAAK,YAAW,IAAK,CAAC,KAAK,YAAW,CAAY,IAAI,CAAA,GAC1D,GAAG,OAAO,KAAK,KAAK,YAAW,CAAE,CAClC,CAAA,CACF,GAAA;EAAA,GAAA,YAAA,EAAA,WAAA,eAAA,+BAAA,CAAA;EACC,QAAQ,GAAG,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,MAAM,EAAE,EAAE;CAAC,CAAA;CAG1D,oBAAoB,WAAW;EAC9C,eAAe;GACb,MAAM,KAAK,KAAI;GACf,QAAQ,KAAK,aAAY;GACzB,UAAU,KAAK,mBAAkB;EAClC;EACD,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,iBAAgB;GACjD,IAAI,CAAC,OAAO,QAAQ,OAAO,GAAG,CAAA,CAAE;GAChC,MAAM,UAAU,OAAe,SAC7B,KAAK,YAAY,MACf,CAAC,QAAQ,IAAI,GACb,OAAO,MACP,QACA,KAAK,YAAY,oBAAoB,KAAK,CAAC;GAE/C,OAAO,SACL,OAAO,KAAK,UACV,OAAO,OAAO,IAAI,CAAC,CAAC,KAClB,iBACE,YAAY,aAAa,OACrB,OAAO,OAAO,QAAQ,CAAC,CAAC,KAAK,iBAAiB,GAAG,CAAA,CAAE,CAAC,CAAC,IACrD,GAAG,CAAA,CAAE,CAAC,CACX,CACF,CACF,CACF,CAAC,KAAK,KAAK,YAAY,OAAO,OAAO,CAAA,GAAI,GAAG,OAAO,CAAC,CAAC;EACxD;CACD,CAAA;CAEgB,QAAQ,WAAW;EAClC,QAAQ,KAAK;EACb,SAAS,EAAE,aACT,KAAK,WACF,SAEE,UAAU,CAAC,MAAM,EAAA,CAAG,KAAK,GAAG,GAAG,QAAQ,IAAI,CAAC,CAC9C,KAAK,iBAAiB,GAAG,EAAE,OAAO,CAAA,EAAE,CAAE,CAAC,CAAC;CAC9C,CAAA;CAEe,WAAW,eAAe,KAAK,MAAM,MAAK,CAAE,EAAE,SAAS,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CACzD,oBAAoB,WAAW;EAC9C,eAAe;GAAE,SAAS,KAAK,QAAO;GAAI,MAAM,KAAK,KAAI;EAAE;EAC3D,SAAS,EAAE,QAAQ,EAAE,SAAS,aAC5B,UACI,KAAK,WACF,SAAmB,QAAQ,CAAA,EAAA,CAAI,KAAK,GAAG,GAAG,WAAW,WAAW,IAAI,CAAC,CACrE,KAAK,iBAAiB,CAAA,CAAE,CAAC,IAC5B,GAAG,CAAA,CAAE;CACZ,CAAA;CAEe,eAAe,eAAc;EAC3C,MAAM,eAAe,CAAA;EACrB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,SAAQ,CAAE,GACvD,IAAI,KAAK,kBAAkB,MAAK,CAAE,EAAE,SAAS,GAAG,GAC9C,aAAa,OAAO;EAGxB,OAAO;CACT,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;CAEe,cAAc,WAAW;EACxC,eAAe;GACb,MAAM,KAAK,KAAI;GACf,MAAM,KAAK,KAAI;GACf,QAAQ,KAAK,kBAAkB,MAAK;EACrC;EAID,SAAS,EAAE,QAAQ,EAAE,MAAM,MAAM,eAC/B,SAAS,CACP,SAAS,gBACL,GAAG,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,IACX,KAAK,kBAAkB,CAAC,GAAI,QAAQ,CAAA,GAAK,aAAa,CAAC,GAC3D,KAAK,kBAAkB,CAAC,GAAI,QAAQ,CAAA,GAAK,IAAI,CAAC,CAC/C,CAAA,CAAC,CAAC,KACD,KAAK,YAAW;GACd,MAAM,CAAC,CAAC,QAAQ,CAAA,GAAI,YAAY,CAAA,IAAK,CAAC,MAAM,CAAA,GAAI,UAAU,CAAA,MACxD;GACF,OAAO;IACL,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAI;GACL;EACH,CAAC,CAAC;CAEP,CAAA;CAEe,gBAAgB,aAAa,KAAK,YAAY,KAAK;CAIlD,oBAAoB,OAAO,oBAAoB,EAC9D,UAAU,KACX,CAAA;CAIgB,qBAAqB,gBAAgB;EACpD,GAAK,KAAK,YAAY,MAAK,KAAM,CAAA;EACjC,GAAI,KAAK,oBAAmB,KAAM,CAAA;CACnC,IAAE,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CAMc,qBAAqB,WAAW;EAC/C,eAAe;GAAE,MAAM,KAAK,KAAI;GAAI,MAAM,KAAK,KAAI;EAAE;EACrD,SAAS,EAAE,QAAQ,EAAE,MAAM,aACzB,KAAK,WACF,SAAkC,QAAQ,CAAA,EAAA,CAAI,KAAK,GAAG,GAAG,MAAM,IAAI,CAAC,CACpE,KAAK,iBAAiB,GAAG,CAAA,CAAE,CAAC,CAAC;CACnC,CAAA;CAEe,cAAc,eACtB,IAAI,IAAI,OAAO,KAAK,KAAK,mBAAmB,MAAK,KAAM,CAAA,CAAE,CAAC,GACjE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEgB,QAAQ,WAAW;EAClC,QAAQ,KAAK;EACb,SAAS,EAAE,aACT,KAAK,kBAAkB,CAAC,GAAG,QAAQ,OAAO,CAAC,CAAC,CAAC,KAC3C,KAAK,WAAwC;GAC3C,MAAM,CAAC,MAAM,CAAA,GAAI,UAAU,CAAA,KAAM;GAIjC,OAAO;IAAE,GAAG,MAAM;IAAU,GAAG,UAAU;GAAQ;EACnD,CAAC,CAAC;CAEP,CAAA;CAEM,QAAQ,MAAY;EACzB,KAAK,SAAS;EACd,IAAI,SAAS,KAAK,KAAI,GACpB,KAAK,KAAK,IAAI,IAAI;CAEtB;CAMgB,aACd,OACA,WACU;EACV,IAAI,SAAS,MAAM,OAAO;EAC1B,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,SAAQ;EAIpD,IAAI,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;OAC/C,IAAI,OAAO,UAAU,UAAU,OAAO;EAE3C,MAAM,EAAE,KAAK,WAAW,KAAK,oBAAoB,KAAK;EAEtD,MAAM,eAAe,KAAK,mBAAkB;EAC5C,MAAM,SAAS,IACZ,MAAM,GAAG,CAAC,CACV,QACE,KAAc,YACb,OAAO,QAAQ,YAAY,QAAQ,OAC7B,MAAkC,YAAY,KAChD,KACN,YAAY;EAGhB,MAAM,eAAe;GAAE,GAAG;GAAQ,GAAI,UAAU,CAAA;EAAG;EAGnD,IAAI,OAAO,WAAW,YAAY,QAAQ;GACxC,MAAM,iBAAiB,KAAK,oBAAoB,QAAQ,YAAY;GACpE,OAAO,KAAK,QAAQ,gBAAgB,MAAM;EAC5C;EAIA,MAAM,oBAAoB,KAAK,oBAAoB,KAAK,YAAY;EACpE,OAAO,KAAK,QAAQ,mBAAmB,MAAM;CAC/C;CAOgB,mBACd,OACA,WACU;EACV,MAAM,iBAAiB,KAAK,UAAU,OAAO,MAAM;EACnD,OAAO,iBAAiB,eAAe,cAAc,IAAI;CAC3D;CAEO,KAAK,OAAiB,CAAC,MAAM,GAAC;EACnC,KAAK,KAAK,IAAI,IAAI;CACpB;CAMQ,oBAAoB,OAAa;EAIvC,IAAI,CAAC,MAAM,SAAS,GAAG,GACrB,OAAO;GAAE,KAAK;GAAO,QAAQ,CAAA;EAAE;EAGjC,MAAM,CAAC,KAAK,eAAe,MAAM,MAAM,GAAG;EAC1C,MAAM,SAAiC,CAAA;EAGvC,IADsB,gBAAgB,WACtC,CAAA,CAAU,SAAS,KAAK,aAAY;GAClC,OAAO,YAAY;EACrB,CAAC;EAED,OAAO;GAAE;GAAK;EAAM;CACtB;CAkBQ,oBACN,MACA,QAA8B;EAE9B,OAAO,KAAK,QACV,kBACC,OAAO,QAAgB,gBAAuB;GAC7C,MAAM,QAAQ,OAAO;GACrB,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,WAAW,GAC3D,OAAO;GAGT,MAAM,WAAW,SAAS,KAAK,wBAAwB,KAAK,IAAI;GAGhE,OAAO,KAAK,YAAY,QAAQ;EAClC,CAAC;CAEL;CAEQ,YAAY,MAAY;EAE9B,OADoB,KAAK,WAAW,IAC7B,CAAA,CACJ,QAAQ,OAAO,OAAO,CAAC,CACvB,QAAQ,MAAM,OAAO,CAAC,CACtB,QAAQ,MAAM,QAAQ,CAAC,CACvB,QAAQ,OAAO,OAAO,CAAC,CACvB,QAAQ,OAAO,OAAO;CAC3B;CAMQ,wBAAwB,OAAa;EAC3C,IAAI,CAAC,OAAO,OAAO;EAEnB,MAAM,eAAe,KAAK,mBAAkB;EAG5C,MAAM,SAAS,MACZ,MAAM,GAAG,CAAC,CACV,QACE,KAAc,YACb,OAAO,QAAQ,YAAY,QAAQ,OAC9B,MAAkC,WACnC,KACN,YAAY;EAIhB,OAAO,OAAO,WAAW,YAAY,SAAS,SAAS;CACzD;CAEQ,kBAAkB,MAAc;EACtC,MAAM,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAG;EACvC,MAAM,OAAO,KAAK,KAAK,SAAS;EAChC,OAAO,SAAS,CACd,KAAK,WAAW,QAAQ,MAAM,MAAM,IAAI,CAAC,CAAC,KAAK,iBAAiB,GAAG,CAAA,CAAE,CAAC,CAAC,GACvE,KAAK,WAAW,QAAQ,MAAM,IAAI,CAAC,CAAC,KAAK,iBAAiB,GAAG,CAAA,CAAE,CAAC,CAAC,CAClE,CAAA,CAAC,CAAC,KAAK,iBAAiB,GAAG,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAC,CAAC;CACxC;CAEQ,WAAW,MAAU;EAC3B,OAAO,GAAG,KAAK,UACb,OAAO,KAAK,OAAM,GAAI,EACvB,GAAI,KAAK,QAAO,EAAE,GAAI,KAAK,UAC1B,SAAS,KAAK,SAAQ,GAAI,EAC3B,GAAI,KAAK,YAAW;CACvB;CAEQ,eAAe,MAAY;EACjC,OAAO,KAAK,WAAW,IAAI,KAAK,IAAI,CAAC;CACvC;CAEQ,QAAQ,KAAW;EACzB,OAAO,KAAK,MAAM,MAAK,CAAE,GAAG,QAAQ;CACtC;CAEQ,UAAU,MAAc,MAAY;EAC1C,OAAO,SAAS,SAAS,KAAK,eAAe,IAAI,IAAI;CACvD;CAEQ,mBACN,SACA,QAA8B;EAE9B,IAAI,QAAQ,SAAS,GAAG,GAAG;GACzB,MAAM,CAAC,MAAM,WAAW,QAAQ,MAAM,GAAG;GACzC,MAAM,cACJ,KAAK,WAAW,GAAG,KAAK,OAAO,QAC3B,KAAK,UAAU,OAAO,KAAK,IAC3B;GACN,MAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO;GAE7C,MAAM,gBAAgB,OAAO,KAAK,YAAY,IAAI,IAAI;GACtD,OAAO,gBACH,YAAY,cAAa,IAAK,KAAK,WAAW,WAAW,EAAC,QAC1D,KAAK,WAAW,WAAW;EACjC;EAEA,IAAI,QAAQ,SAAS,GAAG,GAAG;GACzB,MAAM,CAAC,KAAK,QAAQ,QAAQ,MAAM,GAAG;GACrC,OAAO,KAAK,WAAW,KAAK,UAAU,OAAO,MAAM,IAAI,CAAC;EAC1D;EAEA,IAAI,QAAQ,SAAS,GAAG,GAAG;GACzB,MAAM,CAAC,MAAM,OAAO,QAAQ,MAAM,GAAG;GACrC,MAAM,cACJ,KAAK,WAAW,GAAG,KAAK,OAAO,QAC3B,KAAK,UAAU,OAAO,KAAK,IAC3B;GACN,OAAO,WAAW,KAAK,WAAW,GAAG,EAAC,IAAK,KAAK,WAC9C,WAAW,EACZ;EACH;EAEA,IAAI,QAAQ,WAAW,GAAG,GAAG;GAC3B,MAAM,QAAQ,OAAO,YAAY,OAAO,QAAQ,UAAU,CAAC;GAO3D,IAAI,UAAU,QAAW,OAAO,IAAI,QAAO;GAC3C,OAAO,KAAK,WAAW,KAAK,UAAU,KAAK,CAAC;EAC9C;EAEA,OAAO,IAAI,QAAO;CACpB;CAEiB,WACf,MACA,SAAiC,CAAA,MACvB;EACV,OAAO,KAAK,QAAQ,WAAW,SAC7B,KAAK,mBAAmB,KAAK,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;CAEtD;CAQgB,cAAc,SAA0B,eAAe,IAAI;CAKnE,WAAW,MAAY;EAC7B,MAAM,MAAM,SAAS,cAAc,KAAK;EACxC,IAAI,cAAc;EAClB,OAAO,IAAI;CACb;CAKQ,YAAY,KAAW;EAC7B,MAAM,aAAa,IAAI,KAAI,CAAE,CAAC,YAAW;EAIzC,IACE;GAF0B;GAAe;GAAS;GAAa;EAE/D,CAAA,CAAmB,MAAM,aAAa,WAAW,WAAW,QAAQ,CAAC,GAErE,OAAO;EAIT,IACE,WAAW,WAAW,QAAQ,KAC9B,WAAW,WAAW,SAAS,KAC/B,WAAW,WAAW,SAAS,KAC/B,WAAW,WAAW,GAAG,KACzB,WAAW,WAAW,GAAG,KACzB,WAAW,WAAW,GAAG,GAEzB,OAAO;EAIT,IAAI,CAAC,WAAW,SAAS,GAAG,GAC1B,OAAO;EAIT,OAAO;CACT;CAxeW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAgB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAhB,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAgB,YAFf;CAAM,CAAA;;AAEP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAgB,YAAA,CAAA;EAH5B,MAAA;EAAW,MAAA,CAAA,EACV,YAAY,OACb,CAAA;;;ACXD,IAAa,gBAAb,MAAa,cAAa;CACP,mBAAmB,OAAO,gBAAgB;CAE3D,UACE,OACA,QAA2C;EAI3C,IAAI,SAAS,QAAQ,UAAU,IAAI,OAAO;EAC1C,OAAO,KAAK,iBAAiB,UAAU,OAAO,MAAM;CACtD;CAXW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAa,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAb,OAAA,QAAA,GAAA,gBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAa,cAAA;EAAA,MAAA;EAAA,MAAA;CAAA,CAAA;;AAAb,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAa,YAAA,CAAA;EAJzB,MAAA;EAAK,MAAA,CAAA;GACJ,MAAM;GACN,MAAM;EACP,CAAA;;;ACCD,MAAM,cAAoC;EACvC,KAAK,QAAQ;EACb,KAAK,SAAS;EACd,KAAK,QAAQ;AACf;AAYD,SAAgB,YAAY,MAA+B;CACzD,OAAO,YAAY,OAAO,IAAI,IAAI,OAAO;AAC3C;AAEA,SAAgB,OAAO,OAAc;CACnC,OACE,UAAU,KAAK,SAAS,UAAU,KAAK,UAAU,UAAU,KAAK;AAEpE;AAOA,SAAgB,WACd,GAAG,YAAmD;CAEtD,KAAK,MAAM,aAAa,YACtB,IAAI,OAAO,SAAS,GAAG,OAAO;CAEhC,OAAO;AACT;AAOA,SAAgB,SACd,OACA,QAAa;CAEb,IAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IACrD,OAAO,SAAS,SAAS;CAE3B,OAAO,OAAO,UAAU,WAAW,GAAG,MAAK,MAAO;AACpD;AAUA,SAAgB,gBACd,UACA,aAAuC;CAEvC,IAAI,aAAa,UAAa,aAAa,QAAQ,aAAa,IAC9D,OAAO,QAAQ,YAAY,WAAW,EAAC;CAEzC,IAAI,OAAO,aAAa,UAAU,OAAO,GAAG,SAAQ;CACpD,MAAM,UAAU,SAAS,KAAI;CAC7B,IAAI,YAAY,IAAI,OAAO,QAAQ,YAAY,WAAW,EAAC;CAC3D,IAAI,gBAAgB,KAAK,OAAO,GAAG,OAAO,GAAG,QAAO;CACpD,OAAO;AACT;AASA,SAAgB,YACd,OAAkC;CAElC,IAAI,UAAU,UAAa,UAAU,MAAM,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO,GAAG,MAAK;CAC9C,MAAM,UAAU,MAAM,KAAI;CAC1B,IAAI,YAAY,IAAI,OAAO;CAC3B,OAAO,gBAAgB,KAAK,OAAO,IAAI,GAAG,QAAO,MAAO;AAC1D;AAKA,MAAM,kBAAkB,UAA2C;CACjE,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,MAAM,UAAU,MAAM,KAAI;CAC1B,IAAI,YAAY,MAAM,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,OAAO;CAC5D,OAAO,OAAO,OAAO;AACvB;AAOA,SAAgB,eACd,OAAyC;CAEzC,OAAO,UAAU,UAAa,UAAU,QAAQ,UAAU,KACtD,SACA,SAAS,eAAe,KAAK,CAAC;AACpC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "./magmonium-one-color-utl-D86GGpz5.mjs";
|