@magmonium/one 0.2.95 → 0.2.97
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/fesm2022/{magmonium-one-image-editor-yuO5J7-w.mjs → magmonium-one-image-editor-BvkG6Cvh.mjs} +2 -2
- package/fesm2022/{magmonium-one-image-editor-yuO5J7-w.mjs.map → magmonium-one-image-editor-BvkG6Cvh.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-magmonium-one-DQNL21rQ.mjs → magmonium-one-magmonium-one-9qp__mDn.mjs} +102 -11
- package/fesm2022/magmonium-one-magmonium-one-9qp__mDn.mjs.map +1 -0
- package/fesm2022/{magmonium-one-otp-CdLYJWPD.mjs → magmonium-one-otp-BqKz65Xa.mjs} +2 -2
- package/fesm2022/{magmonium-one-otp-CdLYJWPD.mjs.map → magmonium-one-otp-BqKz65Xa.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-password-YU7fZJsq.mjs → magmonium-one-password-CxXKymRW.mjs} +2 -2
- package/fesm2022/{magmonium-one-password-YU7fZJsq.mjs.map → magmonium-one-password-CxXKymRW.mjs.map} +1 -1
- package/fesm2022/{magmonium-one-toggle-Bv407NRh.mjs → magmonium-one-toggle-CVVVBuRw.mjs} +2 -2
- package/fesm2022/{magmonium-one-toggle-Bv407NRh.mjs.map → magmonium-one-toggle-CVVVBuRw.mjs.map} +1 -1
- package/fesm2022/magmonium-one.mjs +1 -1
- package/package.json +1 -1
- package/types/magmonium-one.d.ts +80 -0
- package/fesm2022/magmonium-one-magmonium-one-DQNL21rQ.mjs.map +0 -1
package/fesm2022/{magmonium-one-image-editor-yuO5J7-w.mjs → magmonium-one-image-editor-BvkG6Cvh.mjs}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, inject, viewChild, signal, computed, effect, DestroyRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { M as MODAL_REF, a as MIN_ZOOM, I as InputType, b as MAX_ZOOM, p as parseRatio, o as outputSize, c as cropRect, i as initialFraming, e as encodeFramed, d as drawFramed, r as renameForType, f as clampFraming, B as ButtonComponent, H as HeaderComponent, R as RangeInputComponent } from './magmonium-one-magmonium-one-
|
|
3
|
+
import { M as MODAL_REF, a as MIN_ZOOM, I as InputType, b as MAX_ZOOM, p as parseRatio, o as outputSize, c as cropRect, i as initialFraming, e as encodeFramed, d as drawFramed, r as renameForType, f as clampFraming, B as ButtonComponent, H as HeaderComponent, R as RangeInputComponent } from './magmonium-one-magmonium-one-9qp__mDn.mjs';
|
|
4
4
|
|
|
5
5
|
const WHEEL_ZOOM_RATE = 0.0015;
|
|
6
6
|
const distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
@@ -287,4 +287,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
287
287
|
}], propDecorators: { file: [{ type: i0.Input, args: [{ isSignal: true, alias: "file", required: true }] }], ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: true }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: true }] }], stage: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }] } });
|
|
288
288
|
|
|
289
289
|
export { ImageEditorComponent };
|
|
290
|
-
//# sourceMappingURL=magmonium-one-image-editor-
|
|
290
|
+
//# sourceMappingURL=magmonium-one-image-editor-BvkG6Cvh.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magmonium-one-image-editor-yuO5J7-w.mjs","sources":["../../../../libs/one/src/lib/shared/ui/input/ui/file-upload-input/image-editor.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ButtonComponent } from '../../../button/ui/button';\nimport { HeaderComponent } from '../../../header';\nimport { RangeInputComponent } from '../range/range';\nimport { InputType, RangeInput } from '../../model/input';\nimport { MODAL_REF, ModalRef } from '../../../../config/modal-ref';\nimport {\n clampFraming,\n cropRect,\n drawFramed,\n encodeFramed,\n Framing,\n FrameSize,\n initialFraming,\n MAX_ZOOM,\n MIN_ZOOM,\n outputSize,\n parseRatio,\n renameForType,\n} from './image-frame';\n\n/**\n * What an ImageEditor closes with. The framed file on an apply, `unreadable`\n * when the picture never decoded, and neither for a dismissal — a flat object\n * rather than a union, so the web-component build (no `strict`) reads it too.\n */\nexport type ImageEditorResult = { file?: File; unreadable?: boolean };\n\ntype Point = { x: number; y: number };\n\nconst WHEEL_ZOOM_RATE = 0.0015;\n\nconst distance = (a: Point, b: Point): number =>\n Math.hypot(a.x - b.x, a.y - b.y);\n\n@Component({\n selector: 'm-image-editor',\n template: `\n <div class=\"image-editor\">\n <m-header\n [level]=\"3\"\n label=\"edit-image-size\"\n [params]=\"sizeParams()\"\n />\n <div\n #stage\n class=\"image-editor__stage\"\n [style.aspect-ratio]=\"aspect()\"\n [style.--m-image-editor-aspect]=\"aspect()\"\n [class.image-editor__stage--panning]=\"isPanning()\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (wheel)=\"onWheel($event)\"\n >\n @if (sourceUrl(); as url) {\n <img\n class=\"image-editor__image\"\n [src]=\"url\"\n alt=\"\"\n draggable=\"false\"\n [style.width.px]=\"imageBox().width\"\n [style.height.px]=\"imageBox().height\"\n [style.transform]=\"imageBox().transform\"\n />\n }\n </div>\n <m-range\n [config]=\"zoomConfig()\"\n [value]=\"zoomPercent()\"\n (valueChange)=\"onZoom($event)\"\n />\n <!-- asset: buttons/okay.yml. No cancel beside it: the Modal's own close\n is the cancel, and it drops the image the same way. -->\n <m-one-button\n name=\"okay\"\n label=\"apply\"\n [disabled]=\"!source() || isApplying()\"\n (clicked)=\"apply()\"\n />\n </div>\n `,\n imports: [ButtonComponent, HeaderComponent, RangeInputComponent],\n styleUrl: './image-editor.sass',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ImageEditorComponent {\n readonly file = input.required<File>();\n readonly ratio = input.required<string>();\n readonly width = input.required<number>();\n\n readonly #modalRef = inject<ModalRef<ImageEditorResult | undefined>>(MODAL_REF);\n private readonly stage = viewChild<ElementRef<HTMLDivElement>>('stage');\n\n protected readonly source = signal<ImageBitmap | undefined>(undefined);\n protected readonly sourceUrl = signal<string | undefined>(undefined);\n protected readonly isApplying = signal(false);\n private readonly framing = signal<Framing>({ cx: 0, cy: 0, zoom: MIN_ZOOM });\n private readonly stageWidth = signal(0);\n private readonly pointers = new Map<number, Point>();\n protected readonly isPanning = signal(false);\n #settled = false;\n\n protected readonly zoomConfig = computed<RangeInput>(() => ({\n name: 'zoom',\n label: 'zoom',\n type: InputType.RANGE,\n min: MIN_ZOOM * 100,\n max: MAX_ZOOM * 100,\n }));\n\n protected readonly aspect = computed(() => parseRatio(this.ratio()) ?? 1);\n\n private readonly output = computed<FrameSize | undefined>(() =>\n outputSize(this.ratio(), this.width())\n );\n\n protected readonly sizeParams = computed(() => {\n const size = this.output();\n return {\n width: String(size?.width ?? ''),\n height: String(size?.height ?? ''),\n };\n });\n\n private readonly imageSize = computed<FrameSize | undefined>(() => {\n const bitmap = this.source();\n return bitmap ? { width: bitmap.width, height: bitmap.height } : undefined;\n });\n\n protected readonly zoomPercent = computed(() =>\n String(Math.round(this.framing().zoom * 100))\n );\n\n /** The whole picture laid out so the box shows exactly the crop. */\n protected readonly imageBox = computed(() => {\n const image = this.imageSize();\n const stage = this.stageWidth();\n if (!image || !stage) return { width: 0, height: 0, transform: 'none' };\n const rect = cropRect(image, this.aspect(), this.framing());\n const scale = stage / rect.width;\n return {\n width: image.width * scale,\n height: image.height * scale,\n transform: `translate(${-rect.x * scale}px, ${-rect.y * scale}px)`,\n };\n });\n\n private readonly load = effect((onCleanup) => {\n const file = this.file();\n let cancelled = false;\n const url = URL.createObjectURL(file);\n this.sourceUrl.set(url);\n // EXIF orientation applied here, so the geometry below and the <img> the\n // stage draws agree on which way is up.\n createImageBitmap(file, { imageOrientation: 'from-image' })\n .then((bitmap) => {\n if (cancelled) {\n bitmap.close();\n return;\n }\n this.framing.set(\n initialFraming({ width: bitmap.width, height: bitmap.height })\n );\n this.source.set(bitmap);\n })\n .catch(() => {\n if (!cancelled) this.settle({ unreadable: true });\n });\n onCleanup(() => {\n cancelled = true;\n URL.revokeObjectURL(url);\n this.source()?.close();\n });\n });\n\n private readonly measure = effect((onCleanup) => {\n const stage = this.stage()?.nativeElement;\n if (!stage) return;\n this.stageWidth.set(stage.clientWidth);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) =>\n this.stageWidth.set(entry.contentRect.width)\n );\n observer.observe(stage);\n onCleanup(() => observer.disconnect());\n });\n\n // The Modal's own close affordance destroys the body without a word, and a\n // dismissal is a cancel: whoever opened the editor is still waiting.\n private readonly reportDismissal = inject(DestroyRef).onDestroy(() =>\n this.settle(undefined)\n );\n\n protected onPointerDown = (event: PointerEvent): void => {\n if (!this.source()) return;\n (event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId);\n this.pointers.set(event.pointerId, { x: event.clientX, y: event.clientY });\n this.isPanning.set(true);\n };\n\n protected onPointerMove = (event: PointerEvent): void => {\n const previous = this.pointers.get(event.pointerId);\n if (!previous) return;\n const next = { x: event.clientX, y: event.clientY };\n const others = [...this.pointers.entries()].filter(\n ([id]) => id !== event.pointerId\n );\n if (others.length === 1) {\n // Pinch: the gap between two fingers is the zoom.\n const anchor = others[0][1];\n const before = distance(previous, anchor);\n if (before > 0) this.zoomBy(distance(next, anchor) / before);\n } else if (others.length === 0) {\n this.panBy(next.x - previous.x, next.y - previous.y);\n }\n this.pointers.set(event.pointerId, next);\n };\n\n protected onPointerUp = (event: PointerEvent): void => {\n this.pointers.delete(event.pointerId);\n this.isPanning.set(this.pointers.size > 0);\n };\n\n protected onWheel = (event: WheelEvent): void => {\n if (!this.source()) return;\n event.preventDefault();\n this.zoomBy(Math.exp(-event.deltaY * WHEEL_ZOOM_RATE));\n };\n\n protected onZoom = (percent: string): void => {\n const zoom = Number(percent) / 100;\n if (!Number.isFinite(zoom)) return;\n this.updateFraming((framing) => ({ ...framing, zoom }));\n };\n\n protected apply = async (): Promise<void> => {\n const bitmap = this.source();\n const image = this.imageSize();\n const output = this.output();\n if (!bitmap || !image || !output || this.isApplying()) return;\n this.isApplying.set(true);\n try {\n const rect = cropRect(image, this.aspect(), this.framing());\n const blob = await encodeFramed(drawFramed(bitmap, rect, output));\n const original = this.file();\n this.settle({\n file: new File([blob], renameForType(original.name, blob.type), {\n type: blob.type,\n lastModified: Date.now(),\n }),\n });\n } catch {\n this.settle({ unreadable: true });\n }\n };\n\n /** Screen pixels dragged, moved into source pixels at the current scale. */\n private panBy = (dx: number, dy: number): void => {\n const image = this.imageSize();\n const stage = this.stageWidth();\n if (!image || !stage) return;\n const rect = cropRect(image, this.aspect(), this.framing());\n const perPixel = rect.width / stage;\n this.updateFraming((framing) => ({\n ...framing,\n cx: framing.cx - dx * perPixel,\n cy: framing.cy - dy * perPixel,\n }));\n };\n\n private zoomBy = (factor: number): void => {\n this.updateFraming((framing) => ({\n ...framing,\n zoom: framing.zoom * factor,\n }));\n };\n\n private updateFraming = (change: (framing: Framing) => Framing): void => {\n const image = this.imageSize();\n if (!image) return;\n this.framing.update((framing) =>\n clampFraming(image, this.aspect(), change(framing))\n );\n };\n\n private settle = (result: ImageEditorResult | undefined): void => {\n if (this.#settled) return;\n this.#settled = true;\n this.#modalRef.close(result);\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"magmonium-one-image-editor-BvkG6Cvh.mjs","sources":["../../../../libs/one/src/lib/shared/ui/input/ui/file-upload-input/image-editor.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ButtonComponent } from '../../../button/ui/button';\nimport { HeaderComponent } from '../../../header';\nimport { RangeInputComponent } from '../range/range';\nimport { InputType, RangeInput } from '../../model/input';\nimport { MODAL_REF, ModalRef } from '../../../../config/modal-ref';\nimport {\n clampFraming,\n cropRect,\n drawFramed,\n encodeFramed,\n Framing,\n FrameSize,\n initialFraming,\n MAX_ZOOM,\n MIN_ZOOM,\n outputSize,\n parseRatio,\n renameForType,\n} from './image-frame';\n\n/**\n * What an ImageEditor closes with. The framed file on an apply, `unreadable`\n * when the picture never decoded, and neither for a dismissal — a flat object\n * rather than a union, so the web-component build (no `strict`) reads it too.\n */\nexport type ImageEditorResult = { file?: File; unreadable?: boolean };\n\ntype Point = { x: number; y: number };\n\nconst WHEEL_ZOOM_RATE = 0.0015;\n\nconst distance = (a: Point, b: Point): number =>\n Math.hypot(a.x - b.x, a.y - b.y);\n\n@Component({\n selector: 'm-image-editor',\n template: `\n <div class=\"image-editor\">\n <m-header\n [level]=\"3\"\n label=\"edit-image-size\"\n [params]=\"sizeParams()\"\n />\n <div\n #stage\n class=\"image-editor__stage\"\n [style.aspect-ratio]=\"aspect()\"\n [style.--m-image-editor-aspect]=\"aspect()\"\n [class.image-editor__stage--panning]=\"isPanning()\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (wheel)=\"onWheel($event)\"\n >\n @if (sourceUrl(); as url) {\n <img\n class=\"image-editor__image\"\n [src]=\"url\"\n alt=\"\"\n draggable=\"false\"\n [style.width.px]=\"imageBox().width\"\n [style.height.px]=\"imageBox().height\"\n [style.transform]=\"imageBox().transform\"\n />\n }\n </div>\n <m-range\n [config]=\"zoomConfig()\"\n [value]=\"zoomPercent()\"\n (valueChange)=\"onZoom($event)\"\n />\n <!-- asset: buttons/okay.yml. No cancel beside it: the Modal's own close\n is the cancel, and it drops the image the same way. -->\n <m-one-button\n name=\"okay\"\n label=\"apply\"\n [disabled]=\"!source() || isApplying()\"\n (clicked)=\"apply()\"\n />\n </div>\n `,\n imports: [ButtonComponent, HeaderComponent, RangeInputComponent],\n styleUrl: './image-editor.sass',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ImageEditorComponent {\n readonly file = input.required<File>();\n readonly ratio = input.required<string>();\n readonly width = input.required<number>();\n\n readonly #modalRef = inject<ModalRef<ImageEditorResult | undefined>>(MODAL_REF);\n private readonly stage = viewChild<ElementRef<HTMLDivElement>>('stage');\n\n protected readonly source = signal<ImageBitmap | undefined>(undefined);\n protected readonly sourceUrl = signal<string | undefined>(undefined);\n protected readonly isApplying = signal(false);\n private readonly framing = signal<Framing>({ cx: 0, cy: 0, zoom: MIN_ZOOM });\n private readonly stageWidth = signal(0);\n private readonly pointers = new Map<number, Point>();\n protected readonly isPanning = signal(false);\n #settled = false;\n\n protected readonly zoomConfig = computed<RangeInput>(() => ({\n name: 'zoom',\n label: 'zoom',\n type: InputType.RANGE,\n min: MIN_ZOOM * 100,\n max: MAX_ZOOM * 100,\n }));\n\n protected readonly aspect = computed(() => parseRatio(this.ratio()) ?? 1);\n\n private readonly output = computed<FrameSize | undefined>(() =>\n outputSize(this.ratio(), this.width())\n );\n\n protected readonly sizeParams = computed(() => {\n const size = this.output();\n return {\n width: String(size?.width ?? ''),\n height: String(size?.height ?? ''),\n };\n });\n\n private readonly imageSize = computed<FrameSize | undefined>(() => {\n const bitmap = this.source();\n return bitmap ? { width: bitmap.width, height: bitmap.height } : undefined;\n });\n\n protected readonly zoomPercent = computed(() =>\n String(Math.round(this.framing().zoom * 100))\n );\n\n /** The whole picture laid out so the box shows exactly the crop. */\n protected readonly imageBox = computed(() => {\n const image = this.imageSize();\n const stage = this.stageWidth();\n if (!image || !stage) return { width: 0, height: 0, transform: 'none' };\n const rect = cropRect(image, this.aspect(), this.framing());\n const scale = stage / rect.width;\n return {\n width: image.width * scale,\n height: image.height * scale,\n transform: `translate(${-rect.x * scale}px, ${-rect.y * scale}px)`,\n };\n });\n\n private readonly load = effect((onCleanup) => {\n const file = this.file();\n let cancelled = false;\n const url = URL.createObjectURL(file);\n this.sourceUrl.set(url);\n // EXIF orientation applied here, so the geometry below and the <img> the\n // stage draws agree on which way is up.\n createImageBitmap(file, { imageOrientation: 'from-image' })\n .then((bitmap) => {\n if (cancelled) {\n bitmap.close();\n return;\n }\n this.framing.set(\n initialFraming({ width: bitmap.width, height: bitmap.height })\n );\n this.source.set(bitmap);\n })\n .catch(() => {\n if (!cancelled) this.settle({ unreadable: true });\n });\n onCleanup(() => {\n cancelled = true;\n URL.revokeObjectURL(url);\n this.source()?.close();\n });\n });\n\n private readonly measure = effect((onCleanup) => {\n const stage = this.stage()?.nativeElement;\n if (!stage) return;\n this.stageWidth.set(stage.clientWidth);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) =>\n this.stageWidth.set(entry.contentRect.width)\n );\n observer.observe(stage);\n onCleanup(() => observer.disconnect());\n });\n\n // The Modal's own close affordance destroys the body without a word, and a\n // dismissal is a cancel: whoever opened the editor is still waiting.\n private readonly reportDismissal = inject(DestroyRef).onDestroy(() =>\n this.settle(undefined)\n );\n\n protected onPointerDown = (event: PointerEvent): void => {\n if (!this.source()) return;\n (event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId);\n this.pointers.set(event.pointerId, { x: event.clientX, y: event.clientY });\n this.isPanning.set(true);\n };\n\n protected onPointerMove = (event: PointerEvent): void => {\n const previous = this.pointers.get(event.pointerId);\n if (!previous) return;\n const next = { x: event.clientX, y: event.clientY };\n const others = [...this.pointers.entries()].filter(\n ([id]) => id !== event.pointerId\n );\n if (others.length === 1) {\n // Pinch: the gap between two fingers is the zoom.\n const anchor = others[0][1];\n const before = distance(previous, anchor);\n if (before > 0) this.zoomBy(distance(next, anchor) / before);\n } else if (others.length === 0) {\n this.panBy(next.x - previous.x, next.y - previous.y);\n }\n this.pointers.set(event.pointerId, next);\n };\n\n protected onPointerUp = (event: PointerEvent): void => {\n this.pointers.delete(event.pointerId);\n this.isPanning.set(this.pointers.size > 0);\n };\n\n protected onWheel = (event: WheelEvent): void => {\n if (!this.source()) return;\n event.preventDefault();\n this.zoomBy(Math.exp(-event.deltaY * WHEEL_ZOOM_RATE));\n };\n\n protected onZoom = (percent: string): void => {\n const zoom = Number(percent) / 100;\n if (!Number.isFinite(zoom)) return;\n this.updateFraming((framing) => ({ ...framing, zoom }));\n };\n\n protected apply = async (): Promise<void> => {\n const bitmap = this.source();\n const image = this.imageSize();\n const output = this.output();\n if (!bitmap || !image || !output || this.isApplying()) return;\n this.isApplying.set(true);\n try {\n const rect = cropRect(image, this.aspect(), this.framing());\n const blob = await encodeFramed(drawFramed(bitmap, rect, output));\n const original = this.file();\n this.settle({\n file: new File([blob], renameForType(original.name, blob.type), {\n type: blob.type,\n lastModified: Date.now(),\n }),\n });\n } catch {\n this.settle({ unreadable: true });\n }\n };\n\n /** Screen pixels dragged, moved into source pixels at the current scale. */\n private panBy = (dx: number, dy: number): void => {\n const image = this.imageSize();\n const stage = this.stageWidth();\n if (!image || !stage) return;\n const rect = cropRect(image, this.aspect(), this.framing());\n const perPixel = rect.width / stage;\n this.updateFraming((framing) => ({\n ...framing,\n cx: framing.cx - dx * perPixel,\n cy: framing.cy - dy * perPixel,\n }));\n };\n\n private zoomBy = (factor: number): void => {\n this.updateFraming((framing) => ({\n ...framing,\n zoom: framing.zoom * factor,\n }));\n };\n\n private updateFraming = (change: (framing: Framing) => Framing): void => {\n const image = this.imageSize();\n if (!image) return;\n this.framing.update((framing) =>\n clampFraming(image, this.aspect(), change(framing))\n );\n };\n\n private settle = (result: ImageEditorResult | undefined): void => {\n if (this.#settled) return;\n this.#settled = true;\n this.#modalRef.close(result);\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4113,6 +4113,7 @@ const initialState$3 = {
|
|
|
4113
4113
|
path: '/',
|
|
4114
4114
|
routeNavId: undefined,
|
|
4115
4115
|
routeParams: {},
|
|
4116
|
+
routeChain: [],
|
|
4116
4117
|
murl: [],
|
|
4117
4118
|
appLink: undefined,
|
|
4118
4119
|
appNavId: undefined,
|
|
@@ -4137,6 +4138,26 @@ const routeNavIdOf = (root) => {
|
|
|
4137
4138
|
}
|
|
4138
4139
|
return navId;
|
|
4139
4140
|
};
|
|
4141
|
+
/**
|
|
4142
|
+
* Each route on the matched chain that names a Nav, with the concrete path it
|
|
4143
|
+
* answers at — its own segments and every parent's, values filled in.
|
|
4144
|
+
*/
|
|
4145
|
+
const routeChainOf = (root) => {
|
|
4146
|
+
const chain = [];
|
|
4147
|
+
const segments = [];
|
|
4148
|
+
for (let r = root; r; r = r.firstChild) {
|
|
4149
|
+
segments.push(...(r.url ?? []).map((segment) => segment.path));
|
|
4150
|
+
const declared = r.data?.['navId'];
|
|
4151
|
+
if (typeof declared !== 'string' || !declared)
|
|
4152
|
+
continue;
|
|
4153
|
+
const path = URL_SEP + segments.filter(Boolean).join(URL_SEP);
|
|
4154
|
+
// Data is inherited down an empty-path child, so one Nav may repeat.
|
|
4155
|
+
if (chain[chain.length - 1]?.navId === declared)
|
|
4156
|
+
chain.pop();
|
|
4157
|
+
chain.push({ navId: declared, path });
|
|
4158
|
+
}
|
|
4159
|
+
return chain;
|
|
4160
|
+
};
|
|
4140
4161
|
/**
|
|
4141
4162
|
* Every path parameter on the matched chain, deepest last. Merged rather than
|
|
4142
4163
|
* read off the leaf: two dynamic Navs on one path each contribute their own
|
|
@@ -4564,7 +4585,63 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4564
4585
|
keepPanelOnPathChange: true,
|
|
4565
4586
|
});
|
|
4566
4587
|
}
|
|
4567
|
-
router.navigateByUrl(address, {
|
|
4588
|
+
router.navigateByUrl(address, {
|
|
4589
|
+
replaceUrl: !!options?.replaceUrl || (wasOpen && willOpen),
|
|
4590
|
+
});
|
|
4591
|
+
};
|
|
4592
|
+
/**
|
|
4593
|
+
* A NavId as the map knows it. A Remote names its Navs root-relative (ADR
|
|
4594
|
+
* 0015); where the map holds the host-scoped key instead, that is the one.
|
|
4595
|
+
*/
|
|
4596
|
+
const knownNavId = (navId) => {
|
|
4597
|
+
const appNavId = untracked(() => store.appNavId());
|
|
4598
|
+
if (untracked(() => store.navMap())[navId] || !appNavId)
|
|
4599
|
+
return navId;
|
|
4600
|
+
const hosted = toHostNavId(navId, appNavId);
|
|
4601
|
+
return untracked(() => store.navMap())[hosted] ? hosted : navId;
|
|
4602
|
+
};
|
|
4603
|
+
/** The route parameter one Nav contributes, read off the map. */
|
|
4604
|
+
const paramNameOf = (navId) => navParamOf(untracked(() => store.navMap())[knownNavId(navId)]);
|
|
4605
|
+
/**
|
|
4606
|
+
* Follows a NavRef whose dynamic segments are keyed by the *Nav* that
|
|
4607
|
+
* contributes each one rather than by its parameter name (m-one-ui
|
|
4608
|
+
* CONTEXT.md OutcomeNav). The map is what knows the names, so a NavParam
|
|
4609
|
+
* renamed after the caller was emitted still fills the right segment.
|
|
4610
|
+
*/
|
|
4611
|
+
const followNav = (navId, byNav, options) => {
|
|
4612
|
+
const entries = Object.entries(byNav ?? {});
|
|
4613
|
+
const params = entries.length
|
|
4614
|
+
? Object.fromEntries(entries.map(([id, value]) => [paramNameOf(id), value]))
|
|
4615
|
+
: undefined;
|
|
4616
|
+
goToNav(knownNavId(navId), params, options);
|
|
4617
|
+
};
|
|
4618
|
+
/** The current value of the parameter one dynamic Nav contributes. */
|
|
4619
|
+
const routeParamOf = (navId) => untracked(() => store.routeParams())[paramNameOf(navId)];
|
|
4620
|
+
/**
|
|
4621
|
+
* Up one level from the page the User stands on — the nearest ancestor on
|
|
4622
|
+
* the matched route chain, so a grouping parent, a Murl or a Nav with no
|
|
4623
|
+
* Page is passed over for the first one that routes. A dynamic ancestor
|
|
4624
|
+
* keeps its value, the path above it being unchanged. On `root`, or where
|
|
4625
|
+
* nothing above routes, nothing happens. Any open panel closes with the
|
|
4626
|
+
* move, a Url address carrying no Murl.
|
|
4627
|
+
*/
|
|
4628
|
+
const goToParentNav = (options) => {
|
|
4629
|
+
const current = untracked(() => store.routeNavId());
|
|
4630
|
+
if (!current || current === ROOT_NAV$1)
|
|
4631
|
+
return;
|
|
4632
|
+
const path = untracked(() => store.path());
|
|
4633
|
+
const parent = [...untracked(() => store.routeChain())]
|
|
4634
|
+
.reverse()
|
|
4635
|
+
.find((entry) => entry.navId !== current &&
|
|
4636
|
+
current.startsWith(`${entry.navId}_`) &&
|
|
4637
|
+
// A `default` child answers its parent's own address.
|
|
4638
|
+
entry.path !== path);
|
|
4639
|
+
if (!parent)
|
|
4640
|
+
return;
|
|
4641
|
+
patchState(store, { menuNavId: undefined });
|
|
4642
|
+
router.navigateByUrl(parent.path, {
|
|
4643
|
+
replaceUrl: !!options?.replaceUrl,
|
|
4644
|
+
});
|
|
4568
4645
|
};
|
|
4569
4646
|
/** Closes the panel, popping our own entry when we are the one who pushed it. */
|
|
4570
4647
|
const closePanel = () => {
|
|
@@ -4594,6 +4671,7 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4594
4671
|
const syncFromRouter = rxMethod(pipe(filter((s) => !!s), tap((snapshot) => {
|
|
4595
4672
|
const routeNavId = routeNavIdOf(snapshot.root);
|
|
4596
4673
|
const routeParams = routeParamsOf(snapshot.root);
|
|
4674
|
+
const routeChain = routeChainOf(snapshot.root);
|
|
4597
4675
|
const murl = murlOf(snapshot.root);
|
|
4598
4676
|
const path = router.url.split(MURL_SEP)[0].split('?')[0];
|
|
4599
4677
|
untracked(() => {
|
|
@@ -4603,6 +4681,7 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4603
4681
|
path,
|
|
4604
4682
|
routeNavId,
|
|
4605
4683
|
routeParams,
|
|
4684
|
+
routeChain,
|
|
4606
4685
|
murl,
|
|
4607
4686
|
menuNavId: undefined,
|
|
4608
4687
|
// Address changes clear the icon-opened flag (ADR 0013), except
|
|
@@ -4728,6 +4807,9 @@ const NavStore = signalStore({ providedIn: 'root' }, withState(initialState$3),
|
|
|
4728
4807
|
return {
|
|
4729
4808
|
addressFor,
|
|
4730
4809
|
goToNav,
|
|
4810
|
+
followNav,
|
|
4811
|
+
goToParentNav,
|
|
4812
|
+
routeParamOf,
|
|
4731
4813
|
closePanel,
|
|
4732
4814
|
syncFromRouter,
|
|
4733
4815
|
toggleMenu,
|
|
@@ -7265,7 +7347,7 @@ class SectionFormItemComponent extends ConfigComponent {
|
|
|
7265
7347
|
break;
|
|
7266
7348
|
}
|
|
7267
7349
|
case InputType.TOGGLE: {
|
|
7268
|
-
const { ToggleInputComponent } = await import('./magmonium-one-toggle-
|
|
7350
|
+
const { ToggleInputComponent } = await import('./magmonium-one-toggle-CVVVBuRw.mjs');
|
|
7269
7351
|
this.createDynamicComponent(seq, ToggleInputComponent, [], true);
|
|
7270
7352
|
break;
|
|
7271
7353
|
}
|
|
@@ -7277,12 +7359,12 @@ class SectionFormItemComponent extends ConfigComponent {
|
|
|
7277
7359
|
break;
|
|
7278
7360
|
}
|
|
7279
7361
|
case InputType.PASSWORD: {
|
|
7280
|
-
const { PasswordInputComponent } = await import('./magmonium-one-password-
|
|
7362
|
+
const { PasswordInputComponent } = await import('./magmonium-one-password-CxXKymRW.mjs');
|
|
7281
7363
|
this.createDynamicComponent(seq, PasswordInputComponent);
|
|
7282
7364
|
break;
|
|
7283
7365
|
}
|
|
7284
7366
|
case InputType.OTP: {
|
|
7285
|
-
const { OtpInputComponent } = await import('./magmonium-one-otp-
|
|
7367
|
+
const { OtpInputComponent } = await import('./magmonium-one-otp-BqKz65Xa.mjs');
|
|
7286
7368
|
this.createDynamicComponent(seq, OtpInputComponent);
|
|
7287
7369
|
break;
|
|
7288
7370
|
}
|
|
@@ -21393,7 +21475,7 @@ class WrapperInputComponent extends ConfigComponent {
|
|
|
21393
21475
|
break;
|
|
21394
21476
|
}
|
|
21395
21477
|
case InputType.TOGGLE: {
|
|
21396
|
-
const { ToggleInputComponent } = await import('./magmonium-one-toggle-
|
|
21478
|
+
const { ToggleInputComponent } = await import('./magmonium-one-toggle-CVVVBuRw.mjs');
|
|
21397
21479
|
this.createDynamicComponent(seq, ToggleInputComponent, [], true);
|
|
21398
21480
|
break;
|
|
21399
21481
|
}
|
|
@@ -21405,12 +21487,12 @@ class WrapperInputComponent extends ConfigComponent {
|
|
|
21405
21487
|
break;
|
|
21406
21488
|
}
|
|
21407
21489
|
case InputType.PASSWORD: {
|
|
21408
|
-
const { PasswordInputComponent } = await import('./magmonium-one-password-
|
|
21490
|
+
const { PasswordInputComponent } = await import('./magmonium-one-password-CxXKymRW.mjs');
|
|
21409
21491
|
this.createDynamicComponent(seq, PasswordInputComponent);
|
|
21410
21492
|
break;
|
|
21411
21493
|
}
|
|
21412
21494
|
case InputType.OTP: {
|
|
21413
|
-
const { OtpInputComponent } = await import('./magmonium-one-otp-
|
|
21495
|
+
const { OtpInputComponent } = await import('./magmonium-one-otp-BqKz65Xa.mjs');
|
|
21414
21496
|
this.createDynamicComponent(seq, OtpInputComponent);
|
|
21415
21497
|
break;
|
|
21416
21498
|
}
|
|
@@ -23117,7 +23199,7 @@ class FileUploadInputComponent extends BaseInputComponent {
|
|
|
23117
23199
|
const modalStore = this.modalStore;
|
|
23118
23200
|
if (!modalStore)
|
|
23119
23201
|
return undefined;
|
|
23120
|
-
const { ImageEditorComponent } = await import('./magmonium-one-image-editor-
|
|
23202
|
+
const { ImageEditorComponent } = await import('./magmonium-one-image-editor-BvkG6Cvh.mjs');
|
|
23121
23203
|
const ratio = String(this.config()?.ratio ?? '');
|
|
23122
23204
|
return new Promise((resolve) => {
|
|
23123
23205
|
const modalRef = new ModalRef();
|
|
@@ -24753,7 +24835,7 @@ function getClassList$1(config) {
|
|
|
24753
24835
|
return classList.join(' ');
|
|
24754
24836
|
}
|
|
24755
24837
|
|
|
24756
|
-
const INTERACTIVE_SELECTOR = 'button, a, input, textarea, select, [role="button"], [contenteditable="true"]';
|
|
24838
|
+
const INTERACTIVE_SELECTOR = 'button, a, input, textarea, select, [role="button"], [role="link"], [contenteditable="true"]';
|
|
24757
24839
|
/** A button/link inside the card owns its click — it must not also fire the card's. */
|
|
24758
24840
|
const isFromNestedControl = (event) => {
|
|
24759
24841
|
const surface = event.currentTarget;
|
|
@@ -24769,6 +24851,12 @@ class CardComponent extends ConfigComponent {
|
|
|
24769
24851
|
href = input(...(ngDevMode ? [undefined, { debugName: "href" }] : /* istanbul ignore next */ []));
|
|
24770
24852
|
clickable = input(...(ngDevMode ? [undefined, { debugName: "clickable" }] : /* istanbul ignore next */ []));
|
|
24771
24853
|
clicked = output();
|
|
24854
|
+
// A `[routerLink]` on the host listens on the host itself, past every guard
|
|
24855
|
+
// below, so a nested control's click would navigate the card too.
|
|
24856
|
+
hostRouterLink = inject(RouterLink, {
|
|
24857
|
+
self: true,
|
|
24858
|
+
optional: true,
|
|
24859
|
+
});
|
|
24772
24860
|
effectiveConfig = computed(() => ({
|
|
24773
24861
|
...this.config(),
|
|
24774
24862
|
variant: this.variant() ?? this.config()?.variant,
|
|
@@ -24788,8 +24876,11 @@ class CardComponent extends ConfigComponent {
|
|
|
24788
24876
|
onCardClick = (event) => {
|
|
24789
24877
|
if (this.isDesignMode)
|
|
24790
24878
|
event.preventDefault();
|
|
24791
|
-
if (isFromNestedControl(event))
|
|
24879
|
+
if (isFromNestedControl(event)) {
|
|
24880
|
+
if (this.hostRouterLink)
|
|
24881
|
+
event.stopPropagation();
|
|
24792
24882
|
return;
|
|
24883
|
+
}
|
|
24793
24884
|
if (this.href() || !this.isClickable())
|
|
24794
24885
|
return;
|
|
24795
24886
|
this.clicked.emit();
|
|
@@ -36850,4 +36941,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
36850
36941
|
*/
|
|
36851
36942
|
|
|
36852
36943
|
export { ColComponent as $, ACCESS_DOMAINS as A, ButtonComponent as B, Assets as C, AuthActivityPageComponent as D, AuthApiService as E, AuthStore as F, AutosizeDirective as G, HeaderComponent$1 as H, InputType as I, BadgeComponent as J, BandingComponent as K, LabelComponent as L, MODAL_REF as M, BaseArrayInputComponent as N, BaseRootWebComponent as O, BaseWebComponent as P, ButtonGroupComponent as Q, RangeInputComponent as R, COMPONENT_INPUT_REGISTRY as S, TranslatePipe as T, CardComponent as U, CardWrapperComponent as V, CarouselComponent as W, ChartComponent as X, ChatBubbleComponent as Y, CheckboxInputComponent as Z, ClearableInputComponent as _, MIN_ZOOM as a, MHeroColorDirective as a$, ColorPickerInputComponent as a0, CommentItemComponent as a1, CommentsApiService as a2, CommentsComponent as a3, CommentsStore as a4, CompactNumberPipe as a5, ComponentInputComponent as a6, ComponentStepperComponent as a7, ConfigComponent as a8, ConfirmComponent as a9, FileService as aA, FileUploadDirective as aB, FileUploadInputComponent as aC, FlexComponent as aD, FlexItemComponent as aE, FormGroupComponent as aF, FrameComponent as aG, FreezeService as aH, GRID_BREAKPOINTS as aI, GetNavService as aJ, HighlightDirective as aK, HttpService as aL, ICON_SOURCE as aM, IS_SIDE_PANEL as aN, IconComponent as aO, ImgComponent as aP, InstrumentScoreComponent as aQ, InterceptorObservables as aR, JumbotronComponent as aS, KeyValueComponent as aT, LAYOUT_ASSET_FOLDER as aU, LOGIN_COMPONENT as aV, LOGIN_STORE as aW, LanguageComponent as aX, ListComponent as aY, LogoComponent as aZ, MAG_SOCKET_EVENT as a_, ContextMenuComponent as aa, CustomIconClass as ab, CustomIconEditComponent as ac, DEFAULT_DENIAL as ad, DEFAULT_FILTER_RANGE_MODE as ae, DEFAULT_FILTER_VARIANT as af, DEFAULT_NAV_PARAM as ag, DEFAULT_NAV_SEGMENT as ah, DEFAULT_SIZE as ai, DashboardCardComponent as aj, DateInputComponent as ak, DatePickerComponent as al, DeviceService as am, DomService as an, Domain as ao, DotGridComponent as ap, DragListDirective as aq, DragListItemDirective as ar, DraggableDirective as as, DropdownInputComponent as at, FILTER_GROUP_CONTEXT as au, FILTER_RANGE_MODES as av, FILTER_VARIANTS as aw, FLEX_VARIANTS as ax, FOLDER_PICK_LISTENER as ay, FORM_ASSET_FOLDER as az, MAX_ZOOM as b, SEARCH_QUERY as b$, MHeroComponent as b0, MODAL_STORE_REF as b1, MRefDirective as b2, MStepComponent as b3, MURL_PARAM as b4, MURL_SEP as b5, ManifestEnrichmentService as b6, MenuComponent as b7, ModalDirective as b8, ModalRef as b9, OPTIONS_SOURCE as bA, OVERLAY_WIDGETS as bB, OneApp as bC, OptionsSourceDirective as bD, OverlayBodyComponent as bE, OverlayRef as bF, OverlayService as bG, PLATFORM_BUTTON_NAV_IDS as bH, PLATFORM_EXTENSIBLE_NAV_IDS as bI, PLATFORM_NAV_MAP as bJ, PLATFORM_ROOT_CHILDREN as bK, PaginationComponent as bL, PanelComponent as bM, PercentagePipe as bN, PlaygroundComponent as bO, PositionDirective as bP, PwaInstallComponent as bQ, ROOT_NAV$1 as bR, RadioGroupComponent as bS, RadioInputComponent as bT, RatingInputComponent as bU, ReactiveElementComponent as bV, RemoteComponent as bW, RemoteLoaderService as bX, ResizeElementComponent as bY, RouteContainer as bZ, RowComponent as b_, ModalStore as ba, MoneyPipe as bb, MultiRangeInputComponent as bc, MurlUrlSerializer as bd, NAV_DEFAULT_MURL as be, NAV_ID_SEP as bf, NAV_MAIN_BUTTONS as bg, NAV_SEGMENT_RE as bh, NAV_STORE_REF as bi, NAV_WC_COMPONENTS as bj, NAV_WIDGET_MAP as bk, NavComponent as bl, NavDetailsComponent as bm, NavHeaderComponent as bn, NavMenuComponent as bo, NavStore as bp, NavTrailComponent as bq, NothingComponent as br, NotificationElementComponent as bs, NotificationGroupComponent as bt, NotificationPopupComponent as bu, NotificationService as bv, NotificationStore as bw, NotificationType as bx, NotificationWidgetComponent as by, ONE_ASSET_BASE_URL as bz, cropRect as c, ThemeDataService as c$, SEARCH_RESULTS_EVENT as c0, SECTION_ACCORDION_GROUP as c1, SECTION_FORM_CONTEXT as c2, SHARED_ICONS as c3, SIZE_CONTEXT as c4, ScoreComponent as c5, ScrollComponent as c6, ScrollService as c7, SearchPanelComponent as c8, SearchStore as c9, SelectorDirective as cA, SettingsSearchBarComponent as cB, SettingsSearchService as cC, ShapeComponent as cD, SharedStoreRegistry as cE, SidePanelDirective as cF, Size as cG, SocketStore as cH, SortComponent as cI, StatComponent as cJ, StepComponent as cK, StepperComponent as cL, StepsComponent as cM, StorageService as cN, StrokeLinecap as cO, StrokeLinejoin as cP, SummaryComponent as cQ, SvgGeneratorComponent as cR, SvgGeneratorService as cS, SvgService as cT, TOTAL_COLUMNS as cU, TRANSLATION_SOURCE as cV, TableComponent as cW, TechnicalMeterComponent as cX, TextInputComponent as cY, TextareaInputComponent as cZ, ThemeComponent as c_, SearchUserPanelComponent as ca, SectionAccordionDirective as cb, SectionAccordionGroupDirective as cc, SectionBackComponent as cd, SectionBadgesComponent as ce, SectionButtonGroupComponent as cf, SectionCardComponent as cg, SectionCarouselComponent as ch, SectionComponent as ci, SectionFilterComponent as cj, SectionFilterGroupComponent as ck, SectionFilterMenuComponent as cl, SectionFilterPanelComponent as cm, SectionFilterRangePanelComponent as cn, SectionFooterComponent as co, SectionFormComponent as cp, SectionFormItemComponent as cq, SectionHeaderComponent as cr, SectionHeroComponent as cs, SectionPaginationComponent as ct, SectionSearchComponent as cu, SectionStepperComponent as cv, SectionTabsComponent as cw, SectionToggleComponent as cx, SectionToggleItemDirective as cy, SelectableCardInputComponent as cz, drawFramed as d, filterNumberList as d$, ThemeService as d0, ThemeStore as d1, TimeAgoPipe as d2, TimelineComponent as d3, ToggleButtonComponent as d4, ToggleInputComponent as d5, ToggleRadioInputComponent as d6, ToolTipDirective as d7, TooltipComponent as d8, TranslateService as d9, calculateRanks as dA, cellText as dB, checkFilterCondition as dC, childNavId as dD, claimDenial as dE, classListSignal as dF, coerceSize as dG, cornerEdge as dH, cornerSide as dI, createMap as dJ, createPlatformNavMap as dK, deriveAvatarGradient as dL, deriveContrastColor as dM, deriveOppositeColor as dN, derivePropertyName as dO, emailValidation as dP, evaluate as dQ, evaluateBool as dR, fieldBoolean as dS, fieldNumber as dT, fieldString as dU, filterHoldsList as dV, filterHoldsOneBound as dW, filterHoldsOptions as dX, filterHoldsRange as dY, filterList as dZ, filterNumber as d_, TreeGridComponent as da, URL_SEP as db, USER_STORE_REF as dc, USER_TAB_MAP as dd, UniverseComponent as de, UserApiService as df, UserAvatarComponent as dg, UserComponent as dh, UserNavComponent as di, UserSettingsComponent as dj, UserStore as dk, WC_ROUTE_CHANGED_EVENT as dl, WC_SEARCH_GROUPS as dm, WIN_USER_TAB_HOOK as dn, WIN_USER_TAB_KEY as dp, WatermarkComponent as dq, WcRouterStore as dr, WrapperInputComponent as ds, anchorNavId as dt, applyColorsToElement as du, assetOptions as dv, bootstrapMagApp as dw, bootstrapPwaInstall as dx, buildWcBaseUrl as dy, calculateLuminance as dz, encodeFramed as e, miniMarkToHtml as e$, filterOne as e0, filterPanelOf as e1, filterPanelWidth as e2, filterRange as e3, filterTreeGridRows as e4, filterValueList as e5, filterValues as e6, flattenTreeGridRows as e7, formatBadgeCount as e8, fullName as e9, isLocalhost as eA, isNavInstanceConfig as eB, isNavMenuConfig as eC, isNavRowsConfig as eD, isNavVisibilityConfig as eE, isPlatformNavId as eF, isSize as eG, isTierPreview as eH, isUrlLocalhost as eI, isValidNavId as eJ, isValidNavSegment as eK, isWebComponent as eL, linkToId as eM, linkToNav as eN, loadingActions as eO, mInterceptor as eP, manualValidation as eQ, matchFieldValidation as eR, maxLengthValidation as eS, maxValidation as eT, mergePlatformNav as eU, mergeUnique as eV, mergeUniqueBy as eW, mergeUniqueWith as eX, minAgeValidation as eY, minLengthValidation as eZ, minValidation as e_, generateClipPath as ea, generateTransform as eb, getClassList as ec, getProperty as ed, getScrollParent as ee, getTierFromPreviewPath as ef, getTreeGridRow as eg, getUniqueId as eh, getValue as ei, hasErrorComputed as ej, hexToRgb as ek, hslToRgb$1 as el, initMagmoniumApp as em, initialNotificationState as en, initialState$2 as eo, initials as ep, injectAuthenticate as eq, injectDefaultDenial as er, injectInstallApp as es, injectParentSize as et, injectScrollSticky as eu, isButtonName as ev, isCancelledComputed as ew, isExtensiblePlatformNavId as ex, isJson as ey, isLoadingComputed as ez, clampFraming as f, navIdChain as f0, navIdFor as f1, navIdSegment as f2, navIdToRoutePath as f3, navIdToSegments as f4, navParamOf as f5, navToId as f6, navVisibilityGuard as f7, normalizeAssetOptions as f8, parentNavId as f9, resolveIconSize as fA, resolvePallet as fB, resolvePatternRules as fC, resolveSize as fD, rgbToHex as fE, rgbToHsl as fF, rowHasChildren as fG, samePatterns as fH, segmentsToNavId as fI, setProperty as fJ, setTreeGridChildren as fK, settingsWidgets as fL, shouldShowBadge as fM, splitNavId as fN, splitOnMatch as fO, stringToColor as fP, toAttrBool as fQ, toAttrNumber as fR, toCssLength as fS, toHostNavId as fT, toLength$1 as fU, toLocalNavId as fV, toggleTreeGridRow as fW, unfetchedPlatformNav as fX, urlValidation as fY, parseAddress as fa, parseColor as fb, parsePatternNames as fc, patternValidation as fd, patternsValidation as fe, permissionRefusal as ff, platformNavWidgets as fg, privateGuard as fh, processImageToSvg as fi, provideAppContext as fj, provideMagAppConfig as fk, provideMagWcConfig as fl, provideMagWcRoutes as fm, provideModalComponents as fn, provideMurlUrlSerializer as fo, provideNavWidgets as fp, provideOverlayWidgets as fq, providePlatformNavWidgets as fr, provideSearch as fs, provideSizeContext as ft, provideUserTabs as fu, publicGuard as fv, readFieldPatterns as fw, renderAddress as fx, requiredValidation as fy, resolveConfigAsset as fz, BaseInputComponent as g, BaseTextInputComponent as h, initialFraming as i, TextOutputComponent as j, IS_DESIGN_MODE as k, APP_CONTEXT_REF as l, ASSET_BASE_URL as m, AccordionBodyDirective as n, outputSize as o, parseRatio as p, AccordionComponent as q, renameForType as r, AccordionGroupComponent as s, ActionComponent as t, AnimatedGraphsComponent as u, AppCardComponent as v, AppRelationType as w, AppTileComponent as x, AssetStore as y, AssetUrlPipe as z };
|
|
36853
|
-
//# sourceMappingURL=magmonium-one-magmonium-one-
|
|
36944
|
+
//# sourceMappingURL=magmonium-one-magmonium-one-9qp__mDn.mjs.map
|