@magicpages/kalotyp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Type definitions for the Ghost integration contract.
3
+ *
4
+ * Source of truth is the Ghost Ember admin (`koenig-image-editor.js:171-225`)
5
+ * and the Koenig hook (`usePinturaEditor.js:79-134`). See
6
+ * `docs/ghost-contract.md` §3 for every key, the line in Ghost where it's
7
+ * passed, and what Ghost expects it to do.
8
+ */
9
+ export type EditorEventName = 'process' | 'loaderror';
10
+ export interface ProcessEvent {
11
+ /** The edited image. Ghost reads `result.dest` and nothing else (§4.2). */
12
+ dest: File;
13
+ }
14
+ export interface LoadErrorEvent {
15
+ message: string;
16
+ cause?: unknown;
17
+ }
18
+ export type EditorEventPayloads = {
19
+ process: ProcessEvent;
20
+ loaderror: LoadErrorEvent;
21
+ };
22
+ export type LocaleCallback = (locale: Record<string, string>) => string;
23
+ export type FrameStyle = 'solidSharp' | 'solidRound' | 'lineSingle' | 'hook' | 'polaroid';
24
+ export type FrameOption = readonly [FrameStyle | undefined, LocaleCallback];
25
+ export type CropPreset = readonly [number | undefined, string];
26
+ export type CropPresetFilter = 'landscape' | 'portrait';
27
+ export interface EditorOptions {
28
+ /** Source image. Always a URL string when called from Ghost (§3 src). */
29
+ src: string | Blob | File;
30
+ enableTransparencyGrid?: boolean;
31
+ util?: string;
32
+ utils?: readonly string[];
33
+ frameOptions?: readonly FrameOption[];
34
+ cropSelectPresetFilter?: CropPresetFilter;
35
+ cropSelectPresetOptions?: readonly CropPreset[];
36
+ locale?: Partial<Record<string, string>>;
37
+ /** Synchronous veto for close requests. Returning false keeps the editor open (§3 willClose, §8.2). */
38
+ willClose?: () => boolean;
39
+ /** Set by Koenig + admin-x-settings, not by the Ember admin (§9). */
40
+ previewPad?: boolean;
41
+ /** Permit unknown keys; we don't crash on extras. */
42
+ [key: string]: unknown;
43
+ }
44
+ export interface EditorInstance {
45
+ on<K extends EditorEventName>(event: K, listener: (payload: EditorEventPayloads[K]) => void): void;
46
+ off<K extends EditorEventName>(event: K, listener: (payload: EditorEventPayloads[K]) => void): void;
47
+ }
48
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,cAAc,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC;AACxE,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAC1F,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,EAAE,cAAc,CAAC,CAAC;AAC5E,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,sBAAsB,CAAC,EAAE,gBAAgB,CAAC;IAC1C,uBAAuB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,uGAAuG;IACvG,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,CAAC,SAAS,eAAe,EAC1B,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,GAClD,IAAI,CAAC;IACR,GAAG,CAAC,CAAC,SAAS,eAAe,EAC3B,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,GAClD,IAAI,CAAC;CACT"}
@@ -0,0 +1,9 @@
1
+ import type { CropPreset } from './contract.js';
2
+ /**
3
+ * The 12-entry preset list Ghost always passes (`docs/ghost-contract.md`
4
+ * §3). Used as a fallback when a non-Ghost caller invokes our API without
5
+ * supplying `cropSelectPresetOptions`. Order and labels match Ghost's
6
+ * source verbatim.
7
+ */
8
+ export declare const DEFAULT_CROP_PRESETS: readonly CropPreset[];
9
+ //# sourceMappingURL=default-presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-presets.d.ts","sourceRoot":"","sources":["../src/default-presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,UAAU,EAarD,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type AnnotateState, type ChainLink, type CropPreset, type CropPresetFilter, type CropState, type EncodeOptions, type FinetuneState, type FlipState, type FramePresetId, type FrameState, type LoadedImage, type RedactState, type ResizeState, type RotateState, type SourceImage, type UtilityPlugin } from '@magicpages/kalotyp-core';
2
+ import type { EditorInstance, EditorOptions } from './contract.js';
3
+ type CropFactoryOptions = {
4
+ presets: readonly CropPreset[];
5
+ presetFilter: CropPresetFilter | undefined;
6
+ panelHost: HTMLElement;
7
+ };
8
+ type FrameFactoryOptions = {
9
+ panelHost: HTMLElement;
10
+ labels?: Partial<Record<FramePresetId, string>> | undefined;
11
+ };
12
+ export interface EditorDependencies {
13
+ sourceToFile(src: string | Blob | File): Promise<File>;
14
+ loadImage(src: string | Blob | File): Promise<LoadedImage>;
15
+ encodeSourceImage(source: SourceImage, options: EncodeOptions): Promise<File>;
16
+ createCropPlugin(options: CropFactoryOptions): UtilityPlugin<CropState>;
17
+ createRotatePlugin(options: {
18
+ panelHost: HTMLElement;
19
+ }): UtilityPlugin<RotateState>;
20
+ createFlipPlugin(options: {
21
+ panelHost: HTMLElement;
22
+ }): UtilityPlugin<FlipState>;
23
+ createFinetunePlugin(options: {
24
+ panelHost: HTMLElement;
25
+ }): UtilityPlugin<FinetuneState>;
26
+ createFilterPlugin(options: {
27
+ panelHost: HTMLElement;
28
+ }): UtilityPlugin<FinetuneState>;
29
+ createAnnotatePlugin(options: {
30
+ panelHost: HTMLElement;
31
+ }): UtilityPlugin<AnnotateState>;
32
+ createRedactPlugin(options: {
33
+ panelHost: HTMLElement;
34
+ }): UtilityPlugin<RedactState>;
35
+ createResizePlugin(options: {
36
+ panelHost: HTMLElement;
37
+ }): UtilityPlugin<ResizeState>;
38
+ createFramePlugin(options: FrameFactoryOptions): UtilityPlugin<FrameState>;
39
+ runUtilityChain(links: readonly ChainLink[], source: SourceImage): Promise<SourceImage>;
40
+ }
41
+ export declare function openDefaultEditor(options: EditorOptions, dependencies?: EditorDependencies): EditorInstance;
42
+ export {};
43
+ //# sourceMappingURL=editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAEd,KAAK,aAAa,EAGlB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,KAAK,WAAW,EAEhB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAEhB,KAAK,WAAW,EAKhB,KAAK,aAAa,EAYnB,MAAM,0BAA0B,CAAC;AA+BlC,OAAO,KAAK,EAGV,cAAc,EACd,aAAa,EAEd,MAAM,eAAe,CAAC;AAIvB,KAAK,kBAAkB,GAAG;IACxB,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,YAAY,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC3C,SAAS,EAAE,WAAW,CAAC;CACxB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,WAAW,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CAC7D,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3D,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACxE,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACpF,gBAAgB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAChF,oBAAoB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;IACxF,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;IACtF,oBAAoB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;IACxF,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACpF,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACpF,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAC3E,eAAe,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACzF;AAsDD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,aAAa,EACtB,YAAY,GAAE,kBAAwC,GACrD,cAAc,CA+ahB"}
@@ -0,0 +1,4 @@
1
+ import { openDefaultEditor } from './editor.js';
2
+ export { openDefaultEditor };
3
+ export type { EditorEventName, EditorEventPayloads, EditorInstance, EditorOptions, ProcessEvent, LoadErrorEvent, } from './contract.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOhD,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Assign Kalotyp's editor to `window.pintura`. Ghost's loader (§5.5,
3
+ * §12.2) reads the resolved module value from dynamic `import()` but
4
+ * ignores it — the contract is purely this side effect.
5
+ *
6
+ * The brand name appears here intentionally and only here. It is the
7
+ * literal global identifier Ghost looks up in
8
+ * `koenig-image-editor.js:171`. Renaming this would break the integration.
9
+ */
10
+ export declare function installGlobal(target?: typeof globalThis): void;
11
+ //# sourceMappingURL=install-global.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-global.d.ts","sourceRoot":"","sources":["../src/install-global.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,OAAO,UAAuB,GAAG,IAAI,CAa1E"}
@@ -0,0 +1 @@
1
+ .pintura-editor{--color-background: 255, 255, 255;--color-foreground: 21, 23, 26;--font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif;--editor-modal-border-radius: 0px;color-scheme:light;--kalotyp-success: 48, 207, 67;--kalotyp-border: rgba(var(--color-foreground), .16);--kalotyp-border-strong: rgba(var(--color-foreground), .36);--kalotyp-muted: rgba(var(--color-foreground), .7);--kalotyp-soft: rgba(var(--color-foreground), .08);--kalotyp-track: rgba(var(--color-foreground), .1);--kalotyp-radius: 6px;--kalotyp-radius-lg: 10px;--kalotyp-control-height: 36px;--kalotyp-text-size: 13px;--kalotyp-transition: all .2s ease;position:fixed;inset:0;z-index:2147483646;display:flex;background:rgb(var(--color-background));font-family:var(--font-family);color:rgb(var(--color-foreground));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:14px;line-height:1.5}html:not(.dark) .pintura-editor{--color-background: 255, 255, 255 !important;--color-foreground: 21, 23, 26 !important;color-scheme:light}html.dark .pintura-editor{--color-background: 21, 23, 26 !important;--color-foreground: 244, 245, 246 !important;color-scheme:dark}.PinturaModal{position:relative!important;display:flex!important;flex:1 1 auto!important;width:100%!important;height:100%!important;min-height:0!important;background:rgb(var(--color-background));border-radius:var(--editor-modal-border-radius);overflow:hidden}.kalotyp-editor:focus,.kalotyp-editor:focus-visible{outline:none}.kalotyp-button-prefs{position:absolute;top:18px;right:56px;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:var(--kalotyp-radius);background:transparent;color:var(--kalotyp-muted);font-size:16px;line-height:1;cursor:pointer;z-index:2;transition:var(--kalotyp-transition)}.kalotyp-button-prefs svg{width:16px;height:16px}.kalotyp-button-prefs:hover{background:var(--kalotyp-soft);color:rgb(var(--color-foreground))}.kalotyp-button-prefs:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-button-close{position:absolute;top:18px;right:14px;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:var(--kalotyp-radius);background:transparent;color:var(--kalotyp-muted);font-size:16px;line-height:1;cursor:pointer;z-index:2;transition:var(--kalotyp-transition)}.kalotyp-button-close svg{width:16px;height:16px}.kalotyp-button-close:hover{background:var(--kalotyp-soft);color:rgb(var(--color-foreground))}.kalotyp-button-close:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-root{display:grid!important;grid-template-rows:auto minmax(0,1fr) auto!important;grid-template-columns:minmax(0,1fr)!important;width:100%!important;height:100%!important;min-height:0!important}.kalotyp-root[data-env~=landscape]{grid-template-rows:auto 1fr auto}.kalotyp-nav-tools{display:flex;align-items:center;gap:8px;padding:14px 180px 14px 24px;border-bottom:1px solid var(--kalotyp-border);min-height:56px;flex:0 0 auto}.kalotyp-history-controls{position:absolute;top:18px;right:100px;display:inline-flex;align-items:center;gap:4px;z-index:2}.kalotyp-history-button{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--kalotyp-muted);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-history-button svg{width:16px;height:16px}.kalotyp-history-button:hover:not(:disabled){color:rgb(var(--color-foreground));background:var(--kalotyp-track)}.kalotyp-history-button:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-history-button:disabled{opacity:.35;cursor:not-allowed}.kalotyp-main{display:flex!important;flex-direction:column!important;min-height:0!important;padding:12px 16px 0;gap:12px;background:rgb(var(--color-background))}.kalotyp-stage{position:relative!important;flex:1 1 0!important;min-height:0!important;border-radius:var(--kalotyp-radius);background:rgba(var(--color-foreground),.06)}.kalotyp-util-footer{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:14px 24px;border-top:1px solid var(--kalotyp-border)}.pintura-editor .kalotyp-root>.kalotyp-nav-tools{padding-bottom:14px!important}.pintura-editor .kalotyp-root .kalotyp-stage{max-width:none!important;margin:0!important}.pintura-editor .kalotyp-root[data-env~=landscape] .kalotyp-util-main,.pintura-editor .kalotyp-root[data-env~=landscape] .kalotyp-util-footer{padding-right:24px!important}.kalotyp-export-group{display:inline-flex;align-items:stretch;height:var(--kalotyp-control-height);border:1px solid rgb(var(--color-foreground));border-radius:var(--kalotyp-radius);background:rgb(var(--color-foreground));overflow:hidden;isolation:isolate;transition:var(--kalotyp-transition)}.kalotyp-export-group:focus-within{box-shadow:var(--kalotyp-focus-shadow)}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-export{display:inline-flex!important;align-items:center;justify-content:center;height:100%!important;padding:0 18px!important;border:0!important;border-radius:0!important;background:transparent!important;color:rgb(var(--color-background))!important;font-family:inherit;font-size:var(--kalotyp-text-size);font-weight:700!important;line-height:1;cursor:pointer;transition:background .18s ease;opacity:1!important}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-export:hover{background:rgba(var(--color-background),.12)!important;color:rgb(var(--color-background))!important;opacity:1!important}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-export:focus-visible{outline:none;background:rgba(var(--color-background),.12)!important}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-export:disabled{opacity:.4!important;cursor:not-allowed}.kalotyp-button-inner{display:inline-block}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-output-settings{display:inline-flex!important;align-items:center;justify-content:center;height:100%!important;width:36px;padding:0;border:0!important;border-radius:0!important;background:transparent!important;color:rgb(var(--color-background))!important;cursor:pointer;transition:background .18s ease;opacity:1!important;box-shadow:inset 1px 0 rgba(var(--color-background),.22)}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-output-settings:hover{background:rgba(var(--color-background),.12)!important;color:rgb(var(--color-background))!important;opacity:1!important}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-output-settings:focus-visible{outline:none;background:rgba(var(--color-background),.12)!important}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-output-settings:disabled{opacity:.4!important;cursor:not-allowed}.pintura-editor .kalotyp-root .kalotyp-export-group .kalotyp-button-output-settings[aria-expanded=true]{background:rgba(var(--color-background),.18)!important}.pintura-editor .kalotyp-root .kalotyp-export-group:hover{background:rgba(var(--color-foreground),.92);border-color:rgba(var(--color-foreground),.92)}.kalotyp-visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.pintura-editor{--kalotyp-focus-ring: rgb(var(--color-foreground));--kalotyp-focus-halo: rgb(var(--color-background));--kalotyp-focus-shadow: 0 0 0 2px var(--kalotyp-focus-halo), 0 0 0 4px var(--kalotyp-focus-ring)}.kalotyp-nested-overlay{position:absolute;inset:0;z-index:50;display:flex;align-items:center;justify-content:center}.kalotyp-nested-overlay--modal{background:rgba(var(--color-foreground),.32)}.kalotyp-nested-overlay--popover{background:transparent;pointer-events:auto}.kalotyp-nested-surface{position:relative;background:rgb(var(--color-background));color:rgb(var(--color-foreground));border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius-lg);box-shadow:0 10px 30px #0000002e,0 2px 6px #00000014;min-width:280px;max-width:min(520px,calc(100% - 32px));max-height:calc(100% - 32px);overflow:hidden;display:flex;flex-direction:column}.kalotyp-nested-surface:focus-visible{outline:none}.kalotyp-nested-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--kalotyp-border)}.kalotyp-nested-title{margin:0;font-size:14px;font-weight:600;line-height:1.2}.kalotyp-nested-close{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid transparent;border-radius:var(--kalotyp-radius);background:transparent;color:var(--kalotyp-muted);font-size:22px;line-height:1;cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-nested-close:hover{background:var(--kalotyp-soft);color:rgb(var(--color-foreground))}.kalotyp-nested-close:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-nested-body{padding:16px 14px;overflow-y:auto}.kalotyp-stage-container{position:absolute;inset:0;overflow:hidden;background:transparent;user-select:none;touch-action:none}.kalotyp-stage-status{position:absolute;inset:50% 0 auto;display:flex;align-items:center;justify-content:center;padding:12px 18px;text-align:center;pointer-events:none;color:rgba(var(--color-foreground),.7);font-size:14px}.kalotyp-stage-image,.kalotyp-stage-overlay{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;display:block}.kalotyp-stage-overlay{z-index:1}.kalotyp-stage-body{position:absolute;z-index:2;cursor:move;touch-action:none}.kalotyp-handles{position:absolute;inset:0;z-index:3;pointer-events:none}.kalotyp-corner-anchor{position:absolute;width:0;height:0;pointer-events:none}.kalotyp-handle{position:absolute;margin:0;padding:0;border:none;background:transparent;pointer-events:auto;touch-action:none}.kalotyp-handle[data-shape=circle]{width:12px;height:12px;left:-6px;top:-6px;border-radius:50%;background:rgb(var(--color-foreground));border:2px solid rgb(var(--color-background));box-shadow:0 1px 3px #0000002e}.kalotyp-handle[data-shape=circle][data-direction=tl],.kalotyp-handle[data-shape=circle][data-direction=br]{cursor:nwse-resize}.kalotyp-handle[data-shape=circle][data-direction=tr],.kalotyp-handle[data-shape=circle][data-direction=bl]{cursor:nesw-resize}.kalotyp-handle[data-shape=edge][data-direction=t],.kalotyp-handle[data-shape=edge][data-direction=b]{height:6px;margin-top:-3px;cursor:ns-resize}.kalotyp-handle[data-shape=edge][data-direction=l],.kalotyp-handle[data-shape=edge][data-direction=r]{width:6px;margin-left:-3px;cursor:ew-resize}.kalotyp-handle:focus-visible{outline:2px solid var(--kalotyp-focus-ring);outline-offset:2px;box-shadow:0 0 0 4px var(--kalotyp-focus-halo)}.kalotyp-crop-panel{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%}.kalotyp-preset-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:center}.kalotyp-preset-button{display:inline-flex;align-items:center;height:var(--kalotyp-control-height);padding:0 12px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-preset-button:hover{background:var(--kalotyp-soft);border-color:var(--kalotyp-border-strong)}.kalotyp-preset-button:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-preset-button[aria-checked=true]{background:rgb(var(--color-foreground));border-color:rgb(var(--color-foreground));color:rgb(var(--color-background))}.kalotyp-crop-dims{display:flex;align-items:end;justify-content:center;flex-wrap:wrap;gap:8px;width:100%;margin-top:6px}.kalotyp-crop-dims-field{display:flex;flex-direction:column;gap:4px}.kalotyp-crop-dims-label{font-size:12px;color:var(--kalotyp-muted);font-weight:500}.kalotyp-crop-dims-input{width:80px;height:var(--kalotyp-control-height);padding:0 10px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-align:right;font-variant-numeric:tabular-nums}.kalotyp-crop-dims-input:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow);background:rgb(var(--color-background))}.kalotyp-util-nav{display:inline-flex;align-items:center;gap:2px;padding:4px;background:var(--kalotyp-track);border-radius:var(--kalotyp-radius-lg)}.kalotyp-util-nav-button{position:relative;display:inline-flex;align-items:center;justify-content:center;height:28px;padding:0 14px;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--kalotyp-muted);font:inherit;font-size:var(--kalotyp-text-size);font-weight:500;cursor:pointer;transition:color .2s ease,background .2s ease,border-color .2s ease,box-shadow .2s ease}.kalotyp-util-nav-button:hover{color:rgb(var(--color-foreground))}.kalotyp-util-nav-button:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-util-nav-button[aria-selected=true]{background:rgb(var(--color-background));border-color:var(--kalotyp-border);color:rgb(var(--color-foreground));font-weight:600;box-shadow:0 1px 2px #0000000a}.kalotyp-util-nav-button:disabled{opacity:.4;cursor:not-allowed}.kalotyp-preview-canvas{pointer-events:none}.kalotyp-flip-panel,.kalotyp-rotate-panel,.kalotyp-resize-panel{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:12px;width:100%;font-size:var(--kalotyp-text-size)}.kalotyp-rotate-row{display:flex;align-items:center;gap:8px}.kalotyp-resize-row{display:flex;align-items:end;gap:8px}.kalotyp-util-main{display:flex;align-items:center;justify-content:center;padding:18px 24px;min-height:88px;flex:0 0 auto;border-top:1px solid var(--kalotyp-border);background:rgb(var(--color-background))}.kalotyp-flip-panel{display:flex;gap:8px;justify-content:center}.kalotyp-toggle-button{display:inline-flex;align-items:center;height:var(--kalotyp-control-height);padding:0 14px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-toggle-button:hover{border-color:var(--kalotyp-border-strong)}.kalotyp-toggle-button:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-toggle-button[aria-pressed=true]{background:rgb(var(--color-foreground));border-color:rgb(var(--color-foreground));color:rgb(var(--color-background))}.kalotyp-rotate-slider-label{font-size:var(--kalotyp-text-size);color:var(--kalotyp-muted);min-width:72px}.kalotyp-rotate-slider{flex:1;min-width:220px;height:4px;cursor:ew-resize;-webkit-appearance:none;appearance:none;background:transparent}.kalotyp-rotate-slider::-webkit-slider-runnable-track{height:4px;background:var(--kalotyp-border);border-radius:999px}.kalotyp-rotate-slider::-moz-range-track{height:4px;background:var(--kalotyp-border);border-radius:999px}.kalotyp-rotate-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;margin-top:-6px;border-radius:50%;background:rgb(var(--color-foreground));border:2px solid rgb(var(--color-background));box-shadow:0 1px 3px #0003;cursor:ew-resize}.kalotyp-rotate-slider::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:rgb(var(--color-foreground));border:2px solid rgb(var(--color-background));box-shadow:0 1px 3px #0003;cursor:ew-resize}.kalotyp-rotate-slider:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 2px rgb(var(--color-background)),0 0 0 5px rgb(var(--color-foreground))}.kalotyp-rotate-slider:focus-visible::-moz-range-thumb{box-shadow:0 0 0 2px rgb(var(--color-background)),0 0 0 5px rgb(var(--color-foreground))}.kalotyp-rotate-input{width:72px;height:var(--kalotyp-control-height);padding:0 8px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-align:right;font-variant-numeric:tabular-nums}.kalotyp-rotate-input:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow);background:rgb(var(--color-background))}.kalotyp-rotate-input-group{display:inline-flex;align-items:center;gap:4px}.kalotyp-rotate-suffix{font-size:var(--kalotyp-text-size);color:var(--kalotyp-muted);font-variant-numeric:tabular-nums}.kalotyp-rotate-reset{height:var(--kalotyp-control-height);padding:0 12px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-rotate-reset:hover{border-color:var(--kalotyp-border-strong)}.kalotyp-rotate-reset:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-quarter-button{width:36px;height:var(--kalotyp-control-height);padding:0;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font-size:18px;line-height:1;cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-quarter-button:hover{background:var(--kalotyp-soft);border-color:var(--kalotyp-border-strong)}.kalotyp-quarter-button:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-resize-field{display:flex;flex-direction:column;gap:4px}.kalotyp-resize-field-label{font-size:12px;color:var(--kalotyp-muted);font-weight:500}.kalotyp-resize-input{width:92px;height:var(--kalotyp-control-height);padding:0 10px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-align:right;font-variant-numeric:tabular-nums}.kalotyp-resize-input:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow);background:rgb(var(--color-background))}.kalotyp-resize-lock{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:var(--kalotyp-muted);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-resize-lock:hover{border-color:var(--kalotyp-border-strong);color:rgb(var(--color-foreground))}.kalotyp-resize-lock:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-resize-lock[aria-pressed=true]{color:rgb(var(--color-foreground));border-color:var(--kalotyp-border-strong)}.kalotyp-resize-dims{align-items:end}.kalotyp-resize-dims .kalotyp-resize-lock{margin-bottom:2px}.kalotyp-resize-summary{font-size:var(--kalotyp-text-size);color:rgb(var(--color-foreground));font-variant-numeric:tabular-nums}.kalotyp-resize-helper{font-size:12px;color:var(--kalotyp-muted)}.kalotyp-annotate-stage{position:absolute;inset:0;overflow:hidden;background:transparent;user-select:none;touch-action:none}.kalotyp-annotate-image,.kalotyp-annotate-shapes,.kalotyp-annotate-live{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;display:block}.kalotyp-annotate-shapes{z-index:1}.kalotyp-annotate-live{z-index:2}.kalotyp-annotate-hit{position:absolute;inset:0;z-index:3;cursor:crosshair}.kalotyp-annotate-stage[data-tool=select] .kalotyp-annotate-hit{cursor:default}.kalotyp-annotate-stage[data-tool=text] .kalotyp-annotate-hit{cursor:text}.kalotyp-annotate-handles{position:absolute;inset:0;z-index:4;pointer-events:none}.kalotyp-annotate-handle{position:absolute;width:12px;height:12px;margin-left:-6px;margin-top:-6px;border:2px solid rgb(var(--color-background));border-radius:50%;background:rgb(var(--color-foreground));box-shadow:0 1px 2px #0006;cursor:pointer;pointer-events:auto;padding:0;font-size:0;touch-action:none}.kalotyp-annotate-handle:focus-visible{outline:2px solid var(--kalotyp-focus-ring);outline-offset:2px;box-shadow:0 0 0 4px var(--kalotyp-focus-halo)}.kalotyp-annotate-handle[data-direction=tl],.kalotyp-annotate-handle[data-direction=br]{cursor:nwse-resize}.kalotyp-annotate-handle[data-direction=tr],.kalotyp-annotate-handle[data-direction=bl]{cursor:nesw-resize}.kalotyp-annotate-handle[data-direction=t],.kalotyp-annotate-handle[data-direction=b]{cursor:ns-resize}.kalotyp-annotate-handle[data-direction=l],.kalotyp-annotate-handle[data-direction=r]{cursor:ew-resize}.kalotyp-annotate-text-overlay{position:absolute;inset:0;z-index:5;pointer-events:none}.kalotyp-annotate-text-editor{position:absolute;pointer-events:auto;min-width:60px;min-height:1em;padding:4px 6px;margin-left:-6px;margin-top:-4px;background:rgba(var(--color-background),.85);border:1px dashed rgba(var(--color-foreground),.55);border-radius:4px;outline:none;white-space:pre-wrap;word-break:break-word;line-height:1.2;caret-color:rgb(var(--color-foreground))}.kalotyp-annotate-panel{display:flex;flex-direction:column;gap:10px;align-items:center;width:100%}.kalotyp-annotate-toolbar{display:inline-flex;align-items:center;gap:4px;padding:4px;background:var(--kalotyp-track);border-radius:var(--kalotyp-radius-lg)}.kalotyp-annotate-tool{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--kalotyp-muted);font-size:16px;font-weight:500;cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-annotate-tool svg{display:block;width:18px;height:18px}.kalotyp-annotate-tool:hover{color:rgb(var(--color-foreground))}.kalotyp-annotate-tool:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-annotate-tool[aria-pressed=true]{background:rgb(var(--color-background));border-color:var(--kalotyp-border);color:rgb(var(--color-foreground));box-shadow:0 1px 2px #0000000a}.kalotyp-annotate-style-row{display:inline-flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:center}.kalotyp-annotate-swatches{display:inline-flex;align-items:center;gap:4px}.kalotyp-annotate-swatch{width:22px;height:22px;padding:0;border:2px solid var(--kalotyp-border);border-radius:50%;background:var(--kalotyp-swatch, currentColor);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-annotate-swatch:hover{transform:scale(1.08)}.kalotyp-annotate-swatch:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-annotate-swatch[aria-checked=true]{border-color:rgb(var(--color-foreground));box-shadow:0 0 0 1px rgb(var(--color-background)) inset}.kalotyp-annotate-hex{width:116px;height:28px;padding:0 8px 0 32px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));background-image:linear-gradient(var(--kalotyp-hex-swatch, #000),var(--kalotyp-hex-swatch, #000));background-repeat:no-repeat;background-position:6px center;background-size:18px 18px;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-transform:lowercase;font-variant-numeric:tabular-nums}.kalotyp-annotate-hex:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-annotate-stroke-label{font-size:var(--kalotyp-text-size);color:var(--kalotyp-muted)}.kalotyp-annotate-stroke{width:120px}.kalotyp-annotate-delete{display:inline-flex;align-items:center;gap:6px;height:var(--kalotyp-control-height);padding:0 12px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-annotate-delete svg{width:14px;height:14px}.kalotyp-annotate-delete:hover:not(:disabled){background:var(--kalotyp-soft);border-color:var(--kalotyp-border-strong)}.kalotyp-annotate-delete:disabled{opacity:.4;cursor:not-allowed}.kalotyp-annotate-insert{display:inline-flex;align-items:center;gap:6px;height:var(--kalotyp-control-height);padding:0 12px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-annotate-insert svg{width:14px;height:14px}.kalotyp-annotate-insert:hover:not(:disabled){background:var(--kalotyp-soft);border-color:var(--kalotyp-border-strong)}.kalotyp-annotate-insert:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-annotate-insert:disabled{opacity:.4;cursor:not-allowed}.kalotyp-annotate-coords{display:flex;align-items:end;justify-content:center;flex-wrap:wrap;gap:8px;width:100%;margin-top:6px}.kalotyp-annotate-coords[hidden]{display:none}.kalotyp-annotate-coords-field{display:flex;flex-direction:column;gap:4px}.kalotyp-annotate-coords-label{font-size:12px;color:var(--kalotyp-muted);font-weight:500}.kalotyp-annotate-coords-input{width:80px;height:var(--kalotyp-control-height);padding:0 10px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-align:right;font-variant-numeric:tabular-nums}.kalotyp-annotate-coords-input:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow);background:rgb(var(--color-background))}.kalotyp-finetune-panel{display:grid;grid-template-columns:1fr;gap:6px;width:100%;max-width:640px;margin:0 auto;font-size:var(--kalotyp-text-size)}.kalotyp-util-main:has(.kalotyp-finetune-panel){align-items:stretch;justify-content:center;padding-block:16px}.kalotyp-finetune-row{display:flex;align-items:center;gap:10px;height:32px}.kalotyp-finetune-label{flex:0 0 auto;width:84px;color:var(--kalotyp-muted);font-size:var(--kalotyp-text-size);font-weight:500;text-align:right}.kalotyp-finetune-slider{flex:1;min-width:160px;height:4px;cursor:ew-resize;-webkit-appearance:none;appearance:none;background:transparent}.kalotyp-finetune-slider::-webkit-slider-runnable-track{height:4px;background:var(--kalotyp-border);border-radius:999px}.kalotyp-finetune-slider::-moz-range-track{height:4px;background:var(--kalotyp-border);border-radius:999px}.kalotyp-finetune-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;margin-top:-6px;border-radius:50%;background:rgb(var(--color-foreground));border:2px solid rgb(var(--color-background));box-shadow:0 1px 3px #0003;cursor:ew-resize}.kalotyp-finetune-slider::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:rgb(var(--color-foreground));border:2px solid rgb(var(--color-background));box-shadow:0 1px 3px #0003;cursor:ew-resize}.kalotyp-finetune-slider:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 2px rgb(var(--color-background)),0 0 0 5px rgb(var(--color-foreground))}.kalotyp-finetune-slider:focus-visible::-moz-range-thumb{box-shadow:0 0 0 2px rgb(var(--color-background)),0 0 0 5px rgb(var(--color-foreground))}.kalotyp-finetune-input{flex:0 0 auto;width:60px;height:28px;padding:0 8px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-align:right;font-variant-numeric:tabular-nums}.kalotyp-finetune-input:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-finetune-row-reset{flex:0 0 auto;width:28px;height:28px;padding:0;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:var(--kalotyp-muted);font-size:14px;line-height:1;cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-finetune-row-reset:hover{border-color:var(--kalotyp-border-strong);color:rgb(var(--color-foreground))}.kalotyp-finetune-row-reset:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-finetune-reset-all{align-self:flex-end;margin-top:4px;height:28px;padding:0 12px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-finetune-reset-all:hover{border-color:var(--kalotyp-border-strong)}.kalotyp-finetune-reset-all:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-filter-panel{display:flex;flex-direction:column;gap:8px;width:100%;max-width:100%;margin:0 auto;font-size:var(--kalotyp-text-size)}.kalotyp-util-main:has(.kalotyp-filter-panel){align-items:stretch;justify-content:center;padding-block:12px}.kalotyp-filter-strip{display:flex;gap:12px;padding:4px 16px;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;-webkit-overflow-scrolling:touch;justify-content:flex-start}@media (min-width: 720px){.kalotyp-filter-strip{justify-content:center}}.kalotyp-filter-thumb{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:6px;padding:4px;border:0;background:transparent;cursor:pointer;font:inherit;color:rgb(var(--color-foreground));border-radius:var(--kalotyp-radius);transition:var(--kalotyp-transition)}.kalotyp-filter-thumb:hover{background:var(--kalotyp-soft)}.kalotyp-filter-thumb:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-filter-thumb-image{display:block;border:2px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);overflow:hidden;background:var(--kalotyp-track);line-height:0;transition:var(--kalotyp-transition)}.kalotyp-filter-thumb-canvas{display:block;width:100%;height:100%}.kalotyp-filter-thumb-label{font-size:12px;color:var(--kalotyp-muted);text-align:center;line-height:1.2;font-variant-numeric:tabular-nums;min-height:14px}.kalotyp-filter-thumb--active .kalotyp-filter-thumb-image{border-color:rgb(var(--color-foreground));box-shadow:0 0 0 3px rgba(var(--color-foreground),.18)}.kalotyp-filter-thumb--active .kalotyp-filter-thumb-label{color:rgb(var(--color-foreground));font-weight:600}.kalotyp-filter-thumb-check{position:absolute;top:4px;right:4px;width:18px;height:18px;display:none;align-items:center;justify-content:center;border-radius:50%;background:rgb(var(--color-foreground));color:rgb(var(--color-background));font-size:12px;line-height:1;font-weight:700;pointer-events:none}.kalotyp-filter-thumb-image{position:relative}.kalotyp-filter-thumb--active .kalotyp-filter-thumb-check{display:inline-flex}.kalotyp-redact-stage{position:absolute;inset:0;overflow:hidden;background:transparent;user-select:none;touch-action:none}.kalotyp-redact-image,.kalotyp-redact-regions,.kalotyp-redact-live{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;display:block}.kalotyp-redact-regions{z-index:1}.kalotyp-redact-live{z-index:2}.kalotyp-redact-hit{position:absolute;inset:0;z-index:3;cursor:crosshair}.kalotyp-redact-handles{position:absolute;inset:0;z-index:4;pointer-events:none}.kalotyp-redact-handle{position:absolute;width:12px;height:12px;margin-left:-6px;margin-top:-6px;border:2px solid rgb(var(--color-background));border-radius:50%;background:rgb(var(--color-foreground));box-shadow:0 1px 2px #0006;cursor:pointer;pointer-events:auto;padding:0;font-size:0;touch-action:none}.kalotyp-redact-handle:focus-visible{outline:2px solid var(--kalotyp-focus-ring);outline-offset:2px;box-shadow:0 0 0 4px var(--kalotyp-focus-halo)}.kalotyp-redact-handle[data-direction=tl],.kalotyp-redact-handle[data-direction=br]{cursor:nwse-resize}.kalotyp-redact-handle[data-direction=tr],.kalotyp-redact-handle[data-direction=bl]{cursor:nesw-resize}.kalotyp-redact-handle[data-direction=t],.kalotyp-redact-handle[data-direction=b]{cursor:ns-resize}.kalotyp-redact-handle[data-direction=l],.kalotyp-redact-handle[data-direction=r]{cursor:ew-resize}.kalotyp-redact-panel{display:flex;flex-direction:column;gap:10px;width:100%;max-width:720px;margin:0 auto;font-size:var(--kalotyp-text-size)}.kalotyp-redact-toolbar{display:flex;justify-content:center;gap:6px;flex-wrap:wrap}.kalotyp-redact-mode{height:var(--kalotyp-control-height);padding:0 14px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-redact-mode:hover{background:var(--kalotyp-soft)}.kalotyp-redact-mode:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-redact-mode--active{background:rgb(var(--color-foreground))!important;color:rgb(var(--color-background))!important;border-color:rgb(var(--color-foreground))!important;font-weight:600;box-shadow:0 0 0 1px rgb(var(--color-foreground)) inset}.kalotyp-redact-style-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:center}.kalotyp-redact-color-group,.kalotyp-redact-button-group{display:inline-flex;align-items:center;gap:8px;flex:0 0 auto}.kalotyp-redact-color-hint{flex:1 1 100%;text-align:center;font-size:12px;color:var(--kalotyp-muted);font-style:italic}.kalotyp-redact-color-hint[hidden]{display:none}.kalotyp-redact-color{width:36px;height:var(--kalotyp-control-height);padding:0;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;cursor:pointer}.kalotyp-redact-color:disabled{opacity:.4;cursor:not-allowed}.kalotyp-redact-hex{width:100px;height:var(--kalotyp-control-height);padding:0 10px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);font-variant-numeric:tabular-nums;text-align:left}.kalotyp-redact-hex:disabled{opacity:.4;cursor:not-allowed}.kalotyp-redact-hex:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-redact-insert,.kalotyp-redact-delete{display:inline-flex;align-items:center;gap:6px;height:var(--kalotyp-control-height);padding:0 14px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-redact-insert:hover,.kalotyp-redact-delete:hover{background:var(--kalotyp-soft)}.kalotyp-redact-insert:focus-visible,.kalotyp-redact-delete:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-redact-delete:disabled{opacity:.5;cursor:not-allowed}.kalotyp-redact-coords{display:flex;align-items:end;justify-content:center;flex-wrap:wrap;gap:8px;width:100%;margin-top:6px}.kalotyp-redact-coords[hidden]{display:none}.kalotyp-redact-coords-field{display:flex;flex-direction:column;gap:4px}.kalotyp-redact-coords-label{font-size:12px;color:var(--kalotyp-muted);font-weight:500}.kalotyp-redact-coords-input{width:80px;height:var(--kalotyp-control-height);padding:0 10px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);text-align:right;font-variant-numeric:tabular-nums}.kalotyp-redact-coords-input:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow);background:rgb(var(--color-background))}.kalotyp-frame-panel{display:flex;flex-direction:column;gap:8px;width:100%;max-width:100%;margin:0 auto;font-size:var(--kalotyp-text-size)}.kalotyp-util-main:has(.kalotyp-frame-panel){align-items:stretch;justify-content:center;padding-block:12px}.kalotyp-frame-strip-wrap{display:block}.kalotyp-frame-strip{display:flex;gap:12px;padding:4px 16px;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;-webkit-overflow-scrolling:touch;justify-content:flex-start}@media (min-width: 720px){.kalotyp-frame-strip{justify-content:center}}.kalotyp-frame-thumb{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:6px;padding:4px;border:0;background:transparent;cursor:pointer;font:inherit;color:rgb(var(--color-foreground));border-radius:var(--kalotyp-radius);transition:var(--kalotyp-transition)}.kalotyp-frame-thumb:hover{background:var(--kalotyp-soft)}.kalotyp-frame-thumb:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-frame-thumb-image{display:block;position:relative;border:2px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);overflow:hidden;background:var(--kalotyp-track);line-height:0;transition:var(--kalotyp-transition);width:80px;height:60px;display:flex;align-items:center;justify-content:center}.kalotyp-frame-thumb-canvas{display:block;max-width:100%;max-height:100%}.kalotyp-frame-thumb-label{font-size:12px;color:var(--kalotyp-muted);text-align:center;line-height:1.2;font-variant-numeric:tabular-nums;min-height:14px}.kalotyp-frame-thumb--active .kalotyp-frame-thumb-image{border-color:rgb(var(--color-foreground));box-shadow:0 0 0 3px rgba(var(--color-foreground),.18)}.kalotyp-frame-thumb--active .kalotyp-frame-thumb-label{color:rgb(var(--color-foreground));font-weight:600}.kalotyp-frame-thumb-check{position:absolute;top:4px;right:4px;width:18px;height:18px;display:none;align-items:center;justify-content:center;border-radius:50%;background:rgb(var(--color-foreground));color:rgb(var(--color-background));font-size:12px;line-height:1;font-weight:700;pointer-events:none}.kalotyp-frame-thumb--active .kalotyp-frame-thumb-check{display:inline-flex}.kalotyp-frame-color-row{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}.kalotyp-frame-color-label{font-size:12px;color:var(--kalotyp-muted);font-weight:500}.kalotyp-frame-color-hint{flex:1 1 100%;text-align:center;font-size:12px;color:var(--kalotyp-muted);font-style:italic}.kalotyp-frame-color-hint[hidden]{display:none}.kalotyp-frame-color{width:36px;height:var(--kalotyp-control-height);padding:0;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;cursor:pointer}.kalotyp-frame-color:disabled{opacity:.4;cursor:not-allowed}.kalotyp-frame-hex{width:100px;height:var(--kalotyp-control-height);padding:0 10px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);font-variant-numeric:tabular-nums;text-align:left}.kalotyp-frame-hex:disabled{opacity:.4;cursor:not-allowed}.kalotyp-frame-hex:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-frame-preview-container{position:absolute;inset:0}.kalotyp-frame-preview-canvas{position:absolute}.kalotyp-nested-overlay--popover .kalotyp-nested-surface.kalotyp-output-popover{min-width:280px;max-width:320px}.kalotyp-output-popover-body{display:flex;flex-direction:column;gap:10px}.kalotyp-output-row{display:grid;grid-template-columns:64px 1fr auto;align-items:center;gap:10px}.kalotyp-output-row-label{font-size:12px;color:var(--kalotyp-muted);font-weight:500}.kalotyp-output-format{height:var(--kalotyp-control-height);padding:0 8px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:rgb(var(--color-background));color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size)}.kalotyp-output-format:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-output-quality{width:100%;accent-color:rgb(var(--color-foreground))}.kalotyp-output-quality:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow);border-radius:var(--kalotyp-radius)}.kalotyp-output-quality-readout{font-size:var(--kalotyp-text-size);color:var(--kalotyp-muted);font-variant-numeric:tabular-nums;min-width:28px;text-align:right}.kalotyp-output-hint{margin:0 0 4px 74px;font-size:12px;color:var(--kalotyp-muted)}.kalotyp-output-summary{margin:4px 0 0;font-size:var(--kalotyp-text-size);color:rgb(var(--color-foreground));font-weight:500}.kalotyp-output-metadata-row{display:flex;align-items:center;gap:8px;margin:6px 0 0;font-size:var(--kalotyp-text-size);cursor:pointer}.kalotyp-output-metadata-checkbox{accent-color:rgb(var(--color-foreground));width:16px;height:16px;margin:0}.kalotyp-output-metadata-text{line-height:1.3}.kalotyp-output-metadata-hint{margin:2px 0 0;padding-left:24px;font-size:11px;color:var(--kalotyp-muted);font-style:italic;line-height:1.4;min-height:16px}.kalotyp-output-footer{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--kalotyp-border)}.kalotyp-output-done{height:var(--kalotyp-control-height);padding:0 14px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:rgb(var(--color-foreground));font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-output-done:hover{background:var(--kalotyp-soft)}.kalotyp-output-done:focus-visible{outline:none;border-color:rgb(var(--color-foreground));box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-output-save{height:var(--kalotyp-control-height);padding:0 16px;border:1px solid rgb(var(--color-foreground));border-radius:var(--kalotyp-radius);background:rgb(var(--color-foreground));color:rgb(var(--color-background));font:inherit;font-size:var(--kalotyp-text-size);font-weight:600;cursor:pointer;transition:var(--kalotyp-transition)}.kalotyp-output-save:hover{background:rgba(var(--color-foreground),.88);border-color:rgba(var(--color-foreground),.88)}.kalotyp-output-save:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-output-save:disabled{opacity:.4;cursor:not-allowed}.kalotyp-nested-overlay--modal .kalotyp-nested-surface.kalotyp-preferences-modal{min-width:360px;max-width:460px}.kalotyp-preferences-body{display:flex;flex-direction:column;gap:18px}.kalotyp-preferences-section{display:flex;flex-direction:column;gap:10px}.kalotyp-preferences-section h4{margin:0;font-size:13px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--kalotyp-muted)}.kalotyp-preferences-toggle{display:flex;align-items:center;gap:10px;font-size:var(--kalotyp-text-size);cursor:pointer}.kalotyp-preferences-toggle input[type=checkbox]{accent-color:rgb(var(--color-foreground));width:16px;height:16px}.kalotyp-preferences-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:4px;padding-top:12px;border-top:1px solid var(--kalotyp-border)}.kalotyp-preferences-reset{height:var(--kalotyp-control-height);padding:0 14px;border:1px solid var(--kalotyp-border);border-radius:var(--kalotyp-radius);background:transparent;color:var(--kalotyp-muted);font:inherit;font-size:var(--kalotyp-text-size);cursor:pointer}.kalotyp-preferences-reset:hover{background:var(--kalotyp-soft);color:rgb(var(--color-foreground))}.kalotyp-preferences-done{height:var(--kalotyp-control-height);padding:0 16px;border:1px solid rgb(var(--color-foreground));border-radius:var(--kalotyp-radius);background:rgb(var(--color-foreground));color:rgb(var(--color-background));font:inherit;font-size:var(--kalotyp-text-size);font-weight:600;cursor:pointer}.kalotyp-preferences-done:hover{background:rgba(var(--color-foreground),.88)}.kalotyp-preferences-done:focus-visible,.kalotyp-preferences-reset:focus-visible{outline:none;box-shadow:var(--kalotyp-focus-shadow)}.kalotyp-nested-overlay--modal .kalotyp-nested-surface.kalotyp-cheatsheet-modal{min-width:380px;max-width:520px;max-height:80vh;overflow-y:auto}.kalotyp-cheatsheet-body{display:flex;flex-direction:column;gap:18px}.kalotyp-cheatsheet-section{display:flex;flex-direction:column;gap:8px}.kalotyp-cheatsheet-heading{margin:0;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--kalotyp-muted)}.kalotyp-cheatsheet-list{margin:0;display:grid;grid-template-columns:minmax(140px,auto) 1fr;column-gap:16px;row-gap:6px;align-items:baseline}.kalotyp-cheatsheet-keys{margin:0;display:flex;flex-wrap:wrap;align-items:center;gap:4px}.kalotyp-cheatsheet-kbd{display:inline-block;min-width:22px;padding:2px 8px;border:1px solid var(--kalotyp-border);border-bottom-width:2px;border-radius:4px;background:var(--kalotyp-soft);color:rgb(var(--color-foreground));font:inherit;font-size:11px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-weight:500;line-height:1.4;text-align:center}.kalotyp-cheatsheet-plus{font-size:11px;color:var(--kalotyp-muted)}.kalotyp-cheatsheet-description{margin:0;font-size:var(--kalotyp-text-size);color:rgb(var(--color-foreground));line-height:1.4}@media (pointer: coarse){.kalotyp-button-close{position:absolute}.kalotyp-button-close:before{content:"";position:absolute;inset:-6px}.kalotyp-history-button{position:relative}.kalotyp-history-button:before{content:"";position:absolute;inset:-6px}.kalotyp-util-nav-button{position:relative}.kalotyp-util-nav-button:before{content:"";position:absolute;inset:-8px -2px}.kalotyp-handle[data-shape=circle]:before{content:"";position:absolute;inset:-12px;z-index:-1}.kalotyp-handle[data-shape=edge][data-direction=t]:before,.kalotyp-handle[data-shape=edge][data-direction=b]:before{content:"";position:absolute;inset:-19px 0;z-index:-1}.kalotyp-handle[data-shape=edge][data-direction=l]:before,.kalotyp-handle[data-shape=edge][data-direction=r]:before{content:"";position:absolute;inset:0 -19px;z-index:-1}.kalotyp-annotate-handle:before{content:"";position:absolute;inset:-16px}.kalotyp-annotate-tool{position:relative}.kalotyp-annotate-tool:before{content:"";position:absolute;inset:-6px}.kalotyp-annotate-swatch{width:32px;height:32px;position:relative}.kalotyp-annotate-swatch:before{content:"";position:absolute;inset:-6px;border-radius:50%}.kalotyp-annotate-color{position:relative;width:36px;height:36px}.kalotyp-annotate-color:before{content:"";position:absolute;inset:-4px}.kalotyp-preset-button{height:40px;position:relative}.kalotyp-preset-button:before{content:"";position:absolute;inset:-2px}.kalotyp-toggle-button,.kalotyp-rotate-input,.kalotyp-rotate-reset,.kalotyp-quarter-button,.kalotyp-resize-input,.kalotyp-resize-lock{height:40px;min-height:40px}.kalotyp-toggle-button:before,.kalotyp-rotate-reset:before,.kalotyp-quarter-button:before,.kalotyp-resize-lock:before{content:"";position:absolute;inset:-2px}.kalotyp-toggle-button,.kalotyp-rotate-reset,.kalotyp-quarter-button,.kalotyp-resize-lock,.kalotyp-finetune-row-reset{position:relative}.kalotyp-finetune-row-reset:before{content:"";position:absolute;inset:-8px}.kalotyp-finetune-reset-all{height:36px;position:relative}.kalotyp-finetune-reset-all:before{content:"";position:absolute;inset:-4px}.kalotyp-rotate-slider,.kalotyp-finetune-slider,.kalotyp-annotate-stroke{height:44px}.kalotyp-rotate-slider::-webkit-slider-thumb,.kalotyp-finetune-slider::-webkit-slider-thumb,.kalotyp-annotate-stroke::-webkit-slider-thumb{width:24px;height:24px;margin-top:-10px}.kalotyp-rotate-slider::-moz-range-thumb,.kalotyp-finetune-slider::-moz-range-thumb,.kalotyp-annotate-stroke::-moz-range-thumb{width:24px;height:24px}.kalotyp-button-export{height:44px;padding:0 22px}}@media (max-width: 768px){.kalotyp-main{padding:8px 8px 0!important;gap:8px}.kalotyp-nav-tools{padding:8px 8px 8px 12px;gap:8px;min-height:56px;flex-wrap:nowrap}.kalotyp-util-nav{flex:1 1 auto;min-width:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;mask-image:linear-gradient(to right,transparent 0,black 36px,black calc(100% - 36px),transparent 100%);-webkit-mask-image:linear-gradient(to right,transparent 0,black 36px,black calc(100% - 36px),transparent 100%)}.kalotyp-util-nav::-webkit-scrollbar{display:none}.kalotyp-util-nav-button{flex:0 0 auto;scroll-snap-align:start}.kalotyp-history-controls,.kalotyp-button-close{position:static!important;flex:0 0 auto}.kalotyp-nav-tools{padding-right:168px}.kalotyp-button-close{position:absolute!important;top:12px!important;right:8px!important}.kalotyp-button-prefs{position:absolute!important;top:12px!important;right:48px!important}.kalotyp-history-controls{position:absolute!important;top:12px!important;right:88px!important}.kalotyp-util-main{padding:12px;min-height:72px}.kalotyp-util-footer{padding:10px 12px}.pintura-editor .kalotyp-root>.kalotyp-nav-tools{padding:8px 100px 8px 12px!important}.pintura-editor .kalotyp-root[data-env~=landscape] .kalotyp-util-main,.pintura-editor .kalotyp-root[data-env~=landscape] .kalotyp-util-footer{padding-left:12px!important;padding-right:12px!important}.kalotyp-rotate-slider{min-width:140px}.kalotyp-rotate-slider-label{min-width:auto}.kalotyp-resize-panel{align-items:stretch;gap:8px}.kalotyp-resize-row{flex-wrap:wrap;justify-content:center}.kalotyp-finetune-panel{max-width:100%}.kalotyp-finetune-label{width:56px;text-align:right;font-size:12px}.kalotyp-finetune-slider{min-width:80px}.kalotyp-finetune-input{width:56px}.kalotyp-annotate-toolbar{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;max-width:100%}.kalotyp-annotate-toolbar::-webkit-scrollbar{display:none}.kalotyp-annotate-tool{flex:0 0 auto}.kalotyp-annotate-style-row{gap:8px;flex-wrap:wrap}.kalotyp-annotate-stroke{min-width:120px}.kalotyp-filter-strip{padding:4px 8px;gap:8px}}@media (max-width: 360px){.kalotyp-util-nav{mask-image:none;-webkit-mask-image:none}.pintura-editor .kalotyp-root>.kalotyp-nav-tools,.kalotyp-nav-tools{padding-right:92px!important}}@media (max-height: 500px) and (orientation: landscape){.kalotyp-nav-tools{min-height:44px;padding-top:6px;padding-bottom:6px}.kalotyp-main{padding:6px 12px 0!important;gap:6px}.kalotyp-util-main{min-height:56px!important;padding:6px 12px}.kalotyp-util-footer{padding:6px 12px}.kalotyp-button-export{height:40px;padding:0 16px}.kalotyp-button-close,.kalotyp-button-prefs,.kalotyp-history-controls{top:6px!important}}
@@ -0,0 +1,103 @@
1
+ (function(it,rt){typeof exports=="object"&&typeof module<"u"?rt(exports):typeof define=="function"&&define.amd?define(["exports"],rt):(it=typeof globalThis<"u"?globalThis:it||self,rt(it.pintura={}))})(this,function(it){"use strict";class rt{listeners=new Map;on(e,n){let o=this.listeners.get(e);return o||(o=new Set,this.listeners.set(e,o)),o.add(n),()=>{o?.delete(n)}}off(e,n){this.listeners.get(e)?.delete(n)}emit(e,n){const o=this.listeners.get(e);if(o)for(const i of[...o])try{i(n)}catch(r){queueMicrotask(()=>{throw r})}}clear(){this.listeners.clear()}}async function oo(t){if(typeof createImageBitmap=="function"){const e=await io(t);if(e)try{const n=await createImageBitmap(e,{imageOrientation:"from-image"});return{element:n,width:n.width,height:n.height}}catch{}}return ro(t)}async function io(t){if(t instanceof Blob)return t;if(typeof fetch!="function")return null;try{const e=await fetch(t,{credentials:"omit"});return e.ok?await e.blob():null}catch{return null}}async function ro(t){const e=typeof t=="string"?t:URL.createObjectURL(t),n=typeof t!="string";try{const o=await new Promise((i,r)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>i(a),a.onerror=()=>r(new Error(`Failed to load image: ${e}`)),a.src=e});return{element:o,width:o.naturalWidth,height:o.naturalHeight}}finally{n&&URL.revokeObjectURL(e)}}const Ct=Object.freeze({zoom:1,panX:0,panY:0});function j(t,e,n=Ct){const o=Math.max(0,t.width-t.padding*2),i=Math.max(0,t.height-t.padding*2);if(e.width<=0||e.height<=0||o<=0||i<=0)return{displayRect:{x:t.padding,y:t.padding,width:0,height:0},scale:0};const r=Math.min(o/e.width,i/e.height),a=Math.max(0,n.zoom||0),s=r*a,c=e.width*s,l=e.height*s,u=t.padding+(o-c)/2,d=t.padding+(i-l)/2,h=u+n.panX,f=d+n.panY,m=ye(h,u,c,o,t.padding),g=ye(f,d,l,i,t.padding);return{displayRect:{x:m,y:g,width:c,height:l},scale:s}}function ye(t,e,n,o,i){if(n<=o)return e;const r=i,a=i+o,s=r+1-n,c=a-1;return t<s?s:t>c?c:t}function Wt(t,e){return e.scale===0?{x:0,y:0}:{x:(t.x-e.displayRect.x)/e.scale,y:(t.y-e.displayRect.y)/e.scale}}function be(t,e){return{x:e.displayRect.x+t.x*e.scale,y:e.displayRect.y+t.y*e.scale,width:t.width*e.scale,height:t.height*e.scale}}const we=8,Ce=.25;class ao{current;isPinching;listeners;constructor(e=Ct){this.current=ve(e),this.isPinching=!1,this.listeners=new Set}getTransform(){return this.current}getSnapshot(){return{transform:this.current,pinching:this.isPinching}}setTransform(e){const n=ve(e);ke(this.current,n)||(this.current=n,this.emit())}zoomAt(e,n,o){if(!Number.isFinite(e)||e<=0)return this.current;const i=this.current.zoom,r=i*e,a=xe(r,Ce,we);if(a===i)return this.current;const s=a/i,c=n.x-o.x,l=n.y-o.y,u=s*this.current.panX+(1-s)*c,d=s*this.current.panY+(1-s)*l;return this.current={zoom:a,panX:u,panY:d},this.emit(),this.current}panBy(e,n){e===0&&n===0||(this.current={zoom:this.current.zoom,panX:this.current.panX+e,panY:this.current.panY+n},this.emit())}resetToFit(){ke(this.current,Ct)||(this.current=Ct,this.emit())}resetPan(){this.current.panX===0&&this.current.panY===0||(this.current={zoom:this.current.zoom,panX:0,panY:0},this.emit())}getPinching(){return this.isPinching}setPinching(e){this.isPinching!==e&&(this.isPinching=e,this.emit())}computeViewport(e,n){return j(e,n,this.current)}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}clear(){this.listeners.clear()}emit(){const e=this.getSnapshot();for(const n of this.listeners)n(e)}}function xe(t,e,n){return t<e?e:t>n?n:t}function ve(t){const e=xe(Number.isFinite(t.zoom)?t.zoom:1,Ce,we),n=Number.isFinite(t.panX)?t.panX:0,o=Number.isFinite(t.panY)?t.panY:0;return{zoom:e,panX:n,panY:o}}function ke(t,e){return t.zoom===e.zoom&&t.panX===e.panX&&t.panY===e.panY}function Q(t,e){if(so())return{kind:"offscreen",canvas:new OffscreenCanvas(t,e)};const n=document.createElement("canvas");return n.width=t,n.height=e,{kind:"html",canvas:n}}function et(t){if(t.kind==="offscreen"){const n=t.canvas.getContext("2d");if(!n)throw new Error("2D canvas context is not available");return n}const e=t.canvas.getContext("2d");if(!e)throw new Error("2D canvas context is not available");return e}async function Se(t,e,n){return t.kind==="offscreen"?t.canvas.convertToBlob({type:e,quality:n}):new Promise((o,i)=>{t.canvas.toBlob(r=>{r?o(r):i(new Error("toBlob produced null"))},e,n)})}function so(){return typeof OffscreenCanvas>"u"?!1:typeof OffscreenCanvas.prototype.convertToBlob=="function"}const Ee=new Map;function dt(t){const e=Ee.get(t);if(e)return e;const n=(async()=>{try{const o=Q(1,1),i=await Se(o,t,.5);return i.type===t&&i.size>0}catch{return!1}})();return Ee.set(t,n),n}function co(t,e,n,o){const i={x:t.x+e,y:t.y+n,width:t.width,height:t.height};return xt(i,o)}function xt(t,e){let{x:n,y:o,width:i,height:r}=t;return i>e.width&&(i=e.width),r>e.height&&(r=e.height),n<e.x&&(n=e.x),o<e.y&&(o=e.y),n+i>e.x+e.width&&(n=e.x+e.width-i),o+r>e.y+e.height&&(o=e.y+e.height-r),{x:n,y:o,width:i,height:r}}function lo(t){return{x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)}}function Ae(t){let e=t;const n=new Set;function o(i){for(const r of[...n])try{r(e,i)}catch(a){queueMicrotask(()=>{throw a})}}return{get(){return e},set(i){const r=e;e={...e,...i},o(r)},update(i){const r=e;e={...e,...i(e)},o(r)},subscribe(i){return n.add(i),()=>n.delete(i)}}}const Me=50;class uo{shadow;undoStack=[];redoStack=[];constructor(e){this.shadow=vt(e)}commit(e){ho(e,this.shadow)||(this.undoStack.push(this.shadow),this.undoStack.length>Me&&this.undoStack.shift(),this.shadow=vt(e),this.redoStack.length=0)}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}undo(e){const n=this.undoStack.pop();return n?(this.redoStack.push(vt(e)),this.shadow=n,{snapshot:n,changed:Ie(e,n)}):null}redo(e){const n=this.redoStack.pop();return n?(this.undoStack.push(vt(e)),this.undoStack.length>Me&&this.undoStack.shift(),this.shadow=n,{snapshot:n,changed:Ie(e,n)}):null}size(){return{undo:this.undoStack.length,redo:this.redoStack.length}}}function ho(t,e){if(t.size!==e.size)return!1;for(const[n,o]of t)if(!e.has(n)||kt(o)!==kt(e.get(n)))return!1;return!0}function Ie(t,e){const n=new Set;for(const[o,i]of e)kt(i)!==kt(t.get(o))&&n.add(o);for(const o of t.keys())e.has(o)||n.add(o);return n}function vt(t){const e=new Map;for(const[n,o]of t)e.set(n,structuredClone(o));return e}function kt(t){return JSON.stringify(t,(e,n)=>{if(n&&typeof n=="object"&&!Array.isArray(n)){const o={};for(const i of Object.keys(n).sort())o[i]=n[i];return o}return n})}function qt(t,e){if(e<=0||t.width<=0||t.height<=0)return{x:t.x,y:t.y,width:0,height:0};const n=t.width/t.height;let o,i;return e>=n?(o=t.width,i=o/e):(i=t.height,o=i*e),{x:t.x+(t.width-o)/2,y:t.y+(t.height-i)/2,width:o,height:i}}function po(t,e,n,o){if(e<=0)return t;if(t.width<=0||t.height<=0)return qt(o,e);const i=t.width/t.height;let r,a;i>e?(a=t.height,r=a*e):(r=t.width,a=r/e);const s=Re(t,r,a,n),c=xt(s,o),l=c.height===0?0:c.width/c.height;return Math.abs(l-e)<=mo?c:fo(c,e,n)}const mo=1e-6;function Re(t,e,n,o){switch(o){case"tl":return{x:t.x,y:t.y,width:e,height:n};case"tr":return{x:t.x+t.width-e,y:t.y,width:e,height:n};case"bl":return{x:t.x,y:t.y+t.height-n,width:e,height:n};case"br":return{x:t.x+t.width-e,y:t.y+t.height-n,width:e,height:n};case"center":return{x:t.x+(t.width-e)/2,y:t.y+(t.height-n)/2,width:e,height:n}}}function fo(t,e,n){const o=qt(t,e);return Re(t,o.width,o.height,n)}function go(t,e,n,o){const i=o.minSize??1,r=t.x,a=t.y,s=t.x+t.width,c=t.y+t.height;let l=r,u=a,d=s,h=c;(e==="tl"||e==="l"||e==="bl")&&(l=n.x),(e==="tr"||e==="r"||e==="br")&&(d=n.x),(e==="tl"||e==="t"||e==="tr")&&(u=n.y),(e==="bl"||e==="b"||e==="br")&&(h=n.y),(e==="l"||e==="r")&&(u=a,h=c),(e==="t"||e==="b")&&(l=r,d=s);let f=Math.min(l,d),m=Math.min(u,h),g=Math.abs(d-l),p=Math.abs(h-u);g<i&&(g=i,e==="tl"||e==="l"||e==="bl"?f=s-i:(e==="tr"||e==="r"||e==="br")&&(f=r)),p<i&&(p=i,e==="tl"||e==="t"||e==="tr"?m=c-i:(e==="bl"||e==="b"||e==="br")&&(m=a));let w={x:f,y:m,width:g,height:p};return w=xt(w,o.bounds),o.aspectRatio!==void 0&&o.aspectRatio>0&&(w=po(w,o.aspectRatio,yo(e),o.bounds)),w}function yo(t){switch(t){case"tl":return"br";case"tr":return"bl";case"bl":return"tr";case"br":return"tl";case"t":return"bl";case"b":return"tl";case"l":return"tr";case"r":return"tl"}}function bo(t,e){const[n]=t;return n===void 0||e===void 0?!0:e==="landscape"?n>=1:e==="portrait"?n<1:!0}function wo(t,e){return t.filter(n=>bo(n,e))}function Co(t){return{rect:{x:0,y:0,width:t.imageSize.width,height:t.imageSize.height},aspectRatio:void 0,activePresetIndex:vo(t.presets),presets:t.presets,imageSize:t.imageSize}}function xo(t,e){const n=t.presets[e];if(!n)return t;const[o]=n;if(o===void 0)return{...t,aspectRatio:void 0,activePresetIndex:e};const i={x:0,y:0,width:t.imageSize.width,height:t.imageSize.height},r=qt(i,o);return{...t,rect:r,aspectRatio:o,activePresetIndex:e}}function vo(t){return t.findIndex(([e])=>e===void 0)}function ko(t,e){const n=lo(e.rect),o=St(n.x,0,t.width),i=St(n.y,0,t.height),r=St(n.width,1,t.width-o),a=St(n.height,1,t.height-i),s=Q(r,a);if(s.kind==="offscreen"){const l=s.canvas.getContext("2d");if(!l)throw new Error("2D canvas context is not available");return l.drawImage(t.bitmap,o,i,r,a,0,0,r,a),{bitmap:s.canvas,width:r,height:a,mimeType:t.mimeType}}const c=s.canvas.getContext("2d");if(!c)throw new Error("2D canvas context is not available");return c.drawImage(t.bitmap,o,i,r,a,0,0,r,a),{bitmap:s.canvas,width:r,height:a,mimeType:t.mimeType}}function St(t,e,n){return Math.max(e,Math.min(n,t))}const Ne={mimeChoice:"auto",quality:.85};function Le(t){return Number.isFinite(t)?t<0?0:t>1?1:t:Ne.quality}function So(t,e){return t.mimeChoice===e?t:{...t,mimeChoice:e}}function Eo(t,e){const n=Le(e);return t.quality===n?t:{...t,quality:n}}function Ao(t,e){return t.stripMetadata===e?t:{...t,stripMetadata:e}}const Te=[255,216],Fe=[255,225],Pe=[69,120,105,102,0,0];async function Mo(t){if(t.output.type&&t.output.type!=="image/jpeg")return t.output;const e=await $e(t.source);if(!De(e,Te))return t.output;const n=Io(e);if(!n)return t.output;const o=await $e(t.output);if(!De(o,Te))return t.output;const i=new Uint8Array(o.length+n.length);return i.set(o.subarray(0,2),0),i.set(n,2),i.set(o.subarray(2),2+n.length),new Blob([i],{type:"image/jpeg"})}async function $e(t){return typeof t.arrayBuffer=="function"?new Uint8Array(await t.arrayBuffer()):new Promise((e,n)=>{const o=new FileReader;o.onload=()=>{const i=o.result;i instanceof ArrayBuffer?e(new Uint8Array(i)):n(new Error("FileReader returned a non-ArrayBuffer result"))},o.onerror=()=>n(o.error??new Error("FileReader failed")),o.readAsArrayBuffer(t)})}function De(t,e){if(t.length<e.length)return!1;for(let n=0;n<e.length;n++)if(t[n]!==e[n])return!1;return!0}function Io(t){let e=2;for(;e+4<=t.length;){if(t[e]!==255)return;const n=t[e+1];if(n===void 0||n===218||n===217)return;const o=t[e+2]!==void 0&&t[e+3]!==void 0?t[e+2]*256+t[e+3]:0;if(o<2)return;const i=e+2+o;if(i>t.length)return;if(t[e]===Fe[0]&&t[e+1]===Fe[1]&&Ro(t,e+4))return t.slice(e,i);e=i}}function Ro(t,e){for(let n=0;n<Pe.length;n++)if(t[e+n]!==Pe[n])return!1;return!0}const He="image/png",No=new Set(["image/png","image/webp","image/avif"]);async function Lo(t,e){return t.mimeChoice!=="auto"?await dt(t.mimeChoice)?t.mimeChoice:await dt("image/webp")?"image/webp":He:await dt("image/webp")?"image/webp":!No.has(e.mimeType)&&await dt("image/jpeg")?"image/jpeg":He}function To(t,e){const n=Po(e);if(!t)return`kalotyp-image.${n}`;const o=$o(t);if(!o)return`kalotyp-image.${n}`;const i=Ho(o);return i?`${i}.${n}`:`kalotyp-image.${n}`}async function Fo(t,e={}){const n=e.output??Ne,o=await Lo(n,t),i=Le(n.quality),r=To(e.sourceName,o),a=Q(t.width,t.height);if(a.kind==="offscreen"){const u=a.canvas.getContext("2d");if(!u)throw new Error("2D canvas context is not available");u.drawImage(t.bitmap,0,0)}else{const u=a.canvas.getContext("2d");if(!u)throw new Error("2D canvas context is not available");u.drawImage(t.bitmap,0,0)}const s=await Se(a,o,i),l=e.output?.stripMetadata===!1&&o==="image/jpeg"&&t.mimeType==="image/jpeg"&&e.sourceBlob!==void 0?await Mo({source:e.sourceBlob,output:s}):s;return new File([l],r,{type:o})}function Po(t){if(t==="image/jpeg")return"jpg";if(t==="image/png")return"png";if(t==="image/webp")return"webp";if(t==="image/avif")return"avif";const e=t.split("/")[1];return e&&e.length>0?e:"bin"}function $o(t){const n=Do(t).split(/[/\\]/);return n[n.length-1]}function Do(t){const e=t.indexOf("?");return e===-1?t:t.slice(0,e)}function Ho(t){const e=t.lastIndexOf(".");return e<=0?t:t.slice(0,e)}async function Oo(t,e){let n=e;for(const o of t)n=await o.plugin.bake(o.state,n);return n}function zo(){return{horizontal:!1,vertical:!1}}function Oe(t,e){return e==="horizontal"?{...t,horizontal:!t.horizontal}:{...t,vertical:!t.vertical}}function ze(t){return!t.horizontal&&!t.vertical}async function Bo(t,e){if(ze(t))return e;const{width:n,height:o}=e,i=Q(n,o),r=et(i),a=t.horizontal?-1:1,s=t.vertical?-1:1,c=t.horizontal?n:0,l=t.vertical?o:0;return r.setTransform(a,0,0,s,c,l),r.drawImage(e.bitmap,0,0),{bitmap:i.canvas,width:n,height:o,mimeType:e.mimeType}}const Ut=-45,Xt=45,Be=.1;function _o(){return{quarterTurns:0,freeAngle:0}}function Wo(t){return{...t,quarterTurns:(t.quarterTurns+1)%4}}function qo(t){return{...t,quarterTurns:(t.quarterTurns+3)%4}}function _e(t,e){const n=Uo(e,Ut,Xt),o=Math.round(n*10)/10;return{...t,freeAngle:o}}function We(t){return t.quarterTurns===0&&Math.abs(t.freeAngle)<1e-6}function Yt(t){return t.quarterTurns*90+t.freeAngle}function Uo(t,e,n){return Math.max(e,Math.min(n,t))}function qe(t,e){const n=t.width,o=t.height;if(n<=0||o<=0)return{width:0,height:0};const i=Math.abs(Math.cos(e)),r=Math.abs(Math.sin(e)),a=n*i+o*r,s=n*r+o*i,c=a>Ue?n*n/a:Number.POSITIVE_INFINITY,l=s>Ue?n*o/s:Number.POSITIVE_INFINITY,u=Math.min(c,l),d=u*o/n;return{width:u,height:d}}const Ue=1e-9;async function Xo(t,e){if(We(t))return e;const n=Yt(t),o=n*Math.PI/180,i=n-t.quarterTurns*90,r=Math.abs(i)<1e-6;let a,s;if(r)t.quarterTurns===1||t.quarterTurns===3?(a=e.height,s=e.width):(a=e.width,s=e.height);else{const u=qe(e,o);a=Math.max(1,Math.round(u.width)),s=Math.max(1,Math.round(u.height))}const c=Q(a,s),l=et(c);return l.imageSmoothingEnabled=!0,l.imageSmoothingQuality="high",l.translate(a/2,s/2),l.rotate(o),l.drawImage(e.bitmap,-e.width/2,-e.height/2),{bitmap:c.canvas,width:a,height:s,mimeType:e.mimeType}}const ht=8e3,Et=1;function Yo(){return{scaleX:1,scaleY:1,lockAspect:!0}}function Xe(t){return Math.abs(t.scaleX-1)<1e-9&&Math.abs(t.scaleY-1)<1e-9}function Ye(t,e){const n=At(Math.round(e.width*t.scaleX)),o=At(Math.round(e.height*t.scaleY));return{width:n,height:o}}function Go(t,e,n){if(n.width<=0)return t;const i=At(Math.round(e))/n.width,r=t.lockAspect?i:t.scaleY;return{...t,scaleX:i,scaleY:r}}function Ko(t,e,n){if(n.height<=0)return t;const i=At(Math.round(e))/n.height,r=t.lockAspect?i:t.scaleX;return{...t,scaleX:r,scaleY:i}}function Vo(t,e){const n=Qo(e/100);return{...t,scaleX:n,scaleY:n}}function jo(t,e){if(t.lockAspect===e)return t;if(!e)return{...t,lockAspect:!1};const n=(t.scaleX+t.scaleY)/2;return{scaleX:n,scaleY:n,lockAspect:!0}}function At(t){return Number.isFinite(t)?Math.max(Et,Math.min(ht,Math.trunc(t))):Et}function Qo(t){return!Number.isFinite(t)||t<=0?.01:Math.max(.01,Math.min(t,ht))}async function Jo(t,e){if(Xe(t))return e;const{width:n,height:o}=Ye(t,e);if(n<=0||o<=0)return e;const i=Zo(e.width,e.height,n,o);let r={bitmap:e.bitmap,width:e.width,height:e.height};for(let s=0;s<i;s++){const c=Math.max(n,Math.floor(r.width/2)),l=Math.max(o,Math.floor(r.height/2));r={bitmap:Ge(r,c,l).canvas,width:c,height:l}}return{bitmap:Ge(r,n,o).canvas,width:n,height:o,mimeType:e.mimeType}}function Zo(t,e,n,o){let i=t,r=e,a=0;for(;(i/2>n||r/2>o)&&a<16;)i=Math.floor(i/2),r=Math.floor(r/2),a+=1;return a}function Ge(t,e,n){const o=Q(e,n),i=et(o);return i.imageSmoothingEnabled=!0,i.imageSmoothingQuality="high",i.drawImage(t.bitmap,0,0,t.width,t.height,0,0,e,n),o}const Mt=-100,It=100,Rt=1,pt={brightness:0,contrast:0,saturation:0,exposure:0,clarity:0,gamma:0},Ke=[{key:"brightness",label:"Brightness"},{key:"contrast",label:"Contrast"},{key:"saturation",label:"Saturation"},{key:"exposure",label:"Exposure"},{key:"clarity",label:"Clarity"},{key:"gamma",label:"Gamma"}];function ti(){return pt}function Gt(t){return t.brightness===0&&t.contrast===0&&t.saturation===0&&t.exposure===0&&t.clarity===0&&t.gamma===0}function Ve(t,e,n){const o=oi(n);return t[e]===o?t:{...t,[e]:o}}function ei(t,e){return t[e]===0?t:{...t,[e]:0}}function ni(){return pt}function oi(t){return Number.isNaN(t)?0:t<=Mt?Mt:t>=It?It:Math.round(t/Rt)*Rt}function je(t){const e=new Uint8ClampedArray(256),n=t.brightness/200,o=1+t.contrast/100,i=1+t.exposure/200,r=ii(t.gamma);for(let a=0;a<256;a++){let s=a/255;s=s*i,s=(s-.5)*o+.5,s=s+n,s<0?s=0:s>1&&(s=1),s=s**r,s<0?s=0:s>1&&(s=1),e[a]=Math.round(s*255)}return e}function ii(t){return t===0?1:t>0?1-.5*(t/100):1+1*(-t/100)}function Qe(t,e,n,o){const i=t.length;if(e.length!==i)throw new Error("applyFinetuneLutAndSaturation: src/dst length mismatch");const r=1+o.saturation/100;if(r===1){for(let a=0;a<i;a+=4)e[a]=n[t[a]],e[a+1]=n[t[a+1]],e[a+2]=n[t[a+2]],e[a+3]=t[a+3];return}for(let a=0;a<i;a+=4){const s=n[t[a]],c=n[t[a+1]],l=n[t[a+2]],u=.2126*s+.7152*c+.0722*l;let d=u+(s-u)*r,h=u+(c-u)*r,f=u+(l-u)*r;d<0?d=0:d>255&&(d=255),h<0?h=0:h>255&&(h=255),f<0?f=0:f>255&&(f=255),e[a]=d,e[a+1]=h,e[a+2]=f,e[a+3]=t[a+3]}}function Je(t,e,n){if(n===0)return;const o=t.length;if(e.length!==o)throw new Error("applyClarity: dst/blurred length mismatch");const i=n/100;for(let r=0;r<o;r+=4){const a=t[r],s=t[r+1],c=t[r+2];let l=a+i*(a-e[r]),u=s+i*(s-e[r+1]),d=c+i*(c-e[r+2]);l<0?l=0:l>255&&(l=255),u<0?u=0:u>255&&(u=255),d<0?d=0:d>255&&(d=255),t[r]=l,t[r+1]=u,t[r+2]=d}}function Ze(t,e,n,o,i){if(t.length!==e.length||t.length!==n.length)throw new Error("boxBlur3x3: buffer length mismatch");for(let r=0;r<i;r++)for(let a=0;a<o;a++){const s=a===0?0:a-1,c=a===o-1?o-1:a+1,l=(r*o+a)*4,u=(r*o+s)*4,d=(r*o+c)*4;e[l]=(t[u]+t[l]+t[d])/3,e[l+1]=(t[u+1]+t[l+1]+t[d+1])/3,e[l+2]=(t[u+2]+t[l+2]+t[d+2])/3,e[l+3]=t[l+3]}for(let r=0;r<i;r++){const a=r===0?0:r-1,s=r===i-1?i-1:r+1;for(let c=0;c<o;c++){const l=(r*o+c)*4,u=(a*o+c)*4,d=(s*o+c)*4;n[l]=(e[u]+e[l]+e[d])/3,n[l+1]=(e[u+1]+e[l+1]+e[d+1])/3,n[l+2]=(e[u+2]+e[l+2]+e[d+2])/3,n[l+3]=e[l+3]}}}function Kt(t,e,n){if(e.width!==n.width||e.height!==n.height||e.data.length!==n.data.length)throw new Error("applyFinetuneToImageData: baseline/dst dimensions mismatch");const o=je(t);if(Qe(e.data,n.data,o,t),t.clarity!==0){const i=new Uint8ClampedArray(e.data.length),r=new Uint8ClampedArray(e.data.length);Ze(e.data,i,r,e.width,e.height),Je(n.data,r,t.clarity)}}async function ri(t,e){if(Gt(t))return e;const n=Q(e.width,e.height),o=et(n);o.imageSmoothingEnabled=!0,o.imageSmoothingQuality="high",o.drawImage(e.bitmap,0,0,e.width,e.height);const i=o.getImageData(0,0,e.width,e.height);if(t.clarity===0)Kt(t,i,i),o.putImageData(i,0,0);else{const r=new ImageData(new Uint8ClampedArray(i.data.length),i.width,i.height);Kt(t,i,r),o.putImageData(r,0,0)}return{bitmap:n.canvas,width:e.width,height:e.height,mimeType:e.mimeType}}const Vt=[{id:"none",label:"None",state:pt},{id:"vivid",label:"Vivid",state:{brightness:0,contrast:10,saturation:40,exposure:0,clarity:5,gamma:0}},{id:"mono",label:"Mono",state:{brightness:0,contrast:15,saturation:-100,exposure:0,clarity:0,gamma:0}},{id:"soft",label:"Soft",state:{brightness:5,contrast:-10,saturation:0,exposure:0,clarity:-25,gamma:0}},{id:"punch",label:"Punch",state:{brightness:0,contrast:30,saturation:5,exposure:0,clarity:25,gamma:0}},{id:"mute",label:"Mute",state:{brightness:0,contrast:5,saturation:-50,exposure:0,clarity:-5,gamma:0}},{id:"bright",label:"Bright",state:{brightness:5,contrast:5,saturation:0,exposure:15,clarity:0,gamma:0}}];function ai(t,e){return t.brightness===e.brightness&&t.contrast===e.contrast&&t.saturation===e.saturation&&t.exposure===e.exposure&&t.clarity===e.clarity&&t.gamma===e.gamma}function jt(t){for(const e of Vt)if(ai(e.state,t))return e}const si="rgba(255, 235, 59, 0.35)",ci=18,tn=32,li="#ff3b30",ui=4;function di(){return{color:li,strokeWidth:ui,fillColor:null,fontSize:tn}}function hi(t){return{shapes:[],selectedId:null,activeTool:"select",currentStyle:di(),imageSize:t.imageSize,nextShapeNumber:1}}function at(t){return{id:`s_${t.nextShapeNumber.toString(36)}`,nextShapeNumber:t.nextShapeNumber+1}}function Qt(t,e){return t.activeTool===e?t:{...t,activeTool:e,selectedId:e==="select"?t.selectedId:null}}function en(t,e){return{...t,currentStyle:{...t.currentStyle,...e}}}function mt(t,e){return t.selectedId===e?t:{...t,selectedId:e}}function st(t,e){return{...t,shapes:[...t.shapes,e],selectedId:e.id}}function nt(t,e){let n=!1;const o=t.shapes.map(i=>i.id!==e.id?i:(n=!0,e));return n?{...t,shapes:o}:t}function Nt(t,e){const n=t.shapes.filter(o=>o.id!==e);return n.length===t.shapes.length?t:{...t,shapes:n,selectedId:t.selectedId===e?null:t.selectedId}}function nn(t){let{x:e,y:n,width:o,height:i}=t;return o<0&&(e+=o,o=-o),i<0&&(n+=i,i=-i),{x:e,y:n,width:o,height:i}}function on(t,e,n){switch(t.kind){case"text":return{...t,x:t.x+e,y:t.y+n};case"rect":case"ellipse":return{...t,x:t.x+e,y:t.y+n};case"arrow":return{...t,x1:t.x1+e,y1:t.y1+n,x2:t.x2+e,y2:t.y2+n};case"freehand":case"highlight":return{...t,points:t.points.map(o=>({x:o.x+e,y:o.y+n}))};default:return Lt(t)}}function Lt(t){throw new Error(`Unhandled annotation shape kind: ${JSON.stringify(t)}`)}function rn(t){return t==="text"||t==="rect"||t==="ellipse"||t==="arrow"}function pi(t,e){const{imageSize:n,style:o,id:i}=e,r=Math.min(n.width,n.height),a=n.width/2,s=n.height/2;switch(t){case"rect":case"ellipse":{const c=Math.max(80,Math.round(r*.25)),l=Math.round(a-c/2),u=Math.round(s-c/2);return t==="rect"?{id:i,kind:"rect",x:l,y:u,width:c,height:c,strokeColor:o.color,strokeWidth:o.strokeWidth,fillColor:o.fillColor}:{id:i,kind:"ellipse",x:l,y:u,width:c,height:c,strokeColor:o.color,strokeWidth:o.strokeWidth,fillColor:o.fillColor}}case"arrow":{const c=Math.max(100,Math.round(r*.3)),l=Math.round(a-c/2),u=l+c,d=Math.round(s);return{id:i,kind:"arrow",x1:l,y1:d,x2:u,y2:d,color:o.color,strokeWidth:o.strokeWidth}}case"text":{const c=Math.round(a),l=Math.round(s-o.fontSize/2);return{id:i,kind:"text",x:c,y:l,text:"",fontSize:o.fontSize,color:o.color,textAlign:"center"}}}}function ft(t){switch(t.kind){case"text":{const{width:e,height:n}=fi(t.text,t.fontSize);return{x:gi(t.x,e,t.textAlign),y:t.y,width:e,height:n}}case"rect":case"ellipse":return{x:t.x,y:t.y,width:t.width,height:t.height};case"arrow":{const e=Math.min(t.x1,t.x2),n=Math.min(t.y1,t.y2);return{x:e,y:n,width:Math.abs(t.x2-t.x1),height:Math.abs(t.y2-t.y1)}}case"freehand":case"highlight":{const e=t.points[0];if(!e)return{x:0,y:0,width:0,height:0};let n=e.x,o=e.y,i=e.x,r=e.y;for(const a of t.points)a.x<n&&(n=a.x),a.x>i&&(i=a.x),a.y<o&&(o=a.y),a.y>r&&(r=a.y);return{x:n,y:o,width:i-n,height:r-o}}default:return Lt(t)}}const Tt=["tl","tr","bl","br","t","r","b","l"];function mi(t){const e=t.x,n=t.x+t.width,o=t.y,i=t.y+t.height,r=t.x+t.width/2,a=t.y+t.height/2;return{tl:{x:e,y:o},tr:{x:n,y:o},bl:{x:e,y:i},br:{x:n,y:i},t:{x:r,y:o},r:{x:n,y:a},b:{x:r,y:i},l:{x:e,y:a}}}function Jt(t,e,n){let o=t.x,i=t.y,r=t.x+t.width,a=t.y+t.height;return(e==="tl"||e==="l"||e==="bl")&&(o=n.x),(e==="tr"||e==="r"||e==="br")&&(r=n.x),(e==="tl"||e==="t"||e==="tr")&&(i=n.y),(e==="bl"||e==="b"||e==="br")&&(a=n.y),{x:o,y:i,width:r-o,height:a-i}}function fi(t,e){const n=t.length===0?[""]:t.split(`
2
+ `);let o=0;for(const a of n)a.length>o&&(o=a.length);const i=Math.max(e*.6,o*e*.55),r=n.length*e*1.2;return{width:i,height:r}}function gi(t,e,n){switch(n){case"left":return t;case"center":return t-e/2;case"right":return t-e}}const ct=4;function yi(t,e){for(let n=t.length-1;n>=0;n--){const o=t[n];if(o&&bi(o,e))return o}}function bi(t,e){switch(t.kind){case"text":return gt(e,ft(t));case"rect":{const n=gt(e,Ft(t));if(t.fillColor!==null)return n;const o=Zt(Ft(t),t.strokeWidth/2+ct),i=Zt(Ft(t),-(t.strokeWidth/2+ct));return gt(e,o)&&!gt(e,i)}case"ellipse":{const n=Ft(t),o=n.width/2,i=n.height/2,r=n.x+o,a=n.y+i;if(o<=0||i<=0)return!1;const s=(e.x-r)/o,c=(e.y-a)/i,l=s*s+c*c,u=(t.strokeWidth/2+ct)/Math.min(o,i);return t.fillColor!==null?l<=(1+u)**2:l<=(1+u)**2&&l>=(1-u)**2}case"arrow":return an(e,{x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t.strokeWidth/2+ct);case"freehand":case"highlight":{const n=ft(t),o=Zt(n,t.strokeWidth/2+ct);if(!gt(e,o))return!1;const i=t.strokeWidth/2+ct;for(let r=1;r<t.points.length;r++){const a=t.points[r-1],s=t.points[r];if(a&&s&&an(e,a,s,i))return!0}if(t.points.length===1){const r=t.points[0];if(!r)return!1;const a=r.x-e.x,s=r.y-e.y;return a*a+s*s<=i*i}return!1}default:return Lt(t)}}function gt(t,e){return t.x>=e.x&&t.y>=e.y&&t.x<=e.x+e.width&&t.y<=e.y+e.height}function Zt(t,e){return{x:t.x-e,y:t.y-e,width:t.width+e*2,height:t.height+e*2}}function Ft(t){let{x:e,y:n,width:o,height:i}=t;return o<0&&(e+=o,o=-o),i<0&&(n+=i,i=-i),{x:e,y:n,width:o,height:i}}function an(t,e,n,o){const i=n.x-e.x,r=n.y-e.y,a=i*i+r*r;if(a===0){const h=t.x-e.x,f=t.y-e.y;return h*h+f*f<=o*o}let s=((t.x-e.x)*i+(t.y-e.y)*r)/a;s<0?s=0:s>1&&(s=1);const c=e.x+s*i,l=e.y+s*r,u=t.x-c,d=t.y-l;return u*u+d*d<=o*o}const sn=2;function wi(t){if(t.length<=1)return[...t];const e=t[0];if(!e)return[];const n=[e];let o=e;const i=sn*sn;for(let a=1;a<t.length-1;a++){const s=t[a];if(!s)continue;const c=s.x-o.x,l=s.y-o.y;c*c+l*l<i||(n.push(s),o=s)}const r=t[t.length-1];return r&&r!==o&&n.push(r),n}function cn(t,e){if(e.length===0)return;const n=e[0];if(!n)return;if(e.length===1){t.moveTo(n.x,n.y),t.lineTo(n.x,n.y);return}t.moveTo(n.x,n.y);for(let i=1;i<e.length-1;i++){const r=e[i],a=e[i+1];if(!r||!a)continue;const s=(r.x+a.x)/2,c=(r.y+a.y)/2;t.quadraticCurveTo(r.x,r.y,s,c)}const o=e[e.length-1];o&&t.lineTo(o.x,o.y)}const ln='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';async function Ci(t,e){if(t.shapes.length===0)return e;const n=Q(e.width,e.height),o=et(n);o.imageSmoothingEnabled=!0,o.imageSmoothingQuality="high",o.drawImage(e.bitmap,0,0,e.width,e.height);for(const i of t.shapes)te(o,i);return{bitmap:n.canvas,width:e.width,height:e.height,mimeType:e.mimeType}}function te(t,e){switch(e.kind){case"text":xi(t,e);return;case"rect":vi(t,e);return;case"ellipse":ki(t,e);return;case"arrow":Si(t,e);return;case"freehand":Ei(t,e);return;case"highlight":Ai(t,e);return;default:Lt(e)}}function xi(t,e){t.save(),t.fillStyle=e.color,t.font=`${e.fontSize}px ${ln}`,t.textAlign=e.textAlign,t.textBaseline="top";const n=e.text.length===0?[""]:e.text.split(`
3
+ `),o=e.fontSize*1.2;for(let i=0;i<n.length;i++){const r=n[i];r!==void 0&&t.fillText(r,e.x,e.y+i*o)}t.restore()}function vi(t,e){t.save(),e.fillColor!==null&&(t.fillStyle=e.fillColor,t.fillRect(e.x,e.y,e.width,e.height)),e.strokeWidth>0&&(t.strokeStyle=e.strokeColor,t.lineWidth=e.strokeWidth,t.lineJoin="miter",t.strokeRect(e.x,e.y,e.width,e.height)),t.restore()}function ki(t,e){t.save();const n=e.width/2,o=e.height/2,i=e.x+n,r=e.y+o;t.beginPath(),t.ellipse(i,r,Math.max(0,n),Math.max(0,o),0,0,Math.PI*2),e.fillColor!==null&&(t.fillStyle=e.fillColor,t.fill()),e.strokeWidth>0&&(t.strokeStyle=e.strokeColor,t.lineWidth=e.strokeWidth,t.stroke()),t.restore()}function Si(t,e){const n=e.x2-e.x1,o=e.y2-e.y1,i=Math.sqrt(n*n+o*o);if(i<.5)return;t.save(),t.strokeStyle=e.color,t.fillStyle=e.color,t.lineWidth=e.strokeWidth,t.lineCap="round",t.lineJoin="round";const r=Math.min(Math.max(e.strokeWidth*5,28),i*.6),a=Math.max(e.strokeWidth*4,18),s=n/i,c=o/i,l=e.x2-s*r*.6,u=e.y2-c*r*.6;t.beginPath(),t.moveTo(e.x1,e.y1),t.lineTo(l,u),t.stroke();const d=e.x2-s*r,h=e.y2-c*r,f=-c,m=s;t.beginPath(),t.moveTo(e.x2,e.y2),t.lineTo(d+f*a/2,h+m*a/2),t.lineTo(d-f*a/2,h-m*a/2),t.closePath(),t.fill(),t.restore()}function Ei(t,e){e.points.length!==0&&(t.save(),t.strokeStyle=e.color,t.lineWidth=e.strokeWidth,t.lineCap="round",t.lineJoin="round",t.beginPath(),cn(t,e.points),t.stroke(),t.restore())}function Ai(t,e){e.points.length!==0&&(t.save(),t.globalCompositeOperation="multiply",t.strokeStyle=e.color,t.lineWidth=e.strokeWidth,t.lineCap="round",t.lineJoin="round",t.beginPath(),cn(t,e.points),t.stroke(),t.restore())}const Mi="#000000",Ii="pixelate";function Ri(t){return{regions:[],nextRegionNumber:1,selectedId:null,currentMode:Ii,currentColor:Mi,imageSize:t.imageSize}}function un(t){return{id:`r_${t.nextRegionNumber.toString(36)}`,nextRegionNumber:t.nextRegionNumber+1}}function dn(t,e){return{...t,regions:[...t.regions,e],selectedId:e.id}}function J(t,e){let n=!1;const o=t.regions.map(i=>i.id!==e.id?i:(n=!0,e));return n?{...t,regions:o}:t}function hn(t,e){const n=t.regions.filter(o=>o.id!==e);return n.length===t.regions.length?t:{...t,regions:n,selectedId:t.selectedId===e?null:t.selectedId}}function pn(t,e){return t.selectedId===e?t:{...t,selectedId:e}}function Ni(t,e){return t.currentMode===e?t:{...t,currentMode:e}}function Li(t,e){return t.currentColor===e?t:{...t,currentColor:e}}function Ti(t,e,n){const o=t.regions.find(i=>i.id===e);return!o||o.mode===n?t:J(t,{...o,mode:n})}function Fi(t,e,n){const o=t.regions.find(i=>i.id===e);return!o||o.color===n?t:J(t,{...o,color:n})}function lt(t){return t.selectedId===null?null:t.regions.find(e=>e.id===t.selectedId)??null}function Pi(t){let{x:e,y:n,width:o,height:i}=t;return o<0&&(e+=o,o=-o),i<0&&(n+=i,i=-i),{x:e,y:n,width:o,height:i}}function $i(t){const{imageSize:e,mode:n,color:o,id:i}=t,r=Math.min(e.width,e.height),a=Math.max(80,Math.round(r*.25)),s=e.width/2,c=e.height/2,l=Math.round(s-a/2),u=Math.round(c-a/2);return{id:i,x:l,y:u,width:a,height:a,mode:n,color:o}}function Di(t,e){if(t.imageSize.width===e.width&&t.imageSize.height===e.height)return t;const n=[];for(const i of t.regions)i.x+i.width<=0||i.y+i.height<=0||i.x>=e.width||i.y>=e.height||n.push(Hi(i,e));const o=t.selectedId!==null&&!n.some(i=>i.id===t.selectedId);return{...t,regions:n,imageSize:{width:e.width,height:e.height},selectedId:o?null:t.selectedId}}function Hi(t,e){const n=Math.max(0,t.x),o=Math.max(0,t.y),i=Math.min(e.width,t.x+t.width),r=Math.min(e.height,t.y+t.height);return{...t,x:n,y:o,width:Math.max(0,i-n),height:Math.max(0,r-o)}}async function Oi(t,e){if(t.regions.length===0)return e;const n=Q(e.width,e.height),o=et(n);o.drawImage(e.bitmap,0,0,e.width,e.height);for(const i of t.regions)mn(o,n.canvas,i,e);return{bitmap:n.canvas,width:e.width,height:e.height,mimeType:e.mimeType}}function mn(t,e,n,o){const i=Math.round(n.width),r=Math.round(n.height);if(i<1||r<1)return;const a=Math.round(n.x),s=Math.round(n.y);switch(n.mode){case"solid":zi(t,n,a,s,i,r);return;case"pixelate":Bi(t,e,o,a,s,i,r);return;case"blur":_i(t,e,o,a,s,i,r);return}}function zi(t,e,n,o,i,r){t.save(),t.fillStyle=e.color,t.fillRect(n,o,i,r),t.restore()}function Bi(t,e,n,o,i,r,a){const s=Math.max(r,a),c=Math.max(4,Math.round(8*Math.min(1,s/240))),l=Math.max(1,Math.round(r/s*c)),u=Math.max(1,Math.round(a/s*c));t.save();const d=ee(l,u);if(!d){t.restore();return}d.ctx.imageSmoothingEnabled=!0,d.ctx.imageSmoothingQuality="low",d.ctx.drawImage(e,o,i,r,a,0,0,l,u),t.imageSmoothingEnabled=!1,t.drawImage(d.canvas,0,0,l,u,o,i,r,a),t.restore()}function _i(t,e,n,o,i,r,a){const c=Math.max(1,Math.round(r*.125)),l=Math.max(1,Math.round(a*.125)),u=ee(c,l);if(!u)return;u.ctx.imageSmoothingEnabled=!0,u.ctx.imageSmoothingQuality="high",u.ctx.drawImage(e,o,i,r,a,0,0,c,l);const d=Math.max(1,Math.round(c*.5)),h=Math.max(1,Math.round(l*.5)),f=ee(d,h);if(!f){t.save(),t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high",t.drawImage(u.canvas,0,0,c,l,o,i,r,a),t.restore();return}f.ctx.imageSmoothingEnabled=!0,f.ctx.imageSmoothingQuality="high",f.ctx.drawImage(u.canvas,0,0,c,l,0,0,d,h),t.save(),t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high",t.drawImage(f.canvas,0,0,d,h,o,i,r,a),t.restore()}function ee(t,e){if(typeof OffscreenCanvas<"u")try{const i=new OffscreenCanvas(t,e),r=i.getContext("2d");if(r)return{canvas:i,ctx:r}}catch{}if(typeof document>"u")return null;const n=document.createElement("canvas");n.width=t,n.height=e;const o=n.getContext("2d");return o?{canvas:n,ctx:o}:null}const fn=[{id:"none",label:"None",acceptsColor:!1,defaultColor:"#000000"},{id:"solidSharp",label:"Mat Sharp",acceptsColor:!0,defaultColor:"#000000"},{id:"solidRound",label:"Mat Round",acceptsColor:!0,defaultColor:"#000000"},{id:"lineSingle",label:"Line Single",acceptsColor:!0,defaultColor:"#000000"},{id:"hook",label:"Corner Hooks",acceptsColor:!0,defaultColor:"#000000"},{id:"polaroid",label:"Polaroid",acceptsColor:!0,defaultColor:"#ffffff"}],Wi={presetId:"none",color:"#000000"};function qi(){return Wi}function gn(t){return t.presetId==="none"}function Ui(t,e){if(t.presetId===e)return t;const n=yn(t.presetId),o=yn(e);if(!o)return{...t,presetId:e};const r=n!==void 0&&t.color===n.defaultColor?o.defaultColor:t.color;return{presetId:e,color:r}}function Xi(t,e){return t.color===e?t:{...t,color:e}}function yn(t){return fn.find(e=>e.id===t)}async function Yi(t,e){return gn(t)?e:t.presetId==="polaroid"?Qi(t.color,e):t.presetId==="none"?e:Gi(t.presetId,t.color,e)}function Gi(t,e,n){const o=Q(n.width,n.height),i=et(o);return i.drawImage(n.bitmap,0,0,n.width,n.height),ne(i,t,e,n.width,n.height),{bitmap:o.canvas,width:n.width,height:n.height,mimeType:n.mimeType}}function ne(t,e,n,o,i){switch(e){case"solidSharp":bn(t,n,o,i);return;case"solidRound":Ki(t,n,o,i);return;case"lineSingle":Vi(t,n,o,i);return;case"hook":ji(t,n,o,i);return}}function bn(t,e,n,o){const i=wn(n,o);t.save(),t.fillStyle=e,t.fillRect(0,0,n,i),t.fillRect(0,o-i,n,i),t.fillRect(0,i,i,o-2*i),t.fillRect(n-i,i,i,o-2*i),t.restore()}function Ki(t,e,n,o){const r=wn(n,o);bn(t,e,n,o),t.save(),t.globalCompositeOperation="destination-out",t.fillStyle="#000",Pt(t,0,0,r,"tl"),Pt(t,n,0,r,"tr"),Pt(t,0,o,r,"bl"),Pt(t,n,o,r,"br"),t.restore()}function Pt(t,e,n,o,i){switch(t.beginPath(),t.moveTo(e,n),i){case"tl":t.lineTo(e+o,n),t.arc(e+o,n+o,o,-Math.PI/2,Math.PI,!0),t.lineTo(e,n);break;case"tr":t.lineTo(e,n+o),t.arc(e-o,n+o,o,0,-Math.PI/2,!0),t.lineTo(e,n);break;case"bl":t.lineTo(e+o,n),t.arc(e+o,n-o,o,Math.PI/2,Math.PI,!1),t.lineTo(e,n);break;case"br":t.lineTo(e-o,n),t.arc(e-o,n-o,o,Math.PI/2,0,!0),t.lineTo(e,n);break}t.closePath(),t.fill()}function Vi(t,e,n,o){const i=Math.round(Math.min(n,o)*.05),r=Math.max(2,Math.round(Math.min(n,o)*.01));t.save(),t.strokeStyle=e,t.lineWidth=r;const a=r/2;t.strokeRect(i+a,i+a,n-2*i-r,o-2*i-r),t.restore()}function ji(t,e,n,o){const i=Math.round(Math.min(n,o)*.08),r=Math.max(2,Math.round(Math.min(n,o)*.01)),a=Math.round(Math.min(n,o)*.05);t.save(),t.strokeStyle=e,t.lineWidth=r,t.lineCap="square";const s=r/2,c=(l,u,d,h)=>{t.beginPath(),t.moveTo(l+d*i,u),t.lineTo(l,u),t.lineTo(l,u+h*i),t.stroke()};c(a+s,a+s,1,1),c(n-a-s,a+s,-1,1),c(a+s,o-a-s,1,-1),c(n-a-s,o-a-s,-1,-1),t.restore()}function Qi(t,e){const n=Math.min(e.width,e.height),o=Math.round(n*.05),i=o,r=o,a=Math.round(n*.18),s=e.width+i+r,c=e.height+o+a,l=Q(s,c),u=et(l);return u.fillStyle=t,u.fillRect(0,0,s,c),u.drawImage(e.bitmap,i,o,e.width,e.height),{bitmap:l.canvas,width:s,height:c,mimeType:e.mimeType}}function wn(t,e){return Math.max(4,Math.round(Math.min(t,e)*.04))}function oe(t,e,n){if(t!=="polaroid")return{width:e,height:n};const o=Math.min(e,n),i=Math.round(o*.05),r=Math.round(o*.18);return{width:e+2*i,height:n+i+r}}/**
4
+ * @license lucide v1.14.0 - ISC
5
+ *
6
+ * This source code is licensed under the ISC license.
7
+ * See the LICENSE file in the root directory of this source tree.
8
+ */const Ji=[["path",{d:"M5 12h14"}],["path",{d:"m12 5 7 7-7 7"}]];/**
9
+ * @license lucide v1.14.0 - ISC
10
+ *
11
+ * This source code is licensed under the ISC license.
12
+ * See the LICENSE file in the root directory of this source tree.
13
+ */const Zi=[["path",{d:"M20 6 9 17l-5-5"}]];/**
14
+ * @license lucide v1.14.0 - ISC
15
+ *
16
+ * This source code is licensed under the ISC license.
17
+ * See the LICENSE file in the root directory of this source tree.
18
+ */const tr=[["path",{d:"m6 9 6 6 6-6"}]];/**
19
+ * @license lucide v1.14.0 - ISC
20
+ *
21
+ * This source code is licensed under the ISC license.
22
+ * See the LICENSE file in the root directory of this source tree.
23
+ */const er=[["circle",{cx:"12",cy:"12",r:"10"}]];/**
24
+ * @license lucide v1.14.0 - ISC
25
+ *
26
+ * This source code is licensed under the ISC license.
27
+ * See the LICENSE file in the root directory of this source tree.
28
+ */const nr=[["path",{d:"m3 7 5 5-5 5V7"}],["path",{d:"m21 7-5 5 5 5V7"}],["path",{d:"M12 20v2"}],["path",{d:"M12 14v2"}],["path",{d:"M12 8v2"}],["path",{d:"M12 2v2"}]];/**
29
+ * @license lucide v1.14.0 - ISC
30
+ *
31
+ * This source code is licensed under the ISC license.
32
+ * See the LICENSE file in the root directory of this source tree.
33
+ */const or=[["path",{d:"m17 3-5 5-5-5h10"}],["path",{d:"m17 21-5-5-5 5h10"}],["path",{d:"M4 12H2"}],["path",{d:"M10 12H8"}],["path",{d:"M16 12h-2"}],["path",{d:"M22 12h-2"}]];/**
34
+ * @license lucide v1.14.0 - ISC
35
+ *
36
+ * This source code is licensed under the ISC license.
37
+ * See the LICENSE file in the root directory of this source tree.
38
+ */const ir=[["path",{d:"m9 11-6 6v3h9l3-3"}],["path",{d:"m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4"}]];/**
39
+ * @license lucide v1.14.0 - ISC
40
+ *
41
+ * This source code is licensed under the ISC license.
42
+ * See the LICENSE file in the root directory of this source tree.
43
+ */const rr=[["path",{d:"M10 8h.01"}],["path",{d:"M12 12h.01"}],["path",{d:"M14 8h.01"}],["path",{d:"M16 12h.01"}],["path",{d:"M18 8h.01"}],["path",{d:"M6 8h.01"}],["path",{d:"M7 16h10"}],["path",{d:"M8 12h.01"}],["rect",{width:"20",height:"16",x:"2",y:"4",rx:"2"}]];/**
44
+ * @license lucide v1.14.0 - ISC
45
+ *
46
+ * This source code is licensed under the ISC license.
47
+ * See the LICENSE file in the root directory of this source tree.
48
+ */const ar=[["path",{d:"M9 17H7A5 5 0 0 1 7 7"}],["path",{d:"M15 7h2a5 5 0 0 1 4 8"}],["line",{x1:"8",x2:"12",y1:"12",y2:"12"}],["line",{x1:"2",x2:"22",y1:"2",y2:"22"}]];/**
49
+ * @license lucide v1.14.0 - ISC
50
+ *
51
+ * This source code is licensed under the ISC license.
52
+ * See the LICENSE file in the root directory of this source tree.
53
+ */const sr=[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12"}]];/**
54
+ * @license lucide v1.14.0 - ISC
55
+ *
56
+ * This source code is licensed under the ISC license.
57
+ * See the LICENSE file in the root directory of this source tree.
58
+ */const cr=[["path",{d:"M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z"}]];/**
59
+ * @license lucide v1.14.0 - ISC
60
+ *
61
+ * This source code is licensed under the ISC license.
62
+ * See the LICENSE file in the root directory of this source tree.
63
+ */const lr=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"}],["path",{d:"m15 5 4 4"}]];/**
64
+ * @license lucide v1.14.0 - ISC
65
+ *
66
+ * This source code is licensed under the ISC license.
67
+ * See the LICENSE file in the root directory of this source tree.
68
+ */const ur=[["path",{d:"M5 12h14"}],["path",{d:"M12 5v14"}]];/**
69
+ * @license lucide v1.14.0 - ISC
70
+ *
71
+ * This source code is licensed under the ISC license.
72
+ * See the LICENSE file in the root directory of this source tree.
73
+ */const dr=[["path",{d:"m15 14 5-5-5-5"}],["path",{d:"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13"}]];/**
74
+ * @license lucide v1.14.0 - ISC
75
+ *
76
+ * This source code is licensed under the ISC license.
77
+ * See the LICENSE file in the root directory of this source tree.
78
+ */const hr=[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"}],["circle",{cx:"12",cy:"12",r:"3"}]];/**
79
+ * @license lucide v1.14.0 - ISC
80
+ *
81
+ * This source code is licensed under the ISC license.
82
+ * See the LICENSE file in the root directory of this source tree.
83
+ */const pr=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2"}]];/**
84
+ * @license lucide v1.14.0 - ISC
85
+ *
86
+ * This source code is licensed under the ISC license.
87
+ * See the LICENSE file in the root directory of this source tree.
88
+ */const mr=[["path",{d:"M10 11v6"}],["path",{d:"M14 11v6"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"}],["path",{d:"M3 6h18"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"}]];/**
89
+ * @license lucide v1.14.0 - ISC
90
+ *
91
+ * This source code is licensed under the ISC license.
92
+ * See the LICENSE file in the root directory of this source tree.
93
+ */const fr=[["path",{d:"M12 4v16"}],["path",{d:"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2"}],["path",{d:"M9 20h6"}]];/**
94
+ * @license lucide v1.14.0 - ISC
95
+ *
96
+ * This source code is licensed under the ISC license.
97
+ * See the LICENSE file in the root directory of this source tree.
98
+ */const gr=[["path",{d:"M9 14 4 9l5-5"}],["path",{d:"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11"}]];/**
99
+ * @license lucide v1.14.0 - ISC
100
+ *
101
+ * This source code is licensed under the ISC license.
102
+ * See the LICENSE file in the root directory of this source tree.
103
+ */const yr=[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]],br={xmlns:"http://www.w3.org/2000/svg",width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"};function wr(t,e={}){const n={...br,...e},o=Object.entries(n).map(([r,a])=>`${r}="${a}"`).join(" "),i=t.map(([r,a])=>{const s=Object.entries(a).map(([c,l])=>`${c}="${l}"`).join(" ");return`<${r} ${s} />`}).join("");return`<svg ${o}>${i}</svg>`}function Cr(t){switch(t){case"select":return cr;case"text":return fr;case"rect":return pr;case"ellipse":return er;case"arrow":return Ji;case"freehand":return lr;case"highlight":return ir;case"undo":return gr;case"redo":return dr;case"close":return yr;case"delete":return mr;case"check":return Zi;case"lockClosed":return sr;case"lockOpen":return ar;case"plus":return ur;case"flipHorizontal":return nr;case"flipVertical":return or;case"chevronDown":return tr;case"settings":return hr;case"keyboard":return rr}}function B(t,e){return wr(Cr(t),e)}let xr=0;function vr(t){const e=`kalotyp-editor-${++xr}`,n=`${e}-title`,o=document.createElement("div");o.className="pintura-editor kalotyp-editor",o.id=e,o.setAttribute("role","dialog"),o.setAttribute("aria-modal","true"),o.setAttribute("aria-labelledby",n),o.tabIndex=-1;const i=document.createElement("h2");i.id=n,i.className="kalotyp-visually-hidden",i.textContent="Image editor";const r=document.createElement("div");r.className="PinturaModal kalotyp-modal";const a=document.createElement("button");a.type="button",a.title="Close",a.setAttribute("aria-label","Close image editor"),a.className="kalotyp-button-close",a.innerHTML=B("close");const s=document.createElement("button");s.type="button",s.title="Preferences",s.setAttribute("aria-label","Open editor preferences"),s.setAttribute("aria-haspopup","dialog"),s.className="kalotyp-button-prefs",s.innerHTML=B("settings");const c=document.createElement("div");c.className="kalotyp-root",c.setAttribute("data-env","landscape has-navigation");const l=document.createElement("div");l.className="kalotyp-main";const u=document.createElement("div");u.className="kalotyp-stage",u.setAttribute("role","region"),u.setAttribute("aria-label","Image preview");const d=document.createElement("div");d.id=`${e}-panel`,d.className="kalotyp-util-main",d.setAttribute("role","tabpanel"),d.setAttribute("tabindex","0");const h=document.createElement("div");h.className="kalotyp-nav-tools";const f=document.createElement("div");f.className="kalotyp-util-footer";const m=document.createElement("div");m.className="kalotyp-export-group";const g=document.createElement("button");g.type="button",g.className="kalotyp-button-export";const p=document.createElement("span");p.className="kalotyp-button-inner",p.textContent=t.exportLabel,g.appendChild(p);const w=document.createElement("button");w.type="button",w.className="kalotyp-button-output-settings",w.title="Output settings",w.setAttribute("aria-label","Output settings (format and quality)"),w.setAttribute("aria-haspopup","dialog"),w.setAttribute("aria-expanded","false"),w.innerHTML=B("chevronDown"),m.appendChild(g),m.appendChild(w),f.appendChild(m);const y=document.createElement("div");return y.className="kalotyp-visually-hidden",y.setAttribute("role","status"),y.setAttribute("aria-live","polite"),y.setAttribute("aria-atomic","true"),l.appendChild(u),l.appendChild(d),c.appendChild(h),c.appendChild(l),c.appendChild(f),r.appendChild(i),r.appendChild(s),r.appendChild(a),r.appendChild(c),r.appendChild(y),o.appendChild(r),{editor:o,modal:r,root:c,main:l,stage:u,navTools:h,utilMain:d,utilFooter:f,closeButton:a,prefsButton:s,exportButton:g,outputSettingsButton:w,liveRegion:y,titleId:n}}function kr(t){const e=vr({exportLabel:t.exportLabel}),n=()=>t.onExportClick(),o=()=>t.onCloseClick(),i=()=>t.onOutputSettingsClick(),r=()=>t.onPrefsClick();e.exportButton.addEventListener("click",n),e.closeButton.addEventListener("click",o),e.outputSettingsButton.addEventListener("click",i),e.prefsButton.addEventListener("click",r),t.host.appendChild(e.editor);let a=!1;function s(c){a=!a,e.liveRegion.textContent=a?`${c} `:c}return{editor:e.editor,modal:e.modal,root:e.root,exportButton:e.exportButton,outputSettingsButton:e.outputSettingsButton,prefsButton:e.prefsButton,closeButton:e.closeButton,stage:e.stage,utilMain:e.utilMain,navTools:e.navTools,announce:s,destroy(){e.exportButton.removeEventListener("click",n),e.closeButton.removeEventListener("click",o),e.outputSettingsButton.removeEventListener("click",i),e.prefsButton.removeEventListener("click",r),e.editor.remove()}}}const ut=12;function Sr(t){const e=be(t.cropRectImage,t.viewport),{cornerAnchors:n,edgeHandles:o,bodyHitArea:i}=t;i.style.left=`${e.x}px`,i.style.top=`${e.y}px`,i.style.width=`${e.width}px`,i.style.height=`${e.height}px`,$t(n.tl,e.x,e.y),$t(n.tr,e.x+e.width,e.y),$t(n.bl,e.x,e.y+e.height),$t(n.br,e.x+e.width,e.y+e.height);const r=Math.max(0,e.width-ut*2),a=Math.max(0,e.height-ut*2);Cn(o.t,e.x+ut,e.y,r),Cn(o.b,e.x+ut,e.y+e.height,r),xn(o.l,e.x,e.y+ut,a),xn(o.r,e.x+e.width,e.y+ut,a)}function $t(t,e,n){t.style.left=`${e}px`,t.style.top=`${n}px`}function Cn(t,e,n,o){t.style.left=`${e}px`,t.style.top=`${n}px`,t.style.width=`${o}px`}function xn(t,e,n,o){t.style.left=`${e}px`,t.style.top=`${n}px`,t.style.height=`${o}px`}function Er(t,e,n,o,i){const r=Math.max(1,window.devicePixelRatio||1),a=Math.max(1,Math.round(n*r)),s=Math.max(1,Math.round(o*r));t.width!==a&&(t.width=a),t.height!==s&&(t.height=s),t.style.width=`${n}px`,t.style.height=`${o}px`;const c=t.getContext("2d");c&&(c.setTransform(r,0,0,r,0,0),c.clearRect(0,0,n,o),c.drawImage(e,i.displayRect.x,i.displayRect.y,i.displayRect.width,i.displayRect.height))}const Ar="rgba(0, 0, 0, 0.4)",Mr="rgba(0, 0, 0, 0.45)",Ir=3,Rr="rgba(255, 255, 255, 0.95)",Nr=1,Lr="rgba(0, 0, 0, 0.25)",Tr=2,Fr="rgba(255, 255, 255, 0.55)",Pr=1;function $r(t,e,n,o,i){const r=Math.max(1,window.devicePixelRatio||1),a=Math.max(1,Math.round(n*r)),s=Math.max(1,Math.round(o*r));t.width!==a&&(t.width=a),t.height!==s&&(t.height=s),t.style.width=`${n}px`,t.style.height=`${o}px`;const c=t.getContext("2d");if(!c)return;c.setTransform(r,0,0,r,0,0),c.clearRect(0,0,n,o);const l=be(e,i),u=i.displayRect;c.save(),c.fillStyle=Ar,c.fillRect(u.x,u.y,u.width,u.height),c.globalCompositeOperation="destination-out",c.fillRect(l.x,l.y,l.width,l.height),c.restore();const d=l.x+.5,h=l.y+.5,f=l.width-1,m=l.height-1;c.strokeStyle=Mr,c.lineWidth=Ir,c.strokeRect(d,h,f,m),c.strokeStyle=Rr,c.lineWidth=Nr,c.strokeRect(d,h,f,m),vn(c,l,Lr,Tr),vn(c,l,Fr,Pr)}function vn(t,e,n,o){t.strokeStyle=n,t.lineWidth=o,t.beginPath();for(let i=1;i<3;i++){const r=e.x+e.width*i/3,a=e.y+e.height*i/3;t.moveTo(r,e.y),t.lineTo(r,e.y+e.height),t.moveTo(e.x,a),t.lineTo(e.x+e.width,a)}t.stroke()}function Dr(t,e,n){const o=document.createElement("div");o.className="kalotyp-preset-row",o.setAttribute("role","radiogroup"),o.setAttribute("aria-label","Crop aspect ratio");const i=[];return t.forEach((r,a)=>{const[,s]=r,c=document.createElement("button");c.type="button",c.className="kalotyp-preset-button",c.textContent=s,c.setAttribute("role","radio"),c.setAttribute("aria-checked",a===e?"true":"false"),c.dataset.presetIndex=String(a),c.addEventListener("click",()=>n(a,r)),o.appendChild(c),i.push(c)}),{container:o,buttons:i}}function kn(t,e){t.forEach((n,o)=>{n.setAttribute("aria-checked",o===e?"true":"false")})}const Hr=["tl","tr","bl","br"],Or=["t","r","b","l"];function zr(){const t=document.createElement("div");t.className="kalotyp-stage-container";const e=document.createElement("canvas");e.className="kalotyp-stage-image",e.setAttribute("aria-hidden","true");const n=document.createElement("canvas");n.className="kalotyp-stage-overlay",n.setAttribute("aria-hidden","true");const o=document.createElement("div");o.className="kalotyp-stage-body";const i=document.createElement("div");i.className="kalotyp-handles",i.setAttribute("role","group"),i.setAttribute("aria-label","Crop region");const r={};for(const s of Or){const c=_r(s);r[s]=c,i.appendChild(c)}const a={};for(const s of Hr){const c=document.createElement("div");c.className="kalotyp-corner-anchor",c.dataset.direction=s;const l=Br(s);c.appendChild(l),r[s]=l,a[s]=c,i.appendChild(c)}return t.appendChild(e),t.appendChild(n),t.appendChild(o),t.appendChild(i),{container:t,imageCanvas:e,overlayCanvas:n,handlesLayer:i,handles:r,cornerAnchors:a,bodyHitArea:o}}function Br(t){const e=document.createElement("button");return e.type="button",e.className="kalotyp-handle",e.dataset.shape="circle",e.dataset.direction=t,e.setAttribute("aria-label",Sn(t)),e.tabIndex=0,e}function _r(t){const e=document.createElement("button");return e.type="button",e.className="kalotyp-handle",e.dataset.shape="edge",e.dataset.direction=t,e.setAttribute("aria-label",Sn(t)),e.tabIndex=0,e}function Sn(t){switch(t){case"tl":return"Top-left crop handle";case"tr":return"Top-right crop handle";case"bl":return"Bottom-left crop handle";case"br":return"Bottom-right crop handle";case"t":return"Top crop handle";case"r":return"Right crop handle";case"b":return"Bottom crop handle";case"l":return"Left crop handle"}}function Wr(t,e,n){const o=[];for(const i of Object.keys(t.handles)){const r=t.handles[i];o.push(qr(r,i,e,n))}return o.push(Ur(t.bodyHitArea,e,n)),{destroy(){for(const i of o)i()}}}function qr(t,e,n,o){return En(t,()=>{const i=o.getViewport(),r=n.get(),a={x:0,y:0,width:r.imageSize.width,height:r.imageSize.height},s=r.aspectRatio;return{onMove(c){const l=ie(t,c.clientX,c.clientY),u=Wt(l,i),d=go(r.rect,e,u,{bounds:a,...s!==void 0?{aspectRatio:s}:{}});n.set({rect:d})},onCommit(){o.onCommit?.()},onCancel(){n.set({rect:r.rect})}}})}function Ur(t,e,n){return En(t,o=>{const i=n.getViewport(),r=e.get(),a={x:0,y:0,width:r.imageSize.width,height:r.imageSize.height},s=ie(t,o.clientX,o.clientY);return{onMove(c){const l=ie(t,c.clientX,c.clientY),u=(l.x-s.x)/i.scale,d=(l.y-s.y)/i.scale,h=co(r.rect,u,d,a);e.set({rect:h})},onCommit(){n.onCommit?.()},onCancel(){e.set({rect:r.rect})}}})}function En(t,e){const n=o=>{if(o.button!==0)return;o.preventDefault(),o.stopPropagation();const i=e(o);t.setPointerCapture(o.pointerId);let r,a=!1;const s=()=>{if(a=!1,!r)return;const h=r;r=void 0,i.onMove(h)},c=h=>{h.pointerId===o.pointerId&&(r={clientX:h.clientX,clientY:h.clientY},a||(a=!0,requestAnimationFrame(s)))},l=h=>{t.removeEventListener("pointermove",c),t.removeEventListener("pointerup",u),t.removeEventListener("pointercancel",d);try{t.releasePointerCapture(o.pointerId)}catch{}if(r){const f=r;r=void 0,i.onMove(f)}h?i.onCommit():i.onCancel()},u=h=>{h.pointerId===o.pointerId&&l(!0)},d=h=>{h.pointerId===o.pointerId&&l(!1)};t.addEventListener("pointermove",c),t.addEventListener("pointerup",u),t.addEventListener("pointercancel",d)};return t.addEventListener("pointerdown",n),()=>t.removeEventListener("pointerdown",n)}function ie(t,e,n){const i=(t.closest(".kalotyp-stage-container")??t).getBoundingClientRect();return{x:e-i.left,y:n-i.top}}const An=32;function Xr(t){const{stageHost:e,utilHost:n,source:o,presets:i,presetFilter:r,store:a,viewport:s}=t,c=t.onCommit??Gr,l=zr();e.appendChild(l.container);const u=document.createElement("div");u.className="kalotyp-crop-panel";const d=wo(i,r),h=Mn(a.get(),i,d),f=Dr(d,h,(A,T)=>{const $=i.indexOf(T);if($===-1)return;const O=xo(a.get(),$);a.set({rect:O.rect,aspectRatio:O.aspectRatio,activePresetIndex:$}),kn(f.buttons,A),c()});u.appendChild(f.container);const m=Yr({initial:a.get().rect,bounds:{width:o.width,height:o.height},onCommit(A){const T=a.get(),$={x:0,y:0,width:T.imageSize.width,height:T.imageSize.height},O=xt(A,$);a.set({rect:O}),c()}});u.appendChild(m.container),n.appendChild(u);let g=j({width:1,height:1,padding:An},{width:o.width,height:o.height});function p(){const A=l.container.getBoundingClientRect(),T={width:A.width,height:A.height,padding:An},$={width:o.width,height:o.height};g=s?s.computeViewport(T,$):j(T,$)}function w(){const A=l.container.getBoundingClientRect();A.width<=0||A.height<=0||(Er(l.imageCanvas,o.bitmap,A.width,A.height,g),y())}function y(){const A=l.container.getBoundingClientRect();A.width<=0||A.height<=0||($r(l.overlayCanvas,a.get().rect,A.width,A.height,g),Sr({cropRectImage:a.get().rect,viewport:g,cornerAnchors:l.cornerAnchors,edgeHandles:{t:l.handles.t,r:l.handles.r,b:l.handles.b,l:l.handles.l},bodyHitArea:l.bodyHitArea}))}p(),w();const C=new ResizeObserver(()=>{p(),w()});C.observe(l.container);let E=!1;const S=s?.subscribe(()=>{E||(E=!0,requestAnimationFrame(()=>{E=!1,p(),w()}))});let M=!1;const H=a.subscribe((A,T)=>{Vr(A,T,i,d,f.buttons),!Kr(A.rect,T.rect)&&(m.sync(A.rect),!M&&(M=!0,requestAnimationFrame(()=>{M=!1,y()})))}),R=Wr({handles:l.handles,bodyHitArea:l.bodyHitArea},a,{getViewport:()=>g,onCommit:c});return{destroy(){R.destroy(),H(),S?.(),C.disconnect(),l.container.remove(),u.remove()}}}function Yr(t){const e=document.createElement("div");e.className="kalotyp-crop-dims",e.setAttribute("role","group"),e.setAttribute("aria-label","Crop region dimensions");const n=Dt("Left",t.initial.x,0,t.bounds.width),o=Dt("Top",t.initial.y,0,t.bounds.height),i=Dt("Width",t.initial.width,1,t.bounds.width),r=Dt("Height",t.initial.height,1,t.bounds.height);function a(){return{x:Math.round(n.input.valueAsNumber),y:Math.round(o.input.valueAsNumber),width:Math.round(i.input.valueAsNumber),height:Math.round(r.input.valueAsNumber)}}for(const c of[n,o,i,r])c.input.addEventListener("change",()=>{const l=a();Number.isFinite(l.x+l.y+l.width+l.height)&&t.onCommit(l)});e.appendChild(n.wrapper),e.appendChild(o.wrapper),e.appendChild(i.wrapper),e.appendChild(r.wrapper);function s(c){n.input.valueAsNumber!==c.x&&(n.input.value=String(Math.round(c.x))),o.input.valueAsNumber!==c.y&&(o.input.value=String(Math.round(c.y))),i.input.valueAsNumber!==c.width&&(i.input.value=String(Math.round(c.width))),r.input.valueAsNumber!==c.height&&(r.input.value=String(Math.round(c.height)))}return{container:e,sync:s}}function Dt(t,e,n,o){const i=document.createElement("label");i.className="kalotyp-crop-dims-field";const r=document.createElement("span");r.className="kalotyp-crop-dims-label",r.textContent=t;const a=document.createElement("input");return a.type="number",a.className="kalotyp-crop-dims-input",a.min=String(n),a.max=String(o),a.step="1",a.value=String(Math.round(e)),a.inputMode="numeric",a.setAttribute("aria-label",`${t} (pixels)`),i.appendChild(r),i.appendChild(a),{wrapper:i,input:a}}function Gr(){}function Kr(t,e){return t.x===e.x&&t.y===e.y&&t.width===e.width&&t.height===e.height}function Mn(t,e,n){if(t.activePresetIndex===-1)return-1;const o=e[t.activePresetIndex];return o?n.indexOf(o):-1}function Vr(t,e,n,o,i){if(t.activePresetIndex===e.activePresetIndex)return;const r=Mn(t,n,o);kn(i,r)}const jr="crop";function Qr(t){return{id:"crop",init(e){return Co({imageSize:{width:e.source.width,height:e.source.height},presets:t.presets,filter:t.presetFilter})},mount(e,n,o){const i=Xr({stageHost:e,utilHost:t.panelHost,source:n.source,presets:t.presets,presetFilter:t.presetFilter,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:jr})});return{destroy:()=>i.destroy()}},async bake(e,n){return ko(n,{rect:e.rect})}}}const In=32;function yt(){const t=document.createElement("div");t.className="kalotyp-stage-container kalotyp-preview-container";const e=document.createElement("canvas");return e.className="kalotyp-stage-image kalotyp-preview-canvas",e.setAttribute("aria-hidden","true"),t.appendChild(e),{container:t,canvas:e}}function Ht(t,e,n){const o=t.getBoundingClientRect();if(o.width<=0||o.height<=0)return;const i={width:o.width,height:o.height,padding:In};return{viewport:n?n.computeViewport(i,e):j(i,e),stageWidth:o.width,stageHeight:o.height}}function re(t,e,n,o){const i=Math.max(1,window.devicePixelRatio||1),r=Math.max(1,Math.round(e*i)),a=Math.max(1,Math.round(n*i));t.width!==r&&(t.width=r),t.height!==a&&(t.height=a),t.style.width=`${e}px`,t.style.height=`${n}px`;const s=t.getContext("2d");s&&(s.setTransform(i,0,0,i,0,0),s.clearRect(0,0,e,n),s.imageSmoothingEnabled=!0,s.imageSmoothingQuality="high",o(s))}function Jr(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??(()=>{}),s=yt();e.appendChild(s.container);const c=Zr({onToggleHorizontal:()=>{i.set(Oe(i.get(),"horizontal")),a()},onToggleVertical:()=>{i.set(Oe(i.get(),"vertical")),a()}});n.appendChild(c.container);function l(){const p=Ht(s.container,{width:o.width,height:o.height},r);if(!p)return;const w=i.get();re(s.canvas,p.stageWidth,p.stageHeight,y=>{const C=p.viewport.displayRect,E=w.horizontal?-1:1,S=w.vertical?-1:1,M=C.x+C.width/2,H=C.y+C.height/2;y.translate(M,H),y.scale(E,S),y.drawImage(o.bitmap,-C.width/2,-C.height/2,C.width,C.height)})}function u(p){c.horizontalButton.setAttribute("aria-pressed",p.horizontal?"true":"false"),c.verticalButton.setAttribute("aria-pressed",p.vertical?"true":"false")}u(i.get()),l();const d=new ResizeObserver(()=>l());d.observe(s.container);let h=!1;const f=r?.subscribe(()=>{h||(h=!0,requestAnimationFrame(()=>{h=!1,l()}))});let m=!1;const g=i.subscribe(p=>{u(p),!m&&(m=!0,requestAnimationFrame(()=>{m=!1,l()}))});return{destroy(){g(),f?.(),d.disconnect(),s.container.remove(),c.container.remove()}}}function Zr(t){const e=document.createElement("div");e.className="kalotyp-flip-panel",e.setAttribute("role","group"),e.setAttribute("aria-label","Flip");const n=Rn("Flip horizontal",B("flipHorizontal"),t.onToggleHorizontal);n.classList.add("kalotyp-flip-button-h");const o=Rn("Flip vertical",B("flipVertical"),t.onToggleVertical);return o.classList.add("kalotyp-flip-button-v"),e.appendChild(n),e.appendChild(o),{container:e,horizontalButton:n,verticalButton:o}}function Rn(t,e,n){const o=document.createElement("button");return o.type="button",o.className="kalotyp-toggle-button",o.innerHTML=`${e}<span>${t}</span>`,o.setAttribute("aria-pressed","false"),o.setAttribute("aria-label",t),o.addEventListener("click",n),o}function ta(t){return{id:"flip",init:()=>zo(),mount(e,n,o){const i=Jr({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"flip"})});return{destroy:()=>i.destroy()}},bake:Bo}}const ea="rgba(0, 0, 0, 0.4)",na="rgba(255, 255, 255, 0.95)",oa="rgba(0, 0, 0, 0.45)";function ia(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??sa,s=yt();e.appendChild(s.container);const c=ra({onCounterClockwise:()=>{i.set(qo(i.get())),a()},onClockwise:()=>{i.set(Wo(i.get())),a()},onAngleInput:p=>i.set(_e(i.get(),p)),onAngleCommit:()=>a(),onAngleReset:()=>{i.set(_e(i.get(),0)),a()}});n.appendChild(c.container);function l(){const p=s.container.getBoundingClientRect();if(p.width<=0||p.height<=0)return;const w=i.get(),y=Yt(w)*Math.PI/180,C=Yt(w)-w.quarterTurns*90,E=Math.abs(C)<1e-6,S=Math.abs(Math.cos(y)),M=Math.abs(Math.sin(y)),H=o.width*S+o.height*M,R=o.width*M+o.height*S,A={width:p.width,height:p.height,padding:In},T={width:H,height:R},$=r?r.computeViewport(A,T):j(A,T),O=$.displayRect,W=O.x+O.width/2,U=O.y+O.height/2,_=E?w.quarterTurns%2===0?{width:o.width,height:o.height}:{width:o.height,height:o.width}:qe(o,y);re(s.canvas,p.width,p.height,D=>{const G=o.width*$.scale,V=o.height*$.scale;D.save(),D.translate(W,U),D.rotate(y),D.drawImage(o.bitmap,-G/2,-V/2,G,V),D.restore();const Y=_.width*$.scale,x=_.height*$.scale,F=W-Y/2,N=U-x/2;E||(D.save(),D.beginPath(),D.rect(0,0,p.width,p.height),D.rect(F,N,Y,x),D.clip("evenodd"),D.fillStyle=ea,D.fillRect(0,0,p.width,p.height),D.restore()),D.save(),D.lineWidth=3,D.strokeStyle=oa,D.strokeRect(F+.5,N+.5,Y-1,x-1),D.lineWidth=1,D.strokeStyle=na,D.strokeRect(F+.5,N+.5,Y-1,x-1),D.restore()})}function u(p){c.angleSlider.valueAsNumber!==p.freeAngle&&(c.angleSlider.valueAsNumber=p.freeAngle);const w=aa(p.freeAngle);c.angleInput.value!==w&&(c.angleInput.value=w)}u(i.get()),l();const d=new ResizeObserver(()=>l());d.observe(s.container);let h=!1;const f=r?.subscribe(()=>{h||(h=!0,requestAnimationFrame(()=>{h=!1,l()}))});let m=!1;const g=i.subscribe(p=>{u(p),!m&&(m=!0,requestAnimationFrame(()=>{m=!1,l()}))});return{destroy(){g(),f?.(),d.disconnect(),s.container.remove(),c.container.remove()}}}function ra(t){const e=document.createElement("div");e.className="kalotyp-rotate-panel",e.setAttribute("role","group"),e.setAttribute("aria-label","Rotate");const n=Nn("Rotate 90° counter-clockwise","↺",t.onCounterClockwise),o=Nn("Rotate 90° clockwise","↻",t.onClockwise),i=document.createElement("label");i.className="kalotyp-rotate-slider-label",i.textContent="Straighten";const r=document.createElement("input");r.type="range",r.className="kalotyp-rotate-slider",r.min=String(Ut),r.max=String(Xt),r.step=String(Be),r.value="0",r.setAttribute("aria-label","Straighten angle"),r.addEventListener("input",()=>t.onAngleInput(r.valueAsNumber)),r.addEventListener("change",()=>t.onAngleCommit());const a=document.createElement("input");a.type="number",a.className="kalotyp-rotate-input",a.min=String(Ut),a.max=String(Xt),a.step=String(Be),a.value="0",a.setAttribute("aria-label","Straighten angle in degrees"),a.addEventListener("change",()=>{const h=a.valueAsNumber;Number.isFinite(h)&&(t.onAngleInput(h),t.onAngleCommit())});const s=document.createElement("span");s.className="kalotyp-rotate-suffix",s.setAttribute("aria-hidden","true"),s.textContent="°";const c=document.createElement("button");c.type="button",c.className="kalotyp-rotate-reset",c.textContent="Reset",c.addEventListener("click",t.onAngleReset);const l=document.createElement("div");l.className="kalotyp-rotate-row",l.appendChild(n),l.appendChild(o);const u=document.createElement("span");u.className="kalotyp-rotate-input-group",u.appendChild(a),u.appendChild(s);const d=document.createElement("div");return d.className="kalotyp-rotate-row kalotyp-rotate-slider-row",d.appendChild(i),d.appendChild(r),d.appendChild(u),d.appendChild(c),e.appendChild(l),e.appendChild(d),{container:e,angleSlider:r,angleInput:a}}function aa(t){const e=Math.round(t*10)/10;return Number.isInteger(e)?String(e):e.toFixed(1)}function sa(){}function Nn(t,e,n){const o=document.createElement("button");return o.type="button",o.className="kalotyp-quarter-button",o.setAttribute("aria-label",t),o.title=t,o.textContent=e,o.addEventListener("click",n),o}function ca(t){return{id:"rotate",init:()=>_o(),mount(e,n,o){const i=ia({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"rotate"})});return{destroy:()=>i.destroy()}},bake:Xo}}function la(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??(()=>{}),s=yt();e.appendChild(s.container);const c={width:o.width,height:o.height},l=ua({upstream:c,onWidthChange:p=>{i.set(Go(i.get(),p,c)),a()},onHeightChange:p=>{i.set(Ko(i.get(),p,c)),a()},onPercentChange:p=>{i.set(Vo(i.get(),p)),a()},onLockChange:p=>{i.set(jo(i.get(),p)),a()}});n.appendChild(l.container);function u(){const p=Ht(s.container,c,r);p&&re(s.canvas,p.stageWidth,p.stageHeight,w=>{const y=p.viewport.displayRect;w.drawImage(o.bitmap,y.x,y.y,y.width,y.height)})}function d(p){const w=Ye(p,c);l.widthInput.valueAsNumber!==w.width&&(l.widthInput.value=String(w.width)),l.heightInput.valueAsNumber!==w.height&&(l.heightInput.value=String(w.height));const y=(p.scaleX+p.scaleY)/2,C=Math.round(y*1e3)/10;Number.parseFloat(l.percentInput.value||"0")!==C&&(l.percentInput.value=String(C)),l.lockButton.setAttribute("aria-pressed",p.lockAspect?"true":"false"),l.lockButton.setAttribute("aria-label",p.lockAspect?"Aspect ratio locked — click to unlock":"Aspect ratio unlocked — click to lock"),l.lockButton.title=p.lockAspect?"Aspect ratio locked":"Aspect ratio unlocked",l.lockButton.innerHTML=Ln(p.lockAspect),l.summary.textContent=`${w.width} × ${w.height}px (from ${c.width} × ${c.height}px)`}d(i.get()),u();const h=new ResizeObserver(()=>u());h.observe(s.container);let f=!1;const m=r?.subscribe(()=>{f||(f=!0,requestAnimationFrame(()=>{f=!1,u()}))}),g=i.subscribe(p=>{d(p)});return{destroy(){g(),m?.(),h.disconnect(),s.container.remove(),l.container.remove()}}}function ua(t){const e=document.createElement("div");e.className="kalotyp-resize-panel",e.setAttribute("role","group"),e.setAttribute("aria-label","Resize");const n=ae({label:"Width (px)",min:Et,max:ht,step:1,value:t.upstream.width,onChange:t.onWidthChange}),o=ae({label:"Height (px)",min:Et,max:ht,step:1,value:t.upstream.height,onChange:t.onHeightChange}),i=ae({label:"Scale (%)",min:1,max:1e3,step:.1,value:100,onChange:t.onPercentChange}),r=document.createElement("button");r.type="button",r.className="kalotyp-resize-lock",r.setAttribute("aria-pressed","true"),r.setAttribute("aria-label","Lock aspect ratio"),r.title="Lock aspect ratio",r.innerHTML=Ln(!0),r.addEventListener("click",()=>{const l=r.getAttribute("aria-pressed")!=="true";t.onLockChange(l)});const a=document.createElement("span");a.className="kalotyp-resize-summary",a.setAttribute("aria-live","polite"),a.textContent=`${t.upstream.width} × ${t.upstream.height}px`,e.title=`Maximum ${ht}px on either axis`;const s=document.createElement("div");s.className="kalotyp-resize-row kalotyp-resize-dims",s.appendChild(n.wrapper),s.appendChild(r),s.appendChild(o.wrapper);const c=document.createElement("div");return c.className="kalotyp-resize-row",c.appendChild(i.wrapper),c.appendChild(a),e.appendChild(s),e.appendChild(c),{container:e,widthInput:n.input,heightInput:o.input,percentInput:i.input,lockButton:r,summary:a}}function ae(t){const e=document.createElement("label");e.className="kalotyp-resize-field";const n=document.createElement("span");n.className="kalotyp-resize-field-label",n.textContent=t.label;const o=document.createElement("input");return o.type="number",o.className="kalotyp-resize-input",o.min=String(t.min),o.max=String(t.max),o.step=String(t.step),o.value=String(t.value),o.inputMode="numeric",o.setAttribute("aria-label",t.label),o.addEventListener("change",()=>{const i=o.valueAsNumber;Number.isFinite(i)&&t.onChange(i)}),e.appendChild(n),e.appendChild(o),{wrapper:e,input:o}}function Ln(t){return B(t?"lockClosed":"lockOpen")}function da(t){return{id:"resize",init:()=>Yo(),mount(e,n,o){const i=la({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"resize"})});return{destroy:()=>i.destroy()}},bake:Jo}}function Tn(t){const{canvas:e,sourceBitmap:n}=t;let o;function i(s,c){if(s<=0||c<=0)return;const l=Fn(e);if(!l)return;e.width=s,e.height=c,l.imageSmoothingEnabled=!0,l.imageSmoothingQuality="high",l.clearRect(0,0,s,c),l.drawImage(n,0,0,s,c);const u=l.getImageData(0,0,s,c);o={baseline:new Uint8ClampedArray(u.data),scratch:u.data,blurred:void 0,width:s,height:c}}function r(s){if(!o)return;const c=Fn(e);if(!c)return;if(Gt(s)){const d=new ImageData(new Uint8ClampedArray(o.baseline),o.width,o.height);c.putImageData(d,0,0);return}const l=je(s);if(Qe(o.baseline,o.scratch,l,s),s.clarity!==0){if(!o.blurred){const d=new Uint8ClampedArray(o.baseline.length),h=new Uint8ClampedArray(o.baseline.length);Ze(o.baseline,d,h,o.width,o.height),o.blurred=h}Je(o.scratch,o.blurred,s.clarity)}const u=new ImageData(o.scratch,o.width,o.height);c.putImageData(u,0,0)}function a(){o=void 0}return{paint:r,rebuild:i,dispose:a}}function Fn(t){return t.getContext("2d",{willReadFrequently:!0})}function ha(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??fa,s=yt();e.appendChild(s.container);const c=Tn({canvas:s.canvas,sourceBitmap:o.bitmap}),l=pa({onSliderInput:(y,C)=>i.set(Ve(i.get(),y,C)),onSliderCommit:()=>a(),onNumberCommit:(y,C)=>{i.set(Ve(i.get(),y,C)),a()},onRowReset:y=>{i.set(ei(i.get(),y)),a()},onResetAll:()=>{i.update(()=>ni()),a()}});n.appendChild(l.container);let u={width:0,height:0};function d(){const y=Ht(s.container,{width:o.width,height:o.height},r);if(!y)return;const C=y.viewport.displayRect,E=Math.max(1,window.devicePixelRatio||1),S=Math.max(1,Math.round(C.width*E)),M=Math.max(1,Math.round(C.height*E));s.canvas.style.width=`${C.width}px`,s.canvas.style.height=`${C.height}px`,s.canvas.style.position="absolute",s.canvas.style.left=`${C.x}px`,s.canvas.style.top=`${C.y}px`,!(r?.getPinching()??!1)&&(u.width!==S||u.height!==M)&&(u={width:S,height:M},c.rebuild(S,M)),c.paint(i.get())}function h(y){for(const C of Ke){const E=l.rows.get(C.key);if(!E)continue;const S=y[C.key];E.slider.valueAsNumber!==S&&(E.slider.valueAsNumber=S),Number.parseFloat(E.input.value||"0")!==S&&(E.input.value=String(S))}}h(i.get()),d();const f=new ResizeObserver(()=>d());f.observe(s.container);let m=!1;const g=r?.subscribe(()=>{m||(m=!0,requestAnimationFrame(()=>{m=!1,d()}))});let p=!1;const w=i.subscribe(y=>{h(y),!p&&(p=!0,requestAnimationFrame(()=>{p=!1,c.paint(i.get())}))});return{destroy(){w(),g?.(),f.disconnect(),c.dispose(),s.container.remove(),l.container.remove()}}}function pa(t){const e=document.createElement("div");e.className="kalotyp-finetune-panel",e.setAttribute("role","group"),e.setAttribute("aria-label","Finetune adjustments");const n=new Map;for(const i of Ke){const r=ma(i.key,i.label,t);n.set(i.key,r),e.appendChild(r.row)}const o=document.createElement("button");return o.type="button",o.className="kalotyp-finetune-reset-all",o.textContent="Reset all",o.title="Reset every adjustment to 0",o.addEventListener("click",t.onResetAll),e.appendChild(o),{container:e,rows:n,resetAllButton:o}}function ma(t,e,n){const o=document.createElement("div");o.className="kalotyp-finetune-row",o.dataset.adjustment=t;const i=document.createElement("label");i.className="kalotyp-finetune-label",i.textContent=e;const r=document.createElement("input");r.type="range",r.className="kalotyp-finetune-slider",r.min=String(Mt),r.max=String(It),r.step=String(Rt),r.value="0",r.setAttribute("aria-label",`${e} adjustment`),r.addEventListener("input",()=>n.onSliderInput(t,r.valueAsNumber)),r.addEventListener("change",()=>n.onSliderCommit());const a=document.createElement("input");a.type="number",a.className="kalotyp-finetune-input",a.min=String(Mt),a.max=String(It),a.step=String(Rt),a.value="0",a.inputMode="numeric",a.setAttribute("aria-label",`${e} value`),a.addEventListener("change",()=>{const c=a.valueAsNumber;Number.isFinite(c)&&n.onNumberCommit(t,c)});const s=document.createElement("button");return s.type="button",s.className="kalotyp-finetune-row-reset",s.setAttribute("aria-label",`Reset ${e}`),s.title=`Reset ${e}`,s.textContent="↺",s.addEventListener("click",()=>n.onRowReset(t)),o.appendChild(i),o.appendChild(r),o.appendChild(a),o.appendChild(s),{row:o,slider:r,input:a,resetButton:s}}function fa(){}function ga(t){return{id:"finetune",init:()=>ti(),mount(e,n,o){const i=ha({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"finetune"})});return{destroy:()=>i.destroy()}},bake:ri}}const Pn=80,$n=60;function ya(t){if(t.width<=0||t.height<=0)return{width:Pn,height:$n};const e=Pn/t.width,n=$n/t.height,o=Math.min(e,n),i=Math.max(1,Math.floor(t.width*o)),r=Math.max(1,Math.floor(t.height*o));return{width:i,height:r}}function ba(t){const{source:e,dims:n,dpr:o}=t,i=Math.max(1,Math.round(n.width*o)),r=Math.max(1,Math.round(n.height*o)),a=document.createElement("canvas");a.width=i,a.height=r;const s=a.getContext("2d",{willReadFrequently:!0});if(!s)return{get:()=>wa(n,o),dispose:()=>{}};s.imageSmoothingEnabled=!0,s.imageSmoothingQuality="high",s.drawImage(e,0,0,i,r);const c=s.getImageData(0,0,i,r),l={data:new Uint8ClampedArray(c.data),width:i,height:r},u=new Map;function d(h){const f=document.createElement("canvas");f.width=i,f.height=r,f.style.width=`${n.width}px`,f.style.height=`${n.height}px`;const m=f.getContext("2d");if(!m)return f;const g={data:new Uint8ClampedArray(l.data.length),width:i,height:r};return Kt(h.state,l,g),m.putImageData(new ImageData(g.data,i,r),0,0),f}return{get(h){const f=u.get(h.id);if(f)return f;const m=d(h);return u.set(h.id,m),m},dispose(){u.clear()}}}function wa(t,e){const n=document.createElement("canvas");return n.width=Math.max(1,Math.round(t.width*e)),n.height=Math.max(1,Math.round(t.height*e)),n.style.width=`${t.width}px`,n.style.height=`${t.height}px`,n}function Ca(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??va,s=yt();e.appendChild(s.container);const c=Tn({canvas:s.canvas,sourceBitmap:o.bitmap}),l=ya({width:o.width,height:o.height}),u=Math.max(1,window.devicePixelRatio||1),d=ba({source:o.bitmap,dims:l,dpr:u}),h=xa({presets:Vt,thumbnailCache:d,dims:l,onPresetClick:S=>{const M=i.get();if(jt(M)?.id===S.id&&S.id!=="none"){i.update(()=>pt),a();return}i.update(()=>S.state),a()}});n.appendChild(h.container);let f={width:0,height:0};function m(){const S=Ht(s.container,{width:o.width,height:o.height},r);if(!S)return;const M=S.viewport.displayRect,H=Math.max(1,Math.round(M.width*u)),R=Math.max(1,Math.round(M.height*u));s.canvas.style.width=`${M.width}px`,s.canvas.style.height=`${M.height}px`,s.canvas.style.position="absolute",s.canvas.style.left=`${M.x}px`,s.canvas.style.top=`${M.y}px`,!(r?.getPinching()??!1)&&(f.width!==H||f.height!==R)&&(f={width:H,height:R},c.rebuild(H,R)),c.paint(i.get())}function g(S){const M=jt(S)?.id;h.setActive(M)}g(i.get()),m();const p=new ResizeObserver(()=>m());p.observe(s.container);let w=!1;const y=r?.subscribe(()=>{w||(w=!0,requestAnimationFrame(()=>{w=!1,m()}))});let C=!1;const E=i.subscribe(S=>{g(S),!C&&(C=!0,requestAnimationFrame(()=>{C=!1,c.paint(i.get())}))});return{destroy(){E(),y?.(),p.disconnect(),c.dispose(),d.dispose(),s.container.remove(),h.container.remove()}}}function xa(t){const e=document.createElement("div");e.className="kalotyp-filter-panel",e.setAttribute("role","radiogroup"),e.setAttribute("aria-label","Filter presets");const n=document.createElement("div");n.className="kalotyp-filter-strip",e.appendChild(n);const o=new Map;for(const i of t.presets){const r=document.createElement("button");r.type="button",r.className="kalotyp-filter-thumb",r.dataset.presetId=i.id,r.setAttribute("role","radio"),r.setAttribute("aria-checked","false"),r.setAttribute("aria-label",`${i.label} filter`),r.title=i.label;const a=document.createElement("span");a.className="kalotyp-filter-thumb-image",a.style.width=`${t.dims.width}px`,a.style.height=`${t.dims.height}px`;const s=t.thumbnailCache.get(i);s.classList.add("kalotyp-filter-thumb-canvas"),a.appendChild(s);const c=document.createElement("span");c.className="kalotyp-filter-thumb-check",c.setAttribute("aria-hidden","true"),c.innerHTML="✓",a.appendChild(c);const l=document.createElement("span");l.className="kalotyp-filter-thumb-label",l.textContent=i.label,r.appendChild(a),r.appendChild(l),r.addEventListener("click",()=>t.onPresetClick(i)),n.appendChild(r),o.set(i.id,r)}return{container:e,setActive(i){for(const[r,a]of o){const s=r===i;a.setAttribute("aria-checked",s?"true":"false"),a.classList.toggle("kalotyp-filter-thumb--active",s)}}}}function va(){}function ka(t){return{id:"filter",init:()=>pt,mount(e,n,o){const i=Ca({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"filter"})});return{destroy:()=>i.destroy()}},bake:Sa}}async function Sa(t,e){return e}const Ea=[{id:"x",label:"Left"},{id:"y",label:"Top"},{id:"width",label:"Width",min:1},{id:"height",label:"Height",min:1}],Aa=[{id:"x1",label:"Start X"},{id:"y1",label:"Start Y"},{id:"x2",label:"End X"},{id:"y2",label:"End Y"}],Ma=[{id:"x",label:"X"},{id:"y",label:"Y"}];function Ia(t){const e=document.createElement("div");e.className="kalotyp-annotate-coords",e.setAttribute("role","group"),e.setAttribute("aria-label","Selected annotation position"),e.hidden=!0;let n=null,o=null;const i=new Map;function r(l){e.replaceChildren(),i.clear();const u=Ra(l);for(const d of u){const h=document.createElement("label");h.className="kalotyp-annotate-coords-field";const f=document.createElement("span");f.className="kalotyp-annotate-coords-label",f.textContent=d.label;const m=document.createElement("input");m.type="number",m.className="kalotyp-annotate-coords-input",m.dataset.field=d.id,m.step="1",m.inputMode="numeric",d.min!==void 0&&(m.min=String(d.min)),d.max!==void 0&&(m.max=String(d.max)),m.setAttribute("aria-label",`${d.label} (pixels)`),m.addEventListener("change",s),h.appendChild(f),h.appendChild(m),e.appendChild(h),i.set(d.id,m)}o=l}function a(l){const u=(d,h)=>{const f=i.get(d);if(!f)return;const m=String(Math.round(h));document.activeElement!==f&&f.value!==m&&(f.value=m)};switch(l.kind){case"rect":case"ellipse":{u("x",l.x),u("y",l.y),u("width",l.width),u("height",l.height);return}case"arrow":{u("x1",l.x1),u("y1",l.y1),u("x2",l.x2),u("y2",l.y2);return}case"text":{u("x",l.x),u("y",l.y);return}default:return}}function s(){if(!n||!o)return;const l=c(n);if(!l)return;const u=Na(n,l);u!==n&&(n=u,t.onShapeChanged(u))}function c(l){const u=d=>{const h=i.get(d);return h?h.valueAsNumber:Number.NaN};switch(l.kind){case"rect":case"ellipse":{const d=Math.round(u("x")),h=Math.round(u("y")),f=Math.round(u("width")),m=Math.round(u("height"));return[d,h,f,m].every(Number.isFinite)?{kind:l.kind,x:d,y:h,width:f,height:m}:null}case"arrow":{const d=Math.round(u("x1")),h=Math.round(u("y1")),f=Math.round(u("x2")),m=Math.round(u("y2"));return[d,h,f,m].every(Number.isFinite)?{kind:"arrow",x1:d,y1:h,x2:f,y2:m}:null}case"text":{const d=Math.round(u("x")),h=Math.round(u("y"));return[d,h].every(Number.isFinite)?{kind:"text",x:d,y:h}:null}default:return null}}return{container:e,updateForShape(l){if(!l){n=null,o=null,e.hidden=!0,e.replaceChildren(),i.clear();return}if(l.kind==="freehand"||l.kind==="highlight"){n=l,o=null,e.hidden=!0,e.replaceChildren(),i.clear();return}n=l,o!==l.kind&&r(l.kind),a(l),e.hidden=!1},destroy(){e.replaceChildren(),i.clear(),e.remove()}}}function Ra(t){switch(t){case"rect":case"ellipse":return Ea;case"arrow":return Aa;case"text":return Ma}}function Na(t,e){switch(t.kind){case"rect":return e.kind!=="rect"?t:{...t,x:e.x,y:e.y,width:e.width,height:e.height};case"ellipse":return e.kind!=="ellipse"?t:{...t,x:e.x,y:e.y,width:e.width,height:e.height};case"arrow":return e.kind!=="arrow"?t:{...t,x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2};case"text":return e.kind!=="text"?t:{...t,x:e.x,y:e.y};default:return t}}const La=[{id:"select",label:"Select",icon:B("select",{fill:"currentColor","stroke-width":1})},{id:"text",label:"Text",icon:B("text")},{id:"rect",label:"Rectangle",icon:B("rect")},{id:"ellipse",label:"Ellipse",icon:B("ellipse")},{id:"arrow",label:"Arrow",icon:B("arrow")},{id:"freehand",label:"Freehand",icon:B("freehand")},{id:"highlight",label:"Highlight",icon:B("highlight")}],Ta=["#ff3b30","#ffcc00","#34c759","#007aff","#ffffff","#000000"];function Fa(t){const e=document.createElement("div");e.className="kalotyp-annotate-panel",e.setAttribute("role","group"),e.setAttribute("aria-label","Annotate");const n=document.createElement("div");n.className="kalotyp-annotate-toolbar",n.setAttribute("role","toolbar"),n.setAttribute("aria-label","Annotation tools");const o=new Map;for(const p of La){const w=document.createElement("button");w.type="button",w.className="kalotyp-annotate-tool",w.dataset.tool=p.id,w.setAttribute("aria-label",p.label),w.title=p.label,w.setAttribute("aria-pressed",p.id===t.initialTool?"true":"false"),w.innerHTML=p.icon,w.addEventListener("click",()=>t.onSelectTool(p.id)),n.appendChild(w),o.set(p.id,w)}const i=document.createElement("div");i.className="kalotyp-annotate-style-row";const r=[],a=document.createElement("div");a.className="kalotyp-annotate-swatches",a.setAttribute("role","radiogroup"),a.setAttribute("aria-label","Color");for(const p of Ta){const w=document.createElement("button");w.type="button",w.className="kalotyp-annotate-swatch",w.setAttribute("role","radio"),w.setAttribute("aria-label",`Use color ${p}`),w.dataset.color=p,w.style.setProperty("--kalotyp-swatch",p),w.addEventListener("click",()=>t.onColorChange(p)),a.appendChild(w),r.push(w)}let s=Hn(t.initialStyle.color);const c=document.createElement("input");c.type="text",c.className="kalotyp-annotate-hex",c.value=s,c.maxLength=7,c.spellcheck=!1,c.autocomplete="off",c.setAttribute("aria-label","Color hex code"),c.setAttribute("placeholder","#000000"),c.style.setProperty("--kalotyp-hex-swatch",s),c.addEventListener("change",()=>{const p=c.value.trim(),w=Pa(p);w?(c.value=w,s=w,c.style.setProperty("--kalotyp-hex-swatch",w),t.onColorChange(w)):c.value=s});const l=document.createElement("label");l.className="kalotyp-annotate-stroke-label",l.textContent="Width";const u=document.createElement("input");u.type="range",u.className="kalotyp-annotate-stroke",u.min="1",u.max="40",u.step="1",u.value=String(t.initialStyle.strokeWidth),u.setAttribute("aria-label","Stroke width"),u.addEventListener("change",()=>t.onStrokeWidthChange(u.valueAsNumber));const d=document.createElement("button");d.type="button",d.className="kalotyp-annotate-delete",d.innerHTML=`${B("delete")}<span>Delete</span>`,d.setAttribute("aria-label","Delete selected annotation"),d.title="Delete (Del)",d.disabled=!t.canDelete,d.addEventListener("click",()=>t.onDeleteSelected());const h=document.createElement("button");h.type="button",h.className="kalotyp-annotate-insert",h.innerHTML=`${B("plus")}<span>Insert at centre</span>`,h.setAttribute("aria-label","Insert annotation at image centre"),h.title="Insert at centre",h.disabled=!Dn(t.initialTool),h.addEventListener("click",()=>t.onInsertAtCenter()),i.appendChild(a),i.appendChild(c),i.appendChild(l),i.appendChild(u),i.appendChild(h),i.appendChild(d),e.appendChild(n),e.appendChild(i),e.appendChild(t.coordInputs);function f(p){for(const[w,y]of o)y.setAttribute("aria-pressed",w===p?"true":"false");h.disabled=!Dn(p)}function m(p){const w=Hn(p.color);c.value.toLowerCase()!==w.toLowerCase()&&(c.value=w),s=w,c.style.setProperty("--kalotyp-hex-swatch",w),u.valueAsNumber!==p.strokeWidth&&(u.value=String(p.strokeWidth));for(const y of r){const C=y.dataset.color?.toLowerCase()===p.color.toLowerCase();y.setAttribute("aria-checked",C?"true":"false")}}function g(p){d.disabled=!p}return m(t.initialStyle),{container:e,toolButtons:o,hexInput:c,colorSwatches:r,strokeRange:u,deleteButton:d,insertButton:h,setActiveTool:f,setStyle:m,setCanDelete:g}}function Dn(t){return t==="select"?!1:rn(t)}function Hn(t){if(/^#[0-9a-fA-F]{6}$/.test(t))return t;if(/^#[0-9a-fA-F]{3}$/.test(t)){const e=t[1],n=t[2],o=t[3];return`#${e}${e}${n}${n}${o}${o}`}return"#000000"}function Pa(t){const e=t.startsWith("#")?t.slice(1):t;if(/^[0-9a-fA-F]{6}$/.test(e))return`#${e.toLowerCase()}`;if(/^[0-9a-fA-F]{3}$/.test(e)){const n=e[0],o=e[1],i=e[2];return`#${n}${n}${o}${o}${i}${i}`.toLowerCase()}return null}function Ot(t,e){const n=o=>{if(o.button!==0)return;const i=e(o);if(!i)return;o.preventDefault(),o.stopPropagation();try{t.setPointerCapture(o.pointerId)}catch{}let r,a=!1,s=o.shiftKey;const c=()=>{if(a=!1,!r)return;const g=r;r=void 0,i.onMove(g)},l=g=>{r=g,a||(a=!0,requestAnimationFrame(c))},u=g=>{g.pointerId===o.pointerId&&(s=g.shiftKey,l({clientX:g.clientX,clientY:g.clientY,shiftKey:g.shiftKey}))},d=g=>{if(g.key!=="Shift"||g.shiftKey===s)return;s=g.shiftKey;const p=r,w=p?.clientX??o.clientX,y=p?.clientY??o.clientY;l({clientX:w,clientY:y,shiftKey:g.shiftKey})},h=g=>{t.removeEventListener("pointermove",u),t.removeEventListener("pointerup",f),t.removeEventListener("pointercancel",m),window.removeEventListener("keydown",d),window.removeEventListener("keyup",d);try{t.releasePointerCapture(o.pointerId)}catch{}if(r){const p=r;r=void 0,i.onMove(p)}g?i.onCommit():i.onCancel()},f=g=>{g.pointerId===o.pointerId&&h(!0)},m=g=>{g.pointerId===o.pointerId&&h(!1)};t.addEventListener("pointermove",u),t.addEventListener("pointerup",f),t.addEventListener("pointercancel",m),window.addEventListener("keydown",d),window.addEventListener("keyup",d)};return t.addEventListener("pointerdown",n),()=>t.removeEventListener("pointerdown",n)}function On(t,e,n){const o=t.getBoundingClientRect();return{x:e-o.left,y:n-o.top}}function zt(t,e,n){const o=Math.max(1,window.devicePixelRatio||1),i=Math.max(1,Math.round(e*o)),r=Math.max(1,Math.round(n*o));t.width!==i&&(t.width=i),t.height!==r&&(t.height=r),t.style.width=`${e}px`,t.style.height=`${n}px`;const a=t.getContext("2d");return a?(a.setTransform(o,0,0,o,0,0),a.clearRect(0,0,e,n),a):null}function $a(t,e,n,o,i){const r=zt(t,n,o);r&&(r.imageSmoothingEnabled=!0,r.imageSmoothingQuality="high",r.drawImage(e.bitmap,i.displayRect.x,i.displayRect.y,i.displayRect.width,i.displayRect.height))}function zn(t,e,n,o,i){const r=zt(t,n,o);if(r&&e.length!==0){r.save(),r.translate(i.displayRect.x,i.displayRect.y),r.scale(i.scale,i.scale);for(const a of e)te(r,a);r.restore()}}function Bn(t,e,n,o,i){const r=zt(t,n,o);r&&e!==null&&(r.save(),r.translate(i.displayRect.x,i.displayRect.y),r.scale(i.scale,i.scale),te(r,e),r.restore())}function Da(t,e,n,o,i){const r=zt(t,n,o);if(!r||!e)return;const a=i.displayRect.x+e.x*i.scale,s=i.displayRect.y+e.y*i.scale;let c=e.width*i.scale,l=e.height*i.scale,u=a,d=s;c<0&&(u=a+c,c=-c),l<0&&(d=s+l,l=-l),r.save(),r.fillStyle="rgba(99, 102, 241, 0.12)",r.fillRect(u,d,c,l),r.strokeStyle="rgba(99, 102, 241, 0.95)",r.lineWidth=1,r.setLineDash([4,3]),r.strokeRect(u+.5,d+.5,c-1,l-1),r.restore()}function Ha(t){const{host:e,toolContext:n}=t,o=new Map,i=[];for(const s of Tt){const c=document.createElement("button");c.type="button",c.className="kalotyp-annotate-handle",c.dataset.direction=s,c.setAttribute("aria-label",Ba(s)),c.tabIndex=-1,c.style.display="none",o.set(s,c),e.appendChild(c),i.push(Ot(c,l=>Oa(n,s)))}function r(s,c){if(!s){_n(o);return}if(s.kind==="arrow"){_n(o);const d=o.get("tl"),h=o.get("br");d&&ce(d,se({x:s.x1,y:s.y1},c)),h&&ce(h,se({x:s.x2,y:s.y2},c));return}const l=ft(s),u=mi(l);for(const d of Tt){const h=o.get(d);h&&ce(h,se(u[d],c))}}function a(){for(const s of i)s();for(const[,s]of o)s.remove();o.clear()}return{update:r,destroy:a}}function se(t,e){return{x:e.displayRect.x+t.x*e.scale,y:e.displayRect.y+t.y*e.scale}}function ce(t,e){t.style.display="",t.style.left=`${e.x}px`,t.style.top=`${e.y}px`}function _n(t){for(const[,e]of t)e.style.display="none"}function Oa(t,e,n){const o=t.store.get(),i=o.shapes.find(a=>a.id===o.selectedId);if(!i)return null;const r=i;return{onMove(a){const s=t.toImageSpace(a),c=za(r,e,s);c&&t.store.update(l=>nt(l,c))},onCommit(){t.commit()},onCancel(){t.store.update(a=>nt(a,r))}}}function za(t,e,n){switch(t.kind){case"rect":case"ellipse":{const o={x:t.x,y:t.y,width:t.width,height:t.height},i=Jt(o,e,n);return{...t,x:i.x,y:i.y,width:i.width,height:i.height}}case"arrow":{const o=t;return e==="tl"?{...o,x1:n.x,y1:n.y}:e==="br"?{...o,x2:n.x,y2:n.y}:t}case"text":{if(e!=="br")return t;const o=n.x-t.x,i=n.y-t.y,r=Math.max(8,Math.round(Math.max(o,i)*.6));return{...t,fontSize:r}}case"freehand":case"highlight":{const o=ft(t);if(o.width===0||o.height===0)return t;const i=Jt(o,e,n),r=i.width/o.width,a=i.height/o.height;if(!Number.isFinite(r)||!Number.isFinite(a))return t;const s=t.points.map(c=>({x:i.x+(c.x-o.x)*r,y:i.y+(c.y-o.y)*a}));return{...t,points:s}}}}function Ba(t){switch(t){case"tl":return"Resize from top-left";case"tr":return"Resize from top-right";case"bl":return"Resize from bottom-left";case"br":return"Resize from bottom-right";case"t":return"Resize from top";case"r":return"Resize from right";case"b":return"Resize from bottom";case"l":return"Resize from left"}}function Z(t){return t.selectedId===null?null:t.shapes.find(e=>e.id===t.selectedId)??null}function _a(){const t=document.createElement("div");t.className="kalotyp-annotate-stage";const e=document.createElement("canvas");e.className="kalotyp-annotate-image",e.setAttribute("aria-hidden","true");const n=document.createElement("canvas");n.className="kalotyp-annotate-shapes",n.setAttribute("aria-hidden","true");const o=document.createElement("canvas");o.className="kalotyp-annotate-live",o.setAttribute("aria-hidden","true");const i=document.createElement("div");i.className="kalotyp-annotate-hit",i.setAttribute("role","presentation");const r=document.createElement("div");r.className="kalotyp-annotate-handles",r.setAttribute("role","group"),r.setAttribute("aria-label","Selected annotation");const a=document.createElement("div");return a.className="kalotyp-annotate-text-overlay",t.appendChild(e),t.appendChild(n),t.appendChild(o),t.appendChild(i),t.appendChild(r),t.appendChild(a),{container:t,imageCanvas:e,shapesCanvas:n,liveCanvas:o,hitArea:i,handlesLayer:r,textOverlay:a}}function Wa(t){const e=document.createElement("div");e.className="kalotyp-annotate-text-editor",e.setAttribute("contenteditable","true"),e.setAttribute("role","textbox"),e.setAttribute("aria-label","Annotation text"),e.spellcheck=!1,e.style.display="none",t.host.appendChild(e);let n=null;const o=()=>{t.onInput(e.innerText)},i=a=>{if(a.key==="Enter"&&!a.shiftKey){a.preventDefault(),a.stopPropagation(),t.onCommit();return}a.key==="Escape"&&(a.preventDefault(),a.stopPropagation(),t.onCancel())},r=a=>{n!==null&&(e.contains(a.target)||t.onCommit())};return e.addEventListener("input",o),e.addEventListener("keydown",i),document.addEventListener("pointerdown",r,!0),{open(a,s,c){n=a;const l=s.displayRect.x+a.x*s.scale,u=s.displayRect.y+a.y*s.scale;e.style.display="",e.style.left=`${l}px`,e.style.top=`${u}px`,e.style.color=a.color,e.style.font=`${a.fontSize*s.scale}px ${ln}`,e.style.textAlign=a.textAlign,e.style.transformOrigin=qa(a.textAlign);const d=Math.max(100,s.displayRect.x+s.displayRect.width-l-8);e.style.maxWidth=`${d}px`,e.innerText=a.text,requestAnimationFrame(()=>{e.focus();const h=document.createRange();h.selectNodeContents(e),h.collapse(!1);const f=window.getSelection();f?.removeAllRanges(),f?.addRange(h)})},close(){n=null,e.style.display="none",e.blur()},destroy(){e.removeEventListener("input",o),e.removeEventListener("keydown",i),document.removeEventListener("pointerdown",r,!0),e.remove()}}}function qa(t){switch(t){case"left":return"top left";case"center":return"top center";case"right":return"top right"}}function Wn(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.max(Math.abs(n),Math.abs(o)),r=n===0?1:Math.sign(n),a=o===0?1:Math.sign(o);return{x:t.x+r*i,y:t.y+a*i}}function Ua(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.sqrt(n*n+o*o);if(i===0)return t;const r=Math.atan2(o,n),a=Math.round(r/(Math.PI/4))*(Math.PI/4);return{x:t.x+Math.cos(a)*i,y:t.y+Math.sin(a)*i}}function Xa(t,e){const n=e.x-t.x,o=e.y-t.y;return Math.abs(n)>=Math.abs(o)?{x:e.x,y:t.y}:{x:t.x,y:e.y}}function Ya(t,e){const n=t.toImageSpace(e),o=t.store.get(),{id:i,nextShapeNumber:r}=at(o);let a=n;return{onMove(s){const c=t.toImageSpace(s);a=s.shiftKey?Wn(n,c):c;const l={id:i,kind:"rect",x:n.x,y:n.y,width:a.x-n.x,height:a.y-n.y,strokeColor:o.currentStyle.color,strokeWidth:o.currentStyle.strokeWidth,fillColor:o.currentStyle.fillColor};t.setLiveShape(l)},onCommit(){const s=nn({x:n.x,y:n.y,width:a.x-n.x,height:a.y-n.y});if(t.setLiveShape(null),s.width<2||s.height<2)return;const c={id:i,kind:"rect",...s,strokeColor:o.currentStyle.color,strokeWidth:o.currentStyle.strokeWidth,fillColor:o.currentStyle.fillColor};t.store.update(l=>({...st(l,c),nextShapeNumber:r})),t.commit()},onCancel(){t.setLiveShape(null)}}}function Ga(t,e){const n=t.toImageSpace(e),o=t.store.get(),{id:i,nextShapeNumber:r}=at(o);let a=n;return{onMove(s){const c=t.toImageSpace(s);a=s.shiftKey?Wn(n,c):c;const l={id:i,kind:"ellipse",x:n.x,y:n.y,width:a.x-n.x,height:a.y-n.y,strokeColor:o.currentStyle.color,strokeWidth:o.currentStyle.strokeWidth,fillColor:o.currentStyle.fillColor};t.setLiveShape(l)},onCommit(){const s=nn({x:n.x,y:n.y,width:a.x-n.x,height:a.y-n.y});if(t.setLiveShape(null),s.width<2||s.height<2)return;const c={id:i,kind:"ellipse",...s,strokeColor:o.currentStyle.color,strokeWidth:o.currentStyle.strokeWidth,fillColor:o.currentStyle.fillColor};t.store.update(l=>({...st(l,c),nextShapeNumber:r})),t.commit()},onCancel(){t.setLiveShape(null)}}}function Ka(t,e){const n=t.toImageSpace(e),o=t.store.get(),{id:i,nextShapeNumber:r}=at(o);let a=n;return{onMove(s){const c=t.toImageSpace(s);a=s.shiftKey?Ua(n,c):c;const l={id:i,kind:"arrow",x1:n.x,y1:n.y,x2:a.x,y2:a.y,color:o.currentStyle.color,strokeWidth:o.currentStyle.strokeWidth};t.setLiveShape(l)},onCommit(){t.setLiveShape(null);const s=a.x-n.x,c=a.y-n.y;if(s*s+c*c<16)return;const l={id:i,kind:"arrow",x1:n.x,y1:n.y,x2:a.x,y2:a.y,color:o.currentStyle.color,strokeWidth:o.currentStyle.strokeWidth};t.store.update(u=>({...st(u,l),nextShapeNumber:r})),t.commit()},onCancel(){t.setLiveShape(null)}}}function qn(t,e,n){const o=t.toImageSpace(e),i=t.store.get(),{id:r,nextShapeNumber:a}=at(i),s=[o];let c=!1,l=o;const u=n.kind==="highlight",d=u?si:i.currentStyle.color,h=u?ci:i.currentStyle.strokeWidth;function f(m){const g={id:r,kind:n.kind,points:m,color:d,strokeWidth:h};t.setLiveShape(g)}return{onMove(m){const g=t.toImageSpace(m);c=m.shiftKey,m.shiftKey?(l=Xa(o,g),f([o,l])):(s.push(g),f(s))},onCommit(){t.setLiveShape(null);const m=c?[o,l]:wi(s);if(m.length<2)return;if(m.length===2){const p=m[0],w=m[1];if(p&&w){const y=w.x-p.x,C=w.y-p.y;if(y*y+C*C<4)return}}const g={id:r,kind:n.kind,points:m,color:d,strokeWidth:h};t.store.update(p=>({...st(p,g),nextShapeNumber:a})),t.commit()},onCancel(){t.setLiveShape(null)}}}function Va(t,e,n,o,i,r){const a=t.toImageSpace(e);return t.store.update(s=>mt(s,n)),{onMove(s){const c=t.toImageSpace(s),l=i(o,c.x-a.x,c.y-a.y);r(l)},onCommit(){t.commit()},onCancel(){r(o)}}}const Un=32;function ja(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??(()=>{}),s=t.onAnnounce??(()=>{}),c=_a();e.appendChild(c.container);let l=j({width:1,height:1,padding:Un},{width:o.width,height:o.height}),u=null,d=null;function h(){const b=c.container.getBoundingClientRect(),k={width:b.width,height:b.height,padding:Un},L={width:o.width,height:o.height};l=r?r.computeViewport(k,L):j(k,L)}function f(){const b=c.container.getBoundingClientRect();b.width<=0||b.height<=0||($a(c.imageCanvas,o,b.width,b.height,l),zn(c.shapesCanvas,i.get().shapes,b.width,b.height,l),Bn(c.liveCanvas,u,b.width,b.height,l),E.update(Z(i.get()),l))}function m(){const b=c.container.getBoundingClientRect();b.width<=0||b.height<=0||zn(c.shapesCanvas,i.get().shapes,b.width,b.height,l)}function g(){const b=c.container.getBoundingClientRect();b.width<=0||b.height<=0||(d!==null?Da(c.liveCanvas,d,b.width,b.height,l):Bn(c.liveCanvas,u,b.width,b.height,l))}function p(b){u=b,d=null,g()}function w(b){d=b,u=null,g()}function y(b){const k=On(c.container,b.clientX,b.clientY);return Wt(k,l)}const C={store:i,toImageSpace:y,setLiveShape:p,commit:a},E=Ha({host:c.handlesLayer,toolContext:C}),S=Wa({host:c.textOverlay,onInput:b=>{const k=Z(i.get());!k||k.kind!=="text"||i.update(L=>nt(L,{...k,text:b}))},onCommit:()=>{const b=Z(i.get());S.close(),b?.kind==="text"&&b.text.trim().length===0&&i.update(k=>Nt(k,b.id)),a(),i.update(k=>Qt(k,"select"))},onCancel:()=>{const b=Z(i.get());S.close(),b?.kind==="text"&&b.text.length===0&&i.update(k=>Nt(k,b.id)),i.update(k=>Qt(k,"select"))}}),M=Ot(c.hitArea,b=>{const k=i.get();switch(k.activeTool){case"select":return H(k,b);case"rect":return Ya(C,b);case"ellipse":return Ga(C,b);case"arrow":return Ka(C,b);case"freehand":return qn(C,b,{kind:"freehand"});case"highlight":return qn(C,b,{kind:"highlight"});case"text":return A(b),null;default:return null}});function H(b,k){const L=y(k),P=yi(b.shapes,L);return P?(b.selectedId!==P.id&&i.update(v=>mt(v,P.id)),Va(C,k,P.id,P,on,v=>i.update(I=>nt(I,v)))):R(k)}function R(b){const k=y(b);let L=k;return{onMove(P){L=y(P),w({x:k.x,y:k.y,width:L.x-k.x,height:L.y-k.y})},onCommit(){w(null);const P=L.x-k.x,v=L.y-k.y;if(Math.abs(P)<2&&Math.abs(v)<2){i.update(q=>mt(q,null));return}const I=Za({x:k.x,y:k.y,width:P,height:v}),z=ts(i.get().shapes,I);i.update(q=>mt(q,z?.id??null))},onCancel(){w(null)}}}function A(b){const k=i.get(),L=y(b),{id:P,nextShapeNumber:v}=at(k),I={id:P,kind:"text",x:L.x,y:L.y,text:"",fontSize:k.currentStyle.fontSize??tn,color:k.currentStyle.color,textAlign:"left"};i.update(z=>({...st(z,I),nextShapeNumber:v})),S.open(I,l,o)}function T(){const b=i.get(),k=b.activeTool;if(k==="select"||!rn(k))return;const{id:L,nextShapeNumber:P}=at(b),v=pi(k,{imageSize:{width:o.width,height:o.height},style:b.currentStyle,id:L});if(i.update(I=>({...st(I,v),nextShapeNumber:P})),v.kind==="text"){S.open(v,l,o),s("Text annotation placed at centre. Type to enter text.");return}s(`${os(v.kind)} placed at centre. Use arrow keys to nudge, or edit coordinates below.`),requestAnimationFrame(()=>{const I=$.container.querySelector(".kalotyp-annotate-coords-input");I?.focus(),I?.select()})}const $=Ia({onShapeChanged:b=>{i.update(k=>nt(k,b)),a()}}),O=i.get(),W=Fa({initialTool:O.activeTool,initialStyle:O.currentStyle,canDelete:O.selectedId!==null,coordInputs:$.container,onSelectTool:b=>i.update(k=>Qt(k,b)),onColorChange:b=>{i.update(k=>{let L=en(k,{color:b});const P=Z(k);return P&&(L=nt(L,Qa(P,b))),L}),a()},onStrokeWidthChange:b=>{i.update(k=>{let L=en(k,{strokeWidth:b});const P=Z(k);return P&&(L=nt(L,Ja(P,b))),L}),a()},onDeleteSelected:()=>{const b=i.get().selectedId;b&&(i.update(k=>Nt(k,b)),a())},onInsertAtCenter:()=>T()});n.appendChild(W.container),h(),f();const U=new ResizeObserver(()=>{h(),f()});U.observe(c.container);let _=!1;const D=r?.subscribe(()=>{_||(_=!0,requestAnimationFrame(()=>{_=!1,h(),f()}))});let G=i.get().shapes,V=i.get().selectedId,Y=i.get().activeTool,x=i.get().currentStyle;const F=i.subscribe(b=>{const k=b.shapes!==G,L=b.selectedId!==V;k&&(G=b.shapes,m()),L&&(V=b.selectedId,W.setCanDelete(b.selectedId!==null)),b.activeTool!==Y&&(Y=b.activeTool,W.setActiveTool(b.activeTool)),b.currentStyle!==x&&(x=b.currentStyle,W.setStyle(b.currentStyle)),E.update(Z(b),l),(L||k)&&$.updateForShape(Z(b))}),N=b=>{const k=b.target;if(ns(k))return;const L=i.get();if(b.key==="Escape"){L.selectedId!==null&&(b.preventDefault(),b.stopPropagation(),i.update(P=>mt(P,null)),s("Selection cleared."));return}if(b.key==="Delete"||b.key==="Backspace"){if(L.selectedId===null)return;b.preventDefault();const P=L.selectedId;i.update(v=>Nt(v,P)),a();return}if(b.key==="ArrowUp"||b.key==="ArrowDown"||b.key==="ArrowLeft"||b.key==="ArrowRight"){const P=Z(L);if(!P||b.ctrlKey||b.altKey||b.metaKey)return;const v=b.shiftKey?10:1,I=b.key==="ArrowLeft"?-v:b.key==="ArrowRight"?v:0,z=b.key==="ArrowUp"?-v:b.key==="ArrowDown"?v:0;b.preventDefault();const q=on(P,I,z);i.update(K=>nt(K,q)),a()}};return document.addEventListener("keydown",N,!0),{destroy(){document.removeEventListener("keydown",N,!0),M(),F(),D?.(),U.disconnect(),S.destroy(),E.destroy(),c.container.remove(),W.container.remove()}}}function Qa(t,e){switch(t.kind){case"text":return{...t,color:e};case"rect":case"ellipse":return{...t,strokeColor:e};case"arrow":case"freehand":case"highlight":return{...t,color:e}}}function Ja(t,e){switch(t.kind){case"text":return{...t,fontSize:Math.max(8,Math.round(e*4))};case"rect":case"ellipse":case"arrow":case"freehand":case"highlight":return{...t,strokeWidth:e}}}function Za(t){let{x:e,y:n,width:o,height:i}=t;return o<0&&(e+=o,o=-o),i<0&&(n+=i,i=-i),{x:e,y:n,width:o,height:i}}function ts(t,e){for(let n=t.length-1;n>=0;n--){const o=t[n];if(!o)continue;const i=ft(o);if(es(i,e))return o}}function es(t,e){return!(t.x+t.width<e.x||e.x+e.width<t.x||t.y+t.height<e.y||e.y+e.height<t.y)}function ns(t){if(!t)return!1;const e=t.tagName;return e==="INPUT"||e==="TEXTAREA"||e==="SELECT"?!0:t.isContentEditable===!0}function os(t){switch(t){case"rect":return"Rectangle";case"ellipse":return"Ellipse";case"arrow":return"Arrow";case"text":return"Text annotation"}}function is(t){return{id:"annotate",init:e=>hi({imageSize:{width:e.source.width,height:e.source.height}}),mount(e,n,o){const i=ja({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"annotate"}),onAnnounce:r=>n.bus.emit("announce",{message:r})});return{destroy:()=>i.destroy()}},bake:(e,n)=>Ci({shapes:e.shapes},n)}}const rs=[{id:"x",label:"Left"},{id:"y",label:"Top"},{id:"width",label:"Width",min:1},{id:"height",label:"Height",min:1}];function as(t){const e=document.createElement("div");e.className="kalotyp-redact-coords",e.setAttribute("role","group"),e.setAttribute("aria-label","Selected redaction position"),e.hidden=!0;let n=null;const o=new Map;for(const s of rs){const c=document.createElement("label");c.className="kalotyp-redact-coords-field";const l=document.createElement("span");l.className="kalotyp-redact-coords-label",l.textContent=s.label;const u=document.createElement("input");u.type="number",u.className="kalotyp-redact-coords-input",u.dataset.field=s.id,u.step="1",u.inputMode="numeric",s.min!==void 0&&(u.min=String(s.min)),u.setAttribute("aria-label",`${s.label} (pixels)`),u.addEventListener("change",r),c.appendChild(l),c.appendChild(u),e.appendChild(c),o.set(s.id,u)}function i(s){const c=(l,u)=>{const d=o.get(l);if(!d)return;const h=String(Math.round(u));document.activeElement!==d&&d.value!==h&&(d.value=h)};c("x",s.x),c("y",s.y),c("width",s.width),c("height",s.height)}function r(){if(!n)return;const s=a("x"),c=a("y"),l=a("width"),u=a("height");if(![s,c,l,u].every(Number.isFinite))return;const d={...n,x:s,y:c,width:l,height:u};d.x===n.x&&d.y===n.y&&d.width===n.width&&d.height===n.height||(n=d,t.onRegionChanged(d))}function a(s){const c=o.get(s);return c?Math.round(c.valueAsNumber):Number.NaN}return{container:e,updateForRegion(s){if(!s){n=null,e.hidden=!0;return}n=s,i(s),e.hidden=!1},destroy(){e.replaceChildren(),o.clear(),e.remove()}}}const ss=[{id:"pixelate",label:"Pixelate"},{id:"blur",label:"Blur"},{id:"solid",label:"Solid fill"}];function cs(t){const e=document.createElement("div");e.className="kalotyp-redact-panel",e.setAttribute("role","group"),e.setAttribute("aria-label","Redact");const n=document.createElement("div");n.className="kalotyp-redact-toolbar",n.setAttribute("role","radiogroup"),n.setAttribute("aria-label","Redaction mode");const o=new Map;for(const g of ss){const p=document.createElement("button");p.type="button",p.className="kalotyp-redact-mode",p.dataset.mode=g.id,p.setAttribute("role","radio"),p.setAttribute("aria-checked",g.id===t.initialMode?"true":"false"),p.setAttribute("aria-label",`${g.label} redaction`),p.title=g.label,p.textContent=g.label,p.addEventListener("click",()=>t.onSelectMode(g.id)),n.appendChild(p),o.set(g.id,p)}const i=document.createElement("div");i.className="kalotyp-redact-style-row";const r=document.createElement("input");r.type="color",r.className="kalotyp-redact-color",r.value=le(t.initialColor),r.setAttribute("aria-label","Solid fill colour (visual picker)"),r.addEventListener("change",()=>t.onColorChange(r.value));const a=document.createElement("input");a.type="text",a.className="kalotyp-redact-hex",a.value=le(t.initialColor),a.maxLength=7,a.spellcheck=!1,a.autocomplete="off",a.setAttribute("aria-label","Solid fill hex code"),a.setAttribute("placeholder","#000000"),a.addEventListener("change",()=>{const g=a.value.trim(),p=ls(g);p?(a.value=p,t.onColorChange(p)):a.value=r.value});const s=document.createElement("button");s.type="button",s.className="kalotyp-redact-insert",s.innerHTML=`${B("plus")}<span>Insert at centre</span>`,s.setAttribute("aria-label","Insert redaction region at image centre"),s.title="Insert at centre",s.addEventListener("click",()=>t.onInsertAtCenter());const c=document.createElement("button");c.type="button",c.className="kalotyp-redact-delete",c.innerHTML=`${B("delete")}<span>Delete</span>`,c.setAttribute("aria-label","Delete selected redaction region"),c.title="Delete (Del)",c.disabled=!t.canDelete,c.addEventListener("click",()=>t.onDeleteSelected());const l=document.createElement("div");l.className="kalotyp-redact-color-group",l.appendChild(r),l.appendChild(a);const u=document.createElement("span");u.className="kalotyp-redact-color-hint",u.textContent="Colour applies to Solid fill only.",u.setAttribute("aria-live","polite");const d=document.createElement("div");d.className="kalotyp-redact-button-group",d.appendChild(s),d.appendChild(c),i.appendChild(l),i.appendChild(u),i.appendChild(d),e.appendChild(n),e.appendChild(i),e.appendChild(t.coordInputs);function h(g){for(const[w,y]of o)y.setAttribute("aria-checked",w===g?"true":"false"),y.classList.toggle("kalotyp-redact-mode--active",w===g);const p=g==="solid";r.disabled=!p,a.disabled=!p,u.hidden=p}function f(g){const p=le(g);r.value!==p&&(r.value=p),a.value.toLowerCase()!==p.toLowerCase()&&(a.value=p)}function m(g){c.disabled=!g}return h(t.initialMode),{container:e,modeButtons:o,colorInput:r,hexInput:a,insertButton:s,deleteButton:c,setActiveMode:h,setColor:f,setCanDelete:m}}function le(t){if(/^#[0-9a-fA-F]{6}$/.test(t))return t;if(/^#[0-9a-fA-F]{3}$/.test(t)){const e=t[1],n=t[2],o=t[3];return`#${e}${e}${n}${n}${o}${o}`}return"#000000"}function ls(t){const e=t.startsWith("#")?t.slice(1):t;if(/^[0-9a-fA-F]{6}$/.test(e))return`#${e.toLowerCase()}`;if(/^[0-9a-fA-F]{3}$/.test(e)){const n=e[0],o=e[1],i=e[2];return`#${n}${n}${o}${o}${i}${i}`.toLowerCase()}return null}function ue(t,e,n){const o=Math.max(1,window.devicePixelRatio||1),i=Math.max(1,Math.round(e*o)),r=Math.max(1,Math.round(n*o));t.width!==i&&(t.width=i),t.height!==r&&(t.height=r),t.style.width=`${e}px`,t.style.height=`${n}px`;const a=t.getContext("2d");return a?(a.setTransform(o,0,0,o,0,0),a.clearRect(0,0,e,n),a):null}function us(t,e,n,o,i){const r=ue(t,n,o);r&&(r.imageSmoothingEnabled=!0,r.imageSmoothingQuality="high",r.drawImage(e.bitmap,i.displayRect.x,i.displayRect.y,i.displayRect.width,i.displayRect.height))}function ds(t,e,n,o,i,r,a){const s=ue(t,i,r);if(!s||n.length===0)return;const c=document.createElement("canvas"),l=Math.max(1,Math.round(a.displayRect.width)),u=Math.max(1,Math.round(a.displayRect.height));c.width=l,c.height=u;const d=c.getContext("2d");if(d){d.imageSmoothingEnabled=!0,d.imageSmoothingQuality="high",d.drawImage(e.bitmap,0,0,l,u);for(const h of n){const f={...h,x:h.x*a.scale,y:h.y*a.scale,width:h.width*a.scale,height:h.height*a.scale};mn(d,c,f,{})}s.drawImage(c,a.displayRect.x,a.displayRect.y,l,u);for(const h of n){const f=a.displayRect.x+h.x*a.scale,m=a.displayRect.y+h.y*a.scale,g=h.width*a.scale,p=h.height*a.scale;s.save(),h.id===o?(s.strokeStyle="rgba(99, 102, 241, 0.9)",s.lineWidth=1.5):(s.strokeStyle="rgba(255, 255, 255, 0.6)",s.lineWidth=1),s.setLineDash([4,3]),s.strokeRect(f+.5,m+.5,Math.max(0,g-1),Math.max(0,p-1)),s.restore()}}}function hs(t,e,n,o,i){const r=ue(t,n,o);if(!r||!e)return;const a=i.displayRect.x+e.x*i.scale,s=i.displayRect.y+e.y*i.scale;let c=e.width*i.scale,l=e.height*i.scale,u=a,d=s;c<0&&(u=a+c,c=-c),l<0&&(d=s+l,l=-l),r.save(),r.fillStyle=ps(e.mode,e.color),r.fillRect(u,d,c,l),r.strokeStyle="rgba(99, 102, 241, 0.95)",r.lineWidth=1.5,r.setLineDash([4,3]),r.strokeRect(u+.75,d+.75,Math.max(0,c-1.5),Math.max(0,l-1.5)),r.restore()}function ps(t,e){switch(t){case"solid":return ms(e,.7);case"pixelate":return"rgba(120, 120, 120, 0.6)";case"blur":return"rgba(180, 200, 220, 0.45)"}}function ms(t,e){const n=/^#([0-9a-fA-F]{6})$/.exec(t);if(!n)return t;const o=n[1];if(!o)return t;const i=Number.parseInt(o.slice(0,2),16),r=Number.parseInt(o.slice(2,4),16),a=Number.parseInt(o.slice(4,6),16);return`rgba(${i}, ${r}, ${a}, ${e})`}function fs(t){const{host:e,store:n}=t,o=new Map,i=[];for(const c of Tt){const l=document.createElement("button");l.type="button",l.className="kalotyp-redact-handle",l.dataset.direction=c,l.setAttribute("aria-label",bs(c)),l.tabIndex=-1,l.style.display="none",o.set(c,l),e.appendChild(l),i.push(Ot(l,u=>s(c)))}function r(c,l){if(!c){for(const[,h]of o)h.style.display="none";return}const u={x:c.x,y:c.y,width:c.width,height:c.height},d=gs(u);for(const h of Tt){const f=o.get(h);if(!f)continue;const m=ys(d[h],l);f.style.display="",f.style.left=`${m.x}px`,f.style.top=`${m.y}px`}}function a(){for(const c of i)c();for(const[,c]of o)c.remove();o.clear()}function s(c,l){const u=lt(n.get());return u?{onMove(d){const h=t.toImageSpace(d),f={x:u.x,y:u.y,width:u.width,height:u.height},m=Jt(f,c,h);n.update(g=>J(g,{...u,x:m.x,y:m.y,width:m.width,height:m.height}))},onCommit(){const d=lt(n.get());if(d&&(d.width<0||d.height<0)){let{x:h,y:f,width:m,height:g}=d;m<0&&(h+=m,m=-m),g<0&&(f+=g,g=-g),n.update(p=>J(p,{...d,x:h,y:f,width:m,height:g}))}t.commit()},onCancel(){n.update(d=>J(d,u))}}:null}return{update:r,destroy:a}}function gs(t){const e=t.x,n=t.x+t.width,o=t.y,i=t.y+t.height,r=t.x+t.width/2,a=t.y+t.height/2;return{tl:{x:e,y:o},tr:{x:n,y:o},bl:{x:e,y:i},br:{x:n,y:i},t:{x:r,y:o},r:{x:n,y:a},b:{x:r,y:i},l:{x:e,y:a}}}function ys(t,e){return{x:e.displayRect.x+t.x*e.scale,y:e.displayRect.y+t.y*e.scale}}function bs(t){switch(t){case"tl":return"Resize from top-left";case"tr":return"Resize from top-right";case"bl":return"Resize from bottom-left";case"br":return"Resize from bottom-right";case"t":return"Resize from top";case"r":return"Resize from right";case"b":return"Resize from bottom";case"l":return"Resize from left"}}function ws(){const t=document.createElement("div");t.className="kalotyp-redact-stage";const e=document.createElement("canvas");e.className="kalotyp-redact-image",e.setAttribute("aria-hidden","true");const n=document.createElement("canvas");n.className="kalotyp-redact-regions",n.setAttribute("aria-hidden","true");const o=document.createElement("canvas");o.className="kalotyp-redact-live",o.setAttribute("aria-hidden","true");const i=document.createElement("div");i.className="kalotyp-redact-hit",i.setAttribute("role","presentation");const r=document.createElement("div");return r.className="kalotyp-redact-handles",r.setAttribute("role","group"),r.setAttribute("aria-label","Selected redaction region"),t.appendChild(e),t.appendChild(n),t.appendChild(o),t.appendChild(i),t.appendChild(r),{container:t,imageCanvas:e,regionsCanvas:n,liveCanvas:o,hitArea:i,handlesLayer:r}}const Xn=32;function Cs(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??(()=>{}),s=t.onAnnounce??(()=>{}),c=Di(i.get(),{width:o.width,height:o.height});c!==i.get()&&i.update(()=>c);const l=ws();e.appendChild(l.container);let u=j({width:1,height:1,padding:Xn},{width:o.width,height:o.height}),d=null;function h(){const x=l.container.getBoundingClientRect(),F={width:x.width,height:x.height,padding:Xn},N={width:o.width,height:o.height};u=r?r.computeViewport(F,N):j(F,N)}function f(){const x=l.container.getBoundingClientRect();x.width<=0||x.height<=0||us(l.imageCanvas,o,x.width,x.height,u)}function m(){const x=l.container.getBoundingClientRect();if(x.width<=0||x.height<=0)return;const F=i.get();ds(l.regionsCanvas,o,F.regions,F.selectedId,x.width,x.height,u)}function g(){const x=l.container.getBoundingClientRect();x.width<=0||x.height<=0||hs(l.liveCanvas,d,x.width,x.height,u)}function p(){f(),m(),g(),C.update(lt(i.get()),u)}function w(x){d=x,g()}function y(x){const F=On(l.container,x.clientX,x.clientY);return Wt(F,u)}const C=fs({host:l.handlesLayer,store:i,toImageSpace:y,getViewport:()=>u,commit:a}),E=Ot(l.hitArea,x=>{const F=i.get(),N=y(x),b=xs(F.regions,N);return b?(F.selectedId!==b.id&&i.update(k=>pn(k,b.id)),S(b,x)):M(F,x)});function S(x,F){const N=y(F);return{onMove(b){const k=y(b),L=k.x-N.x,P=k.y-N.y;i.update(v=>J(v,{...x,x:x.x+L,y:x.y+P}))},onCommit(){a()},onCancel(){i.update(b=>J(b,x))}}}function M(x,F){const N=y(F);let b=N;return{onMove(k){const L=y(k);if(k.shiftKey){const P=L.x-N.x,v=L.y-N.y,I=Math.max(Math.abs(P),Math.abs(v)),z=P===0?1:Math.sign(P),q=v===0?1:Math.sign(v);b={x:N.x+z*I,y:N.y+q*I}}else b=L;w({x:N.x,y:N.y,width:b.x-N.x,height:b.y-N.y,mode:x.currentMode,color:x.currentColor})},onCommit(){w(null);const k=Pi({x:N.x,y:N.y,width:b.x-N.x,height:b.y-N.y});if(k.width<4||k.height<4)return;const{id:L,nextRegionNumber:P}=un(x),v={id:L,x:k.x,y:k.y,width:k.width,height:k.height,mode:x.currentMode,color:x.currentColor};i.update(I=>({...dn(I,v),nextRegionNumber:P})),a()},onCancel(){w(null)}}}function H(){const x=i.get(),{id:F,nextRegionNumber:N}=un(x),b=$i({imageSize:{width:o.width,height:o.height},mode:x.currentMode,color:x.currentColor,id:F});i.update(k=>({...dn(k,b),nextRegionNumber:N})),s("Redaction region placed at centre. Use arrow keys to nudge, or edit coordinates below."),requestAnimationFrame(()=>{const k=R.container.querySelector(".kalotyp-redact-coords-input");k?.focus(),k?.select()}),a()}const R=as({onRegionChanged:x=>{i.update(F=>J(F,x)),a()}}),A=i.get(),T=cs({initialMode:A.currentMode,initialColor:A.currentColor,canDelete:A.selectedId!==null,coordInputs:R.container,onSelectMode:x=>{i.update(F=>{const N=Ni(F,x);return N.selectedId===null?N:Ti(N,N.selectedId,x)}),a()},onColorChange:x=>{i.update(F=>{const N=Li(F,x);return N.selectedId===null?N:Fi(N,N.selectedId,x)}),a()},onInsertAtCenter:()=>H(),onDeleteSelected:()=>{const x=i.get().selectedId;x&&(i.update(F=>hn(F,x)),a())}});n.appendChild(T.container),h(),p();const $=new ResizeObserver(()=>{h(),p()});$.observe(l.container);let O=!1;const W=r?.subscribe(()=>{O||(O=!0,requestAnimationFrame(()=>{O=!1,h(),p()}))});let U=i.get().regions,_=i.get().selectedId,D=i.get().currentMode,G=i.get().currentColor;const V=i.subscribe(x=>{const F=x.regions!==U,N=x.selectedId!==_;F&&(U=x.regions,m()),N&&(_=x.selectedId,T.setCanDelete(x.selectedId!==null)),x.currentMode!==D&&(D=x.currentMode,T.setActiveMode(x.currentMode)),x.currentColor!==G&&(G=x.currentColor,T.setColor(x.currentColor)),C.update(lt(x),u),(N||F)&&R.updateForRegion(lt(x))}),Y=x=>{const F=x.target;if(vs(F))return;const N=i.get();if(x.key==="Escape"){N.selectedId!==null&&(x.preventDefault(),x.stopPropagation(),i.update(b=>pn(b,null)),s("Selection cleared."));return}if(x.key==="Delete"||x.key==="Backspace"){if(N.selectedId===null)return;x.preventDefault();const b=N.selectedId;i.update(k=>hn(k,b)),a();return}if(x.key==="ArrowUp"||x.key==="ArrowDown"||x.key==="ArrowLeft"||x.key==="ArrowRight"){const b=lt(N);if(!b||x.ctrlKey||x.altKey||x.metaKey)return;const k=x.shiftKey?10:1,L=x.key==="ArrowLeft"?-k:x.key==="ArrowRight"?k:0,P=x.key==="ArrowUp"?-k:x.key==="ArrowDown"?k:0;x.preventDefault(),i.update(v=>J(v,{...b,x:b.x+L,y:b.y+P})),a()}};return document.addEventListener("keydown",Y,!0),{destroy(){document.removeEventListener("keydown",Y,!0),E(),V(),W?.(),$.disconnect(),R.destroy(),C.destroy(),l.container.remove(),T.container.remove()}}}function xs(t,e){for(let n=t.length-1;n>=0;n--){const o=t[n];if(o&&e.x>=o.x&&e.x<=o.x+o.width&&e.y>=o.y&&e.y<=o.y+o.height)return o}}function vs(t){if(!t)return!1;const e=t.tagName;return e==="INPUT"||e==="TEXTAREA"||e==="SELECT"?!0:t.isContentEditable===!0}function ks(t){return{id:"redact",init:e=>Ri({imageSize:{width:e.source.width,height:e.source.height}}),mount(e,n,o){const i=Cs({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,onCommit:()=>n.bus.emit("commit",{utility:"redact"}),onAnnounce:r=>n.bus.emit("announce",{message:r})});return{destroy:()=>i.destroy()}},bake:(e,n)=>Oi({regions:e.regions},n)}}const Yn=32;function Ss(t){const{stageHost:e,utilHost:n,source:o,store:i,viewport:r}=t,a=t.onCommit??(()=>{}),s=document.createElement("div");s.className="kalotyp-stage-container kalotyp-frame-preview-container";const c=document.createElement("canvas");c.className="kalotyp-stage-image kalotyp-frame-preview-canvas",c.setAttribute("aria-hidden","true"),s.appendChild(c),e.appendChild(s);const l=i.get(),u=document.createElement("div");u.className="kalotyp-frame-panel";const d=Es({presets:fn,initialActiveId:l.presetId,labels:t.labels,source:o,initialState:l,onPresetClick:S=>{i.update(M=>Ui(M,S.id)),a()}});u.appendChild(d.container);const h=As({initialColor:l.color,initialPresetId:l.presetId,onColorChange:S=>{i.update(M=>Xi(M,S)),a()}});u.appendChild(h.container),n.appendChild(u);let f=j({width:1,height:1,padding:Yn},{width:o.width,height:o.height});function m(){const S=s.getBoundingClientRect();if(S.width<=0||S.height<=0)return;const M={width:S.width,height:S.height,padding:Yn},H=i.get(),R=oe(H.presetId,o.width,o.height);f=r?r.computeViewport(M,R):j(M,R)}function g(){const S=s.getBoundingClientRect();if(S.width<=0||S.height<=0)return;const M=Math.max(1,window.devicePixelRatio||1),H=Math.max(1,Math.round(S.width*M)),R=Math.max(1,Math.round(S.height*M));c.width!==H&&(c.width=H),c.height!==R&&(c.height=R),c.style.width=`${S.width}px`,c.style.height=`${S.height}px`;const A=c.getContext("2d");if(!A)return;A.setTransform(M,0,0,M,0,0),A.clearRect(0,0,S.width,S.height),A.imageSmoothingEnabled=!0,A.imageSmoothingQuality="high";const T=i.get(),$=oe(T.presetId,o.width,o.height),O=f.displayRect.x,W=f.displayRect.y,U=f.displayRect.width,_=f.displayRect.height;if(T.presetId==="polaroid"){A.fillStyle=T.color,A.fillRect(O,W,U,_);const D=o.width*(U/$.width),G=o.height*(_/$.height),V=Math.min(o.width,o.height),Y=Math.round(V*.05),x=O+Y*U/$.width,F=W+Y*_/$.height;A.drawImage(o.bitmap,x,F,D,G)}else A.drawImage(o.bitmap,O,W,U,_),T.presetId!=="none"&&(A.save(),A.translate(O,W),ne(A,T.presetId,T.color,U,_),A.restore())}m(),g();const p=new ResizeObserver(()=>{m(),g()});p.observe(s);let w=!1;const y=r?.subscribe(()=>{w||(w=!0,requestAnimationFrame(()=>{w=!1,m(),g()}))});let C=!1;const E=i.subscribe(S=>{d.setActive(S.presetId),h.setColor(S.color),h.setEnabled(S.presetId!=="none"),!C&&(C=!0,requestAnimationFrame(()=>{C=!1,m(),g()}))});return{destroy(){E(),y?.(),p.disconnect(),s.remove(),u.remove()}}}function Es(t){const e=document.createElement("div");e.className="kalotyp-frame-strip-wrap",e.setAttribute("role","radiogroup"),e.setAttribute("aria-label","Frame presets");const n=document.createElement("div");n.className="kalotyp-frame-strip",e.appendChild(n);const o=new Map;for(const r of t.presets){const a=document.createElement("button");a.type="button",a.className="kalotyp-frame-thumb",a.dataset.presetId=r.id,a.setAttribute("role","radio"),a.setAttribute("aria-checked","false");const s=t.labels?.[r.id]??r.label;a.setAttribute("aria-label",`${s} frame`),a.title=s;const c=document.createElement("span");c.className="kalotyp-frame-thumb-image";const l=Ms(r,t.source,t.initialState.color);l.classList.add("kalotyp-frame-thumb-canvas"),c.appendChild(l);const u=document.createElement("span");u.className="kalotyp-frame-thumb-check",u.setAttribute("aria-hidden","true"),u.innerHTML="✓",c.appendChild(u);const d=document.createElement("span");d.className="kalotyp-frame-thumb-label",d.textContent=s,a.appendChild(c),a.appendChild(d),a.addEventListener("click",()=>t.onPresetClick(r)),n.appendChild(a),o.set(r.id,a)}function i(r){for(const[a,s]of o){const c=a===r;s.setAttribute("aria-checked",c?"true":"false"),s.classList.toggle("kalotyp-frame-thumb--active",c)}}return i(t.initialActiveId),{container:e,setActive:i}}function As(t){const e=document.createElement("div");e.className="kalotyp-frame-color-row";const n=document.createElement("span");n.className="kalotyp-frame-color-label",n.textContent="Colour";const o=document.createElement("input");o.type="color",o.className="kalotyp-frame-color",o.value=de(t.initialColor),o.setAttribute("aria-label","Frame colour (visual picker)"),o.addEventListener("change",()=>t.onColorChange(o.value));const i=document.createElement("input");i.type="text",i.className="kalotyp-frame-hex",i.value=de(t.initialColor),i.maxLength=7,i.spellcheck=!1,i.autocomplete="off",i.setAttribute("aria-label","Frame colour hex code"),i.setAttribute("placeholder","#000000"),i.addEventListener("change",()=>{const c=i.value.trim(),l=Is(c);l?(i.value=l,t.onColorChange(l)):i.value=o.value});const r=document.createElement("span");r.className="kalotyp-frame-color-hint",r.textContent="Pick a frame preset to choose a colour.",r.setAttribute("aria-live","polite"),e.appendChild(n),e.appendChild(o),e.appendChild(i),e.appendChild(r);function a(c){o.disabled=!c,i.disabled=!c,r.hidden=c}function s(c){const l=de(c);o.value!==l&&(o.value=l),i.value.toLowerCase()!==l.toLowerCase()&&(i.value=l)}return a(t.initialPresetId!=="none"),{container:e,setColor:s,setEnabled:a}}function Ms(t,e,n){const o={width:80,height:60},i=oe(t.id,e.width,e.height),r=Math.min(o.width/i.width,o.height/i.height),a=Math.max(1,Math.floor(i.width*r)),s=Math.max(1,Math.floor(i.height*r)),c=Math.max(1,window.devicePixelRatio||1),l=document.createElement("canvas");l.width=Math.max(1,Math.round(a*c)),l.height=Math.max(1,Math.round(s*c)),l.style.width=`${a}px`,l.style.height=`${s}px`;const u=l.getContext("2d");if(!u)return l;if(u.setTransform(c,0,0,c,0,0),u.imageSmoothingEnabled=!0,u.imageSmoothingQuality="high",t.id==="polaroid"){u.fillStyle=n,u.fillRect(0,0,a,s);const d=Math.min(e.width,e.height),h=Math.round(d*.05/i.width*a),f=Math.round(d*.05/i.height*s),m=Math.round(e.width/i.width*a),g=Math.round(e.height/i.height*s);u.drawImage(e.bitmap,h,f,m,g)}else u.drawImage(e.bitmap,0,0,a,s),t.id!=="none"&&ne(u,t.id,n,a,s);return l}function de(t){if(/^#[0-9a-fA-F]{6}$/.test(t))return t;if(/^#[0-9a-fA-F]{3}$/.test(t)){const e=t[1],n=t[2],o=t[3];return`#${e}${e}${n}${n}${o}${o}`}return"#000000"}function Is(t){const e=t.startsWith("#")?t.slice(1):t;if(/^[0-9a-fA-F]{6}$/.test(e))return`#${e.toLowerCase()}`;if(/^[0-9a-fA-F]{3}$/.test(e)){const n=e[0],o=e[1],i=e[2];return`#${n}${n}${o}${o}${i}${i}`.toLowerCase()}return null}function Rs(t){return{id:"frame",init:()=>qi(),mount(e,n,o){const i=Ss({stageHost:e,utilHost:t.panelHost,source:n.source,store:o,viewport:n.viewport,labels:t.labels,onCommit:()=>n.bus.emit("commit",{utility:"frame"})});return{destroy:()=>i.destroy()}},bake:(e,n)=>Yi(e,n)}}function Ns(t,e,n,o){const i=document.createElement("div");i.className="kalotyp-util-nav",i.setAttribute("role","tablist"),i.setAttribute("aria-label","Editor tools");const r=new Map;for(const a of t){const s=document.createElement("button");s.type="button",s.className="kalotyp-util-nav-button",s.dataset.utilityId=a.id,s.id=`${o.panelId}-tab-${a.id}`,s.setAttribute("role","tab"),s.setAttribute("aria-selected",a.id===e?"true":"false"),s.setAttribute("aria-controls",o.panelId),s.tabIndex=a.id===e?0:-1,s.textContent=a.label,s.addEventListener("click",()=>n(a.id)),i.appendChild(s),r.set(a.id,s)}return i.addEventListener("keydown",a=>{if(a.key!=="ArrowLeft"&&a.key!=="ArrowRight"&&a.key!=="Home"&&a.key!=="End")return;const s=t.map(f=>f.id),l=a.target?.dataset?.utilityId,u=l?s.indexOf(l):-1;if(u===-1)return;let d=u;a.key==="ArrowLeft"?d=(u-1+s.length)%s.length:a.key==="ArrowRight"?d=(u+1)%s.length:a.key==="Home"?d=0:a.key==="End"&&(d=s.length-1);const h=s[d];!h||h===l||(a.preventDefault(),n(h),r.get(h)?.focus())}),{container:i,buttons:r}}function Gn(t,e,n){for(const[o,i]of t.buttons.entries()){const r=o===e;if(i.setAttribute("aria-selected",r?"true":"false"),i.tabIndex=r?0:-1,r){try{i.scrollIntoView({block:"nearest",inline:"nearest",behavior:"smooth"})}catch{}n&&n.setAttribute("aria-labelledby",i.id)}}}const Ls=["a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","details","summary",'[tabindex]:not([tabindex="-1"])','[contenteditable="true"]'].join(", ");function Ts(t){const{host:e}=t,n=document.activeElement instanceof HTMLElement&&document.activeElement!==document.body?document.activeElement:null;function o(){return Array.from(e.querySelectorAll(Ls))}const i=t.initialFocus??o()[0];i&&requestAnimationFrame(()=>i.focus());const r=a=>{if(a.key!=="Tab")return;const s=o();if(s.length===0){a.preventDefault();return}const c=s[0],l=s[s.length-1];if(!c||!l)return;const u=document.activeElement;a.shiftKey?(u===c||!e.contains(u))&&(a.preventDefault(),l.focus()):(u===l||!e.contains(u))&&(a.preventDefault(),c.focus())};return document.addEventListener("keydown",r,!0),{refresh:()=>{},release:()=>{if(document.removeEventListener("keydown",r,!0),n?.isConnected)try{n.focus()}catch{}}}}const Fs=1.0015;function Ps(t,e){const n=new Map;let o=null;function i(){return t.getBoundingClientRect()}function r(m,g){const p=i();return{x:m-p.left,y:g-p.top}}function a(){const m=i();return{x:m.width/2,y:m.height/2}}function s(){if(n.size<2)return null;const m=n.values(),g=m.next().value,p=m.next().value,w=r((g.x+p.x)/2,(g.y+p.y)/2),y=p.x-g.x,C=p.y-g.y,E=Math.sqrt(y*y+C*C);return{midpoint:w,distance:E}}function c(){if(n.size<2||o!==null)return;const m=s();!m||m.distance<=0||(o={lastDistance:m.distance,lastMidpoint:m.midpoint},e.setPinching(!0))}function l(){o!==null&&(o=null,e.setPinching(!1))}function u(m){m.pointerType==="mouse"&&m.button!==0||(n.set(m.pointerId,{id:m.pointerId,x:m.clientX,y:m.clientY}),c())}function d(m){const g=n.get(m.pointerId);if(!g||(g.x=m.clientX,g.y=m.clientY,o===null))return;const p=s();if(!p||p.distance<=0)return;const w=p.distance/o.lastDistance;w!==1&&e.zoomAt(w,p.midpoint,a());const y=p.midpoint.x-o.lastMidpoint.x,C=p.midpoint.y-o.lastMidpoint.y;(y!==0||C!==0)&&e.panBy(y,C),o.lastDistance=p.distance,o.lastMidpoint=p.midpoint,m.preventDefault()}function h(m){n.has(m.pointerId)&&(n.delete(m.pointerId),n.size<2&&l())}function f(m){const g=Fs**-m.deltaY;if(g===1)return;const p=r(m.clientX,m.clientY);e.zoomAt(g,p,a()),m.preventDefault()}return t.addEventListener("pointerdown",u),t.addEventListener("pointermove",d),t.addEventListener("pointerup",h),t.addEventListener("pointercancel",h),t.addEventListener("pointerleave",h),t.addEventListener("wheel",f,{passive:!1}),()=>{t.removeEventListener("pointerdown",u),t.removeEventListener("pointermove",d),t.removeEventListener("pointerup",h),t.removeEventListener("pointercancel",h),t.removeEventListener("pointerleave",h),t.removeEventListener("wheel",f),n.clear(),o!==null&&e.setPinching(!1),o=null}}const $s=["a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[tabindex]:not([tabindex="-1"])','[contenteditable="true"]'].join(", ");function he(t){const e=document.activeElement instanceof HTMLElement?document.activeElement:null,n=document.createElement("div");n.className="kalotyp-nested-overlay",t.variant&&n.classList.add(t.variant);const o=document.createElement("div");o.className="kalotyp-nested-surface",o.setAttribute("role","dialog"),o.setAttribute("aria-modal","true"),o.tabIndex=-1;const i=`kalotyp-nested-title-${Math.random().toString(36).slice(2,8)}`;o.setAttribute("aria-labelledby",i);const r=document.createElement("div");r.className="kalotyp-nested-header";const a=document.createElement("h3");a.id=i,a.className="kalotyp-nested-title",a.textContent=t.title,r.appendChild(a);let s;t.showCloseButton!==!1&&(s=document.createElement("button"),s.type="button",s.className="kalotyp-nested-close",s.setAttribute("aria-label",`Close ${t.title}`),s.textContent="×",s.addEventListener("click",()=>h()),r.appendChild(s)),o.appendChild(r);const c=document.createElement("div");if(c.className="kalotyp-nested-body",c.appendChild(t.body),o.appendChild(c),n.appendChild(o),t.host.appendChild(n),t.anchor){n.classList.add("kalotyp-nested-overlay--popover"),Kn(n,o,t.anchor);const f=()=>Kn(n,o,t.anchor);window.addEventListener("resize",f),n.dataset.resizeListenerAttached="1",n.addEventListener("kalotyp-nested-cleanup",()=>{window.removeEventListener("resize",f)})}else n.classList.add("kalotyp-nested-overlay--modal");requestAnimationFrame(()=>o.focus());const l=f=>{if(f.key==="Escape"){f.preventDefault(),f.stopPropagation(),h();return}if(f.key!=="Tab")return;const m=Array.from(o.querySelectorAll($s));if(m.length===0){f.preventDefault(),o.focus();return}const g=m[0],p=m[m.length-1];if(!g||!p)return;const w=document.activeElement;f.shiftKey?(w===g||!o.contains(w))&&(f.preventDefault(),p.focus()):(w===p||!o.contains(w))&&(f.preventDefault(),g.focus())};document.addEventListener("keydown",l,!0);const u=f=>{const m=f.target;m&&(o.contains(m)||h())};n.addEventListener("mousedown",u);let d=!1;function h(){if(!d){if(d=!0,document.removeEventListener("keydown",l,!0),n.removeEventListener("mousedown",u),n.dispatchEvent(new Event("kalotyp-nested-cleanup")),n.remove(),e?.isConnected)try{e.focus()}catch{}t.onClose()}}return{element:n,close:h}}function Kn(t,e,n){const o=n.getBoundingClientRect(),i=t.parentElement?.getBoundingClientRect()??{top:0,right:window.innerWidth},r=e.getBoundingClientRect(),a=o.top-i.top-r.height-8,s=i.right-o.right;e.style.position="absolute",e.style.top=`${Math.max(8,a)}px`,e.style.right=`${Math.max(8,s)}px`}const pe=[{value:"auto",label:"Auto",description:"WebP when supported, PNG fallback.",requires:[]},{value:"image/webp",label:"WebP",description:"Best compression for most images.",requires:["image/webp"]},{value:"image/avif",label:"AVIF",description:"Smallest size; slower encode.",requires:["image/avif"]},{value:"image/jpeg",label:"JPEG",description:"Universal; no transparency.",requires:["image/jpeg"]},{value:"image/png",label:"PNG",description:"Lossless; preserves transparency.",requires:["image/png"]}];function Ds(t){const{host:e,anchor:n,store:o}=t,i=document.createElement("div");i.className="kalotyp-output-popover-body";const r=document.createElement("label");r.className="kalotyp-output-row";const a=document.createElement("span");a.className="kalotyp-output-row-label",a.textContent="Format",r.appendChild(a);const s=document.createElement("select");s.className="kalotyp-output-format",s.setAttribute("aria-label","Output format");for(const R of pe){const A=document.createElement("option");A.value=R.value,A.textContent=R.label,s.appendChild(A)}s.value=o.get().mimeChoice,s.addEventListener("change",()=>{const R=s.value;o.update(A=>So(A,R))}),r.appendChild(s);const c=document.createElement("p");c.className="kalotyp-output-hint",c.setAttribute("aria-live","polite");const l=document.createElement("label");l.className="kalotyp-output-row";const u=document.createElement("span");u.className="kalotyp-output-row-label",u.textContent="Quality",l.appendChild(u);const d=document.createElement("input");d.type="range",d.className="kalotyp-output-quality",d.min="50",d.max="100",d.step="1",d.value=String(Math.round(o.get().quality*100)),d.setAttribute("aria-label","Output quality"),d.addEventListener("input",()=>{o.update(R=>Eo(R,d.valueAsNumber/100))}),l.appendChild(d);const h=document.createElement("span");h.className="kalotyp-output-quality-readout",h.setAttribute("aria-hidden","true"),h.textContent=`${Math.round(o.get().quality*100)}`,l.appendChild(h);const f=document.createElement("p");f.className="kalotyp-output-summary",f.setAttribute("aria-live","polite");const m=document.createElement("label");m.className="kalotyp-output-metadata-row";const g=document.createElement("input");g.type="checkbox",g.className="kalotyp-output-metadata-checkbox",g.checked=o.get().stripMetadata,g.addEventListener("change",()=>{o.update(R=>Ao(R,g.checked))});const p=document.createElement("span");p.className="kalotyp-output-metadata-text",p.textContent="Strip EXIF, GPS, and camera metadata on save",m.appendChild(g),m.appendChild(p);const w=document.createElement("p");w.className="kalotyp-output-metadata-hint",w.setAttribute("aria-live","polite");const y=document.createElement("footer");y.className="kalotyp-output-footer";const C=document.createElement("button");C.type="button",C.className="kalotyp-output-done",C.textContent="Done",C.setAttribute("aria-label","Close output settings"),C.addEventListener("click",()=>S.close());const E=document.createElement("button");E.type="button",E.className="kalotyp-output-save",E.textContent="Save and close",E.addEventListener("click",()=>{t.canSave()&&t.onSaveAndClose()}),y.appendChild(C),y.appendChild(E),i.appendChild(r),i.appendChild(c),i.appendChild(l),i.appendChild(f),i.appendChild(m),i.appendChild(w),i.appendChild(y),n.setAttribute("aria-expanded","true");const S=he({host:e,anchor:n,title:"Output settings",body:i,variant:"kalotyp-output-popover",showCloseButton:!0,onClose:()=>{n.setAttribute("aria-expanded","false"),H(),t.onClose()}});function M(R){s.value!==R.mimeChoice&&(s.value=R.mimeChoice);const A=Math.round(R.quality*100);d.valueAsNumber!==A&&(d.value=String(A)),h.textContent=String(A);const T=pe.find(O=>O.value===R.mimeChoice);c.textContent=T?.description??"",f.textContent=Hs(R);const $=R.mimeChoice!=="image/png";d.disabled=!$,h.style.opacity=$?"1":"0.4",g.checked!==R.stripMetadata&&(g.checked=R.stripMetadata),w.textContent=Os(R),E.disabled=!t.canSave()}M(o.get());const H=o.subscribe(M);return(async()=>{for(const R of pe){if(R.requires.length===0)continue;if(!(await Promise.all(R.requires.map(T=>dt(T)))).every(Boolean)){const T=s.querySelector(`option[value="${R.value}"]`);T&&(T.disabled=!0,T.textContent=`${R.label} (unsupported)`)}}})(),{close:()=>S.close()}}function Hs(t){if(t.mimeChoice==="image/png")return"PNG · lossless";const e=Math.round(t.quality*100);switch(t.mimeChoice){case"auto":return`Auto · ${e}% quality`;case"image/webp":return`WebP · ${e}% quality`;case"image/avif":return`AVIF · ${e}% quality`;case"image/jpeg":return`JPEG · ${e}% quality`;default:return`${t.mimeChoice} · ${e}% quality`}}function Os(t){return t.stripMetadata?"":t.mimeChoice==="image/jpeg"?"EXIF preserved when the source is also JPEG.":t.mimeChoice==="auto"?"Metadata is preserved only when the resolved output is JPEG.":"Metadata can only be preserved when the output is JPEG."}const X={outputMimeChoice:"auto",outputQuality:.85,outputStripMetadata:!0,rememberAnnotationStyle:!0,rememberFilter:!0,rememberFrame:!0,lastAnnotationColor:"#ff3b30",lastAnnotationStrokeWidth:4,lastFilterPresetId:null,lastFramePresetId:null,lastFrameColor:"#000000"},zs="kalotyp:prefs:v1";function Bs(t){if(typeof t=="string")try{const e=new URL(t),n=e.pathname,o=n.indexOf("/content/"),i=o===-1?"":n.slice(0,o);return`${e.origin}${i}`}catch{}return typeof window<"u"?window.location.origin:"default"}function Vn(t){return`${zs}:${t}`}function _s(t){try{if(typeof localStorage>"u")return X;const e=localStorage.getItem(Vn(t));if(!e)return X;const n=JSON.parse(e);return Qn(n)}catch{return X}}function jn(t,e){try{if(typeof localStorage>"u")return;const n=Qn(e);localStorage.setItem(Vn(t),JSON.stringify(n))}catch{}}function Qn(t){const e=Ws(t.outputMimeChoice)?t.outputMimeChoice:X.outputMimeChoice,n=Jn(t.outputQuality,0,1,X.outputQuality),o=typeof t.outputStripMetadata=="boolean"?t.outputStripMetadata:X.outputStripMetadata,i=typeof t.rememberAnnotationStyle=="boolean"?t.rememberAnnotationStyle:X.rememberAnnotationStyle,r=typeof t.rememberFilter=="boolean"?t.rememberFilter:X.rememberFilter,a=typeof t.rememberFrame=="boolean"?t.rememberFrame:X.rememberFrame,s=typeof t.lastAnnotationColor=="string"?t.lastAnnotationColor:X.lastAnnotationColor,c=Jn(t.lastAnnotationStrokeWidth,1,40,X.lastAnnotationStrokeWidth),l=t.lastFilterPresetId===null||typeof t.lastFilterPresetId=="string"?t.lastFilterPresetId:X.lastFilterPresetId,u=t.lastFramePresetId===null||typeof t.lastFramePresetId=="string"?t.lastFramePresetId:X.lastFramePresetId,d=typeof t.lastFrameColor=="string"?t.lastFrameColor:X.lastFrameColor;return{outputMimeChoice:e,outputQuality:n,outputStripMetadata:o,rememberAnnotationStyle:i,rememberFilter:r,rememberFrame:a,lastAnnotationColor:s,lastAnnotationStrokeWidth:c,lastFilterPresetId:l,lastFramePresetId:u,lastFrameColor:d}}function Ws(t){return t==="auto"||t==="image/png"||t==="image/jpeg"||t==="image/webp"||t==="image/avif"}function Jn(t,e,n,o){return typeof t!="number"||!Number.isFinite(t)?o:t<e?e:t>n?n:t}const qs=[{value:"auto",label:"Auto (recommended)"},{value:"image/webp",label:"WebP"},{value:"image/avif",label:"AVIF"},{value:"image/jpeg",label:"JPEG"},{value:"image/png",label:"PNG"}];function Us(t){let e=t.initial;function n(E){e={...e,...E},t.onChange(e)}const o=document.createElement("div");o.className="kalotyp-preferences-body";const i=document.createElement("section");i.className="kalotyp-preferences-section",i.innerHTML="<h4>Output defaults</h4>";const r=Zn("Format"),a=document.createElement("select");a.className="kalotyp-output-format",a.setAttribute("aria-label","Default output format");for(const E of qs){const S=document.createElement("option");S.value=E.value,S.textContent=E.label,a.appendChild(S)}a.value=e.outputMimeChoice,a.addEventListener("change",()=>{n({outputMimeChoice:a.value})}),r.appendChild(a),i.appendChild(r);const s=Zn("Quality"),c=document.createElement("input");c.type="range",c.className="kalotyp-output-quality",c.min="50",c.max="100",c.step="1",c.value=String(Math.round(e.outputQuality*100)),c.setAttribute("aria-label","Default output quality"),c.addEventListener("input",()=>{n({outputQuality:c.valueAsNumber/100}),l.textContent=String(c.valueAsNumber)});const l=document.createElement("span");l.className="kalotyp-output-quality-readout",l.textContent=String(Math.round(e.outputQuality*100)),l.setAttribute("aria-hidden","true"),s.appendChild(c),s.appendChild(l),i.appendChild(s);const u=Bt("Strip EXIF, GPS, and camera metadata on save",e.outputStripMetadata,E=>n({outputStripMetadata:E}));i.appendChild(u);const d=document.createElement("section");d.className="kalotyp-preferences-section",d.innerHTML="<h4>Remember across sessions</h4>";const h=Bt("Annotation style (colour + stroke width)",e.rememberAnnotationStyle,E=>n({rememberAnnotationStyle:E})),f=Bt("Last filter preset",e.rememberFilter,E=>n({rememberFilter:E})),m=Bt("Last frame preset",e.rememberFrame,E=>n({rememberFrame:E}));d.appendChild(h),d.appendChild(f),d.appendChild(m);const g=document.createElement("footer");g.className="kalotyp-preferences-footer";const p=document.createElement("button");p.type="button",p.className="kalotyp-preferences-reset",p.textContent="Reset to defaults",p.addEventListener("click",()=>{e={...X},t.onChange(e),C(e)});const w=document.createElement("button");w.type="button",w.className="kalotyp-preferences-done",w.textContent="Done",w.addEventListener("click",()=>y.close()),g.appendChild(p),g.appendChild(w),o.appendChild(i),o.appendChild(d),o.appendChild(g);const y=he({host:t.host,title:"Preferences",body:o,variant:"kalotyp-preferences-modal",showCloseButton:!0,onClose:t.onClose});function C(E){a.value=E.outputMimeChoice,c.value=String(Math.round(E.outputQuality*100)),l.textContent=String(Math.round(E.outputQuality*100)),_t(u,E.outputStripMetadata),_t(h,E.rememberAnnotationStyle),_t(f,E.rememberFilter),_t(m,E.rememberFrame)}return{close:()=>y.close()}}function Zn(t){const e=document.createElement("div");e.className="kalotyp-output-row";const n=document.createElement("span");return n.className="kalotyp-output-row-label",n.textContent=t,e.appendChild(n),e}function Bt(t,e,n){const o=document.createElement("label");o.className="kalotyp-preferences-toggle";const i=document.createElement("input");i.type="checkbox",i.checked=e,i.addEventListener("change",()=>n(i.checked));const r=document.createElement("span");return r.textContent=t,o.appendChild(i),o.appendChild(r),o}function _t(t,e){const n=t.querySelector('input[type="checkbox"]');n&&n.checked!==e&&(n.checked=e)}const Xs=[{keys:["?"],description:"Show keyboard shortcuts",context:"editor"},{keys:["Esc"],description:"Close editor (or clear current selection)",context:"editor"},{keys:["Ctrl","Z"],description:"Undo",context:"editor"},{keys:["Ctrl","Shift","Z"],description:"Redo",context:"editor"},{keys:["Ctrl","Y"],description:"Redo (alternate)",context:"editor"},{keys:["Tab"],description:"Move focus to next control",context:"editor"},{keys:["Shift","Tab"],description:"Move focus to previous control",context:"editor"},{keys:["Delete"],description:"Delete the selected shape",context:"annotate"},{keys:["Arrow keys"],description:"Nudge the selected shape by 1 px",context:"annotate"},{keys:["Shift","Arrow keys"],description:"Nudge the selected shape by 10 px",context:"annotate"},{keys:["Shift","while drawing"],description:"Constrain shape (square, 45° line, circle)",context:"annotate"},{keys:["Delete"],description:"Delete the selected redaction region",context:"redact"},{keys:["Arrow keys"],description:"Nudge the selected region by 1 px",context:"redact"},{keys:["Shift","Arrow keys"],description:"Nudge the selected region by 10 px",context:"redact"},{keys:["Enter"],description:"Commit the text and close the editor",context:"text"},{keys:["Shift","Enter"],description:"Insert a line break",context:"text"},{keys:["Esc"],description:"Cancel the in-progress edit",context:"text"}],Ys={editor:"Editor",annotate:"Annotate",redact:"Redact",text:"Text editing"},Gs=["editor","annotate","redact","text"];function Ks(t){const e=document.createElement("div");e.className="kalotyp-cheatsheet-body";for(const o of Gs){const i=Xs.filter(r=>r.context===o);i.length!==0&&e.appendChild(Vs(o,i))}const n=he({host:t.host,title:"Keyboard shortcuts",body:e,variant:"kalotyp-cheatsheet-modal",showCloseButton:!0,onClose:t.onClose});return{close:()=>n.close()}}function Vs(t,e){const n=document.createElement("section");n.className="kalotyp-cheatsheet-section";const o=document.createElement("h4");o.className="kalotyp-cheatsheet-heading",o.textContent=Ys[t],n.appendChild(o);const i=document.createElement("dl");i.className="kalotyp-cheatsheet-list";for(const r of e){const a=document.createElement("dt");a.className="kalotyp-cheatsheet-keys",r.keys.forEach((c,l)=>{if(l>0){const d=document.createElement("span");d.className="kalotyp-cheatsheet-plus",d.setAttribute("aria-hidden","true"),d.textContent="+",a.appendChild(d)}const u=document.createElement("kbd");u.className="kalotyp-cheatsheet-kbd",u.textContent=c,a.appendChild(u)});const s=document.createElement("dd");s.className="kalotyp-cheatsheet-description",s.textContent=r.description,i.appendChild(a),i.appendChild(s)}return n.appendChild(i),n}const js=[[void 0,"Custom"],[1,"Square"],[2,"2:1"],[1.5,"3:2"],[4/3,"4:3"],[1.6,"16:10"],[16/9,"16:9"],[.5,"1:2"],[2/3,"2:3"],[.75,"3:4"],[10/16,"10:16"],[9/16,"9:16"]];async function Qs(t){return t instanceof File?t:t instanceof Blob?new File([t],"kalotyp-image.png",{type:t.type||"image/png"}):Js(t)}async function Js(t){const e=new URL(t,typeof window<"u"?window.location.href:"http://localhost"),n=await fetch(e.href,{credentials:"omit",mode:"cors"});if(!n.ok)throw new Error(`Source fetch failed: ${n.status} ${n.statusText}`);const o=await n.blob(),i=Zs(e,o.type);return new File([o],i,{type:o.type||"application/octet-stream"})}function Zs(t,e){const n=t.pathname.split("/").pop();return n&&/\.[a-z0-9]{2,5}$/i.test(n)?n:`kalotyp-image.${e.split("/")[1]??"bin"}`}const tc={sourceToFile:Qs,loadImage:oo,encodeSourceImage:Fo,createCropPlugin:Qr,createRotatePlugin:ca,createFlipPlugin:ta,createFinetunePlugin:ga,createFilterPlugin:ka,createAnnotatePlugin:is,createRedactPlugin:ks,createResizePlugin:da,createFramePlugin:Rs,runUtilityChain:Oo},me=[{id:"crop",label:"Crop"},{id:"rotate",label:"Rotate"},{id:"flip",label:"Flip"},{id:"filter",label:"Filter"},{id:"finetune",label:"Finetune"},{id:"annotate",label:"Annotate"},{id:"redact",label:"Redact"},{id:"resize",label:"Resize"},{id:"frame",label:"Frame"}];function to(t,e=tc){const n=new rt,o=new rt,i=new ao,r=rc(t),a=document.createElement("div");a.dataset.kalotypHost="",document.body.appendChild(a);let s=!1,c=!1;const l=Bs(t.src);let u=_s(l),d;function h(){d!==void 0&&clearTimeout(d),d=setTimeout(()=>{d=void 0,jn(l,u)},250)}function f(v){u={...u,...v},h()}const m=Ae({mimeChoice:u.outputMimeChoice,quality:u.outputQuality,stripMetadata:u.outputStripMetadata});m.subscribe(v=>{f({outputMimeChoice:v.mimeChoice,outputQuality:v.quality,outputStripMetadata:v.stripMetadata})});let g=null,p=null,w=null;const y={slots:new Map,sourceImage:void 0,sourceName:void 0,sourceFile:void 0,active:void 0,statusElement:void 0,history:void 0,committedChain:[],workingImage:void 0},C=kr({host:a,exportLabel:r,onExportClick:()=>{b()},onCloseClick:()=>{O()},onOutputSettingsClick:()=>{x()},onPrefsClick:()=>{N()}}),E=ic(t),S=Ns(me,E,v=>{W(v)},{panelId:C.utilMain.id});for(const v of S.buttons.values())v.disabled=!0;C.navTools.appendChild(S.container);const M=cc({onUndo:()=>D(),onRedo:()=>G()});M.undoButton.disabled=!0,M.redoButton.disabled=!0,C.modal.appendChild(M.container),C.exportButton.disabled=!0,eo(C.stage,"Loading image…",y);const H=Ts({host:C.editor,initialFocus:C.editor});C.announce("Image editor opened. Use Tab to navigate."),ec(C,t,y,e,S,E,o,i).then(()=>{C.exportButton.disabled=!1;for(const z of S.buttons.values())z.disabled=!1;no(y),_(),ac(y,u,f);const v=y.sourceImage?.width??0,I=y.sourceImage?.height??0;C.announce(`Image loaded. ${v} by ${I} pixels.`)},v=>{const I=v instanceof Error?v.message:"Failed to load image";n.emit("loaderror",{message:I,cause:v}),eo(C.stage,I,y),C.announce(`Failed to load image. ${I}`)});const R=o.on("commit",()=>{c||y.history&&(y.history.commit(bt(y)),_())}),A=o.on("announce",({message:v})=>{C.announce(v)}),T=lc({onUndo:()=>D(),onRedo:()=>G(),onEscape:()=>$(),onCheatsheet:()=>F()});function $(){L||(y.history?.canUndo()??!1)&&!window.confirm("You have unsaved changes. Discard them and close?")||O()}function O(){const v=t.willClose;return(v?v():!0)?(P(),!0):!1}async function W(v){if(!y.sourceImage||y.active?.id===v)return;const I=y.slots.get(v);if(!I)return;U()&&await nc(y,o,i),y.active?.handle.destroy(),y.active=void 0,Gn(S,v,C.utilMain),i.resetPan();const K={source:y.workingImage??y.sourceImage,bus:o,viewport:i},tt=I.plugin.mount(C.stage,K,I.store);y.active={id:v,handle:tt},y.history&&(y.history.commit(bt(y)),_())}function U(){if(!y.active)return!1;const v=y.active.id,I=v==="filter"?"finetune":v,z=y.slots.get(I);return z?!ge(I,z.store.get()):!1}function _(){M.undoButton.disabled=!y.history?.canUndo(),M.redoButton.disabled=!y.history?.canRedo()}function D(){if(!y.history)return;const v=y.history.undo(bt(y));v&&V(v)}function G(){if(!y.history)return;const v=y.history.redo(bt(y));v&&V(v)}async function V(v){c=!0;try{const q=v.snapshot.get(fe);q!==void 0&&(y.committedChain=q.map(K=>({id:K.id,state:K.state})),await oc(y,e));for(const[K,tt]of v.snapshot){if(K===fe)continue;const wt=y.slots.get(K);wt&&wt.store.update(()=>tt)}}finally{c=!1}_();const I=y.active?.id;if(I){const q=y.slots.get(I);if(q&&y.workingImage){y.active?.handle.destroy();const K={source:y.workingImage,bus:o,viewport:i},tt=q.plugin.mount(C.stage,K,q.store);y.active={id:I,handle:tt}}}if(I&&v.changed.has(I))return;const z=Y(v.changed);z&&z!==I&&await W(z)}function Y(v){for(const I of me)if(v.has(I.id))return I.id}function x(){if(g){g.close();return}g=Ds({host:C.editor,anchor:C.outputSettingsButton,store:m,canSave:()=>!s&&!C.exportButton.disabled,onSaveAndClose:()=>{g?.close(),b()},onClose:()=>{g=null}})}function F(){if(w){w.close();return}w=Ks({host:C.editor,onClose:()=>{w=null}})}function N(){if(p){p.close();return}p=Us({host:C.editor,initial:u,onChange:v=>{u=v,m.set({mimeChoice:v.outputMimeChoice,quality:v.outputQuality,stripMetadata:v.outputStripMetadata}),h()},onClose:()=>{p=null}})}async function b(){if(!s&&!(!y.sourceImage||y.slots.size===0)){s=!0;try{const v=y.workingImage??y.sourceImage;let I=v;const z=y.active;if(z){const tt=y.slots.get(z.id);if(tt){const wt=tt.store.get();ge(z.id,wt)||(I=await tt.plugin.bake(wt,v))}}const q={output:m.get(),...y.sourceName?{sourceName:y.sourceName}:{},...y.sourceFile?{sourceBlob:y.sourceFile}:{}},K=await e.encodeSourceImage(I,q);n.emit("process",{dest:K}),C.announce("Image saved."),P()}catch(v){const I=v instanceof Error?v.message:"Failed to export image";n.emit("loaderror",{message:I,cause:v}),C.announce(`Save failed. ${I}`)}finally{s=!1}}}const k=Ps(C.stage,i);let L=!1;function P(){L||(L=!0,g?.close(),g=null,p?.close(),p=null,w?.close(),w=null,d!==void 0&&(clearTimeout(d),d=void 0,jn(l,u)),y.active?.handle.destroy(),R(),A(),T(),k(),i.clear(),H.release(),C.destroy(),a.remove(),n.clear(),o.clear())}return{on(v,I){n.on(v,I)},off(v,I){n.off(v,I)}}}async function ec(t,e,n,o,i,r,a,s){const c=await o.sourceToFile(e.src),l=await o.loadImage(c),u={bitmap:l.element,width:l.width,height:l.height,mimeType:c.type||"image/png"},d=e.cropSelectPresetOptions??js,h=e.cropSelectPresetFilter,f=o.createCropPlugin({presets:d,presetFilter:h,panelHost:t.utilMain}),m=o.createRotatePlugin({panelHost:t.utilMain}),g=o.createFlipPlugin({panelHost:t.utilMain}),p=o.createFinetunePlugin({panelHost:t.utilMain}),w=o.createFilterPlugin({panelHost:t.utilMain}),y=o.createAnnotatePlugin({panelHost:t.utilMain}),C=o.createRedactPlugin({panelHost:t.utilMain}),E=o.createResizePlugin({panelHost:t.utilMain}),S=o.createFramePlugin({panelHost:t.utilMain,labels:sc(e)}),M={source:u,bus:a,viewport:s};ot(n,f,M),ot(n,m,M),ot(n,g,M),ot(n,p,M);const H=n.slots.get("finetune");H&&n.slots.set("filter",{id:"filter",plugin:w,store:H.store}),ot(n,y,M),ot(n,C,M),ot(n,E,M),ot(n,S,M),n.sourceImage=u,n.sourceName=c.name,n.sourceFile=c,n.workingImage=u,n.committedChain=[],n.history=new uo(bt(n));const R=n.slots.get(r);if(!R)return;const A={source:n.workingImage,bus:a,viewport:s},T=R.plugin.mount(t.stage,A,R.store);n.active={id:r,handle:T},Gn(i,r,t.utilMain)}function ot(t,e,n){const o=e.init(n),i=Ae(o);t.slots.set(e.id,{id:e.id,plugin:e,store:i})}const fe="__committedChain__";function bt(t){const e=new Map;for(const[n,o]of t.slots)e.set(n,o.store.get());return e.set(fe,t.committedChain),e}function ge(t,e){switch(t){case"crop":{const n=e;return!n.rect||!n.imageSize?!1:n.rect.x===0&&n.rect.y===0&&n.rect.width===n.imageSize.width&&n.rect.height===n.imageSize.height}case"rotate":{const n=e;return typeof n.quarterTurns!="number"||typeof n.freeAngle!="number"?!1:We(n)}case"flip":{const n=e;return typeof n.horizontal!="boolean"||typeof n.vertical!="boolean"?!1:ze(n)}case"finetune":case"filter":{const n=e;return n?Gt(n):!1}case"annotate":{const n=e.shapes;return Array.isArray(n)&&n.length===0}case"redact":{const n=e.regions;return Array.isArray(n)&&n.length===0}case"resize":{const n=e;return typeof n.scaleX!="number"||typeof n.scaleY!="number"?!1:Xe(n)}case"frame":{const n=e;return n.presetId?gn(n):!1}default:return!0}}async function nc(t,e,n){if(!t.active||!t.workingImage)return;const o=t.active.id,i=o==="filter"?"finetune":o,r=t.slots.get(i);if(!r)return;const a=r.store.get();if(ge(i,a))return;const s=await r.plugin.bake(a,t.workingImage);t.workingImage=s,t.committedChain.push({id:r.id,state:structuredClone(a)});const c={source:t.workingImage,bus:e,viewport:n},l=r.plugin.init(c);r.store.update(()=>l)}async function oc(t,e){if(!t.sourceImage)return;const n=[];for(const o of t.committedChain){const i=t.slots.get(o.id);i&&n.push({id:o.id,plugin:i.plugin,state:o.state})}if(n.length===0){t.workingImage=t.sourceImage;return}t.workingImage=await e.runUtilityChain(n,t.sourceImage)}function ic(t){const e=t.util;if(typeof e!="string")return"crop";for(const n of me)if(n.id===e)return n.id;return"crop"}function eo(t,e,n){no(n);const o=document.createElement("div");o.className="kalotyp-stage-status",o.setAttribute("role","status"),o.textContent=e,t.appendChild(o),n.statusElement=o}function no(t){t.statusElement?.remove(),t.statusElement=void 0}function rc(t){const e=t.locale?.labelButtonExport;return typeof e=="string"&&e.length>0?e:"Save and close"}function ac(t,e,n){if(e.rememberAnnotationStyle){const o=t.slots.get("annotate");if(o){const i=o.store;i.update(r=>({...r,currentStyle:{...r.currentStyle,color:e.lastAnnotationColor,strokeWidth:e.lastAnnotationStrokeWidth}})),i.subscribe(r=>{n({lastAnnotationColor:r.currentStyle.color,lastAnnotationStrokeWidth:r.currentStyle.strokeWidth})})}}if(e.rememberFilter&&e.lastFilterPresetId!==null){const o=t.slots.get("finetune"),i=Vt.find(r=>r.id===e.lastFilterPresetId);o&&i&&o.store.update(()=>i.state)}if(e.rememberFilter){const o=t.slots.get("finetune");o&&o.store.subscribe(r=>{const a=jt(r);n({lastFilterPresetId:a?.id??null})})}if(e.rememberFrame){const o=t.slots.get("frame");if(o){const i=o.store;e.lastFramePresetId&&i.update(()=>({presetId:e.lastFramePresetId,color:e.lastFrameColor})),i.subscribe(r=>{n({lastFramePresetId:r.presetId,lastFrameColor:r.color})})}}}function sc(t){const e=t.frameOptions;if(!Array.isArray(e))return;const n=t.locale??{},o={};for(const i of e){if(!Array.isArray(i))continue;const[r,a]=i,s=r===void 0?"none":r;try{const c=a(n);typeof c=="string"&&c.length>0&&(o[s]=c)}catch{}}return Object.keys(o).length===0?void 0:o}function cc(t){const e=document.createElement("div");e.className="kalotyp-history-controls",e.setAttribute("role","group"),e.setAttribute("aria-label","Edit history");const n=document.createElement("button");n.type="button",n.className="kalotyp-history-button kalotyp-history-undo",n.setAttribute("aria-label","Undo"),n.title="Undo (Ctrl+Z)",n.innerHTML=B("undo"),n.addEventListener("click",t.onUndo);const o=document.createElement("button");return o.type="button",o.className="kalotyp-history-button kalotyp-history-redo",o.setAttribute("aria-label","Redo"),o.title="Redo (Ctrl+Shift+Z)",o.innerHTML=B("redo"),o.addEventListener("click",t.onRedo),e.appendChild(n),e.appendChild(o),{container:e,undoButton:n,redoButton:o}}function lc(t){const e=n=>{if(n.key==="Escape"){n.preventDefault(),t.onEscape();return}const o=n.target;if(uc(o))return;if(n.key==="?"&&!n.ctrlKey&&!n.metaKey&&!n.altKey){n.preventDefault(),t.onCheatsheet();return}if(n.ctrlKey||n.metaKey){if(n.key==="z"||n.key==="Z"){n.preventDefault(),n.shiftKey?t.onRedo():t.onUndo();return}(n.key==="y"||n.key==="Y")&&(n.preventDefault(),t.onRedo())}};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)}function uc(t){if(!t)return!1;const e=t.tagName;return e==="INPUT"||e==="TEXTAREA"||e==="SELECT"?!0:t.isContentEditable===!0}function dc(t=globalThis){const e=t.pintura;e&&typeof e=="object"||Object.defineProperty(t,"pintura",{value:{openDefaultEditor:to},writable:!0,configurable:!0,enumerable:!0})}typeof window<"u"&&dc(globalThis),it.openDefaultEditor=to,Object.defineProperty(it,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Resolve any source input into a `File`. A `File` (not a `Blob`) is
3
+ * required so the upload gets a sensible name: `gh-uploader.js:330` calls
4
+ * `formData.append(this.paramName, file, file.name)` (contract §4.2).
5
+ */
6
+ export declare function sourceToFile(src: string | Blob | File): Promise<File>;
7
+ //# sourceMappingURL=source-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-image.d.ts","sourceRoot":"","sources":["../src/source-image.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@magicpages/kalotyp",
3
+ "version": "0.1.0",
4
+ "description": "Kalotyp — an open-source image editor for Ghost CMS. The bundle Ghost loads (kalotyp.js + kalotyp.css).",
5
+ "license": "MIT",
6
+ "author": "Jannis Fedoruk-Betschki <jannis@magicpages.co>",
7
+ "homepage": "https://github.com/magicpages/kalotyp#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/magicpages/kalotyp.git",
11
+ "directory": "packages/ghost"
12
+ },
13
+ "bugs": "https://github.com/magicpages/kalotyp/issues",
14
+ "keywords": [
15
+ "ghost",
16
+ "ghost-cms",
17
+ "image-editor",
18
+ "koenig"
19
+ ],
20
+ "type": "module",
21
+ "main": "./dist/kalotyp.js",
22
+ "types": "./dist/index.d.ts",
23
+ "unpkg": "./dist/kalotyp.js",
24
+ "jsdelivr": "./dist/kalotyp.js",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/kalotyp.js"
29
+ },
30
+ "./styles.css": "./dist/kalotyp.css"
31
+ },
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public",
37
+ "provenance": true
38
+ },
39
+ "scripts": {
40
+ "build": "vite build && tsc -p tsconfig.build.json",
41
+ "dev": "vite build --watch",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "typecheck": "tsc --noEmit"
45
+ },
46
+ "dependencies": {
47
+ "@magicpages/kalotyp-core": "workspace:*",
48
+ "@magicpages/kalotyp-ui": "workspace:*"
49
+ },
50
+ "devDependencies": {
51
+ "typescript": "5.6.3",
52
+ "vite": "5.4.10",
53
+ "vitest": "2.1.5",
54
+ "jsdom": "25.0.1"
55
+ }
56
+ }