@inkbar/svelte 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/components/InkFindBar.svelte +213 -0
- package/dist/components/InkFindBar.svelte.d.ts +6 -0
- package/dist/components/InkFindBar.svelte.d.ts.map +1 -0
- package/dist/components/InkFormAlert.svelte +108 -0
- package/dist/components/InkFormAlert.svelte.d.ts +13 -0
- package/dist/components/InkFormAlert.svelte.d.ts.map +1 -0
- package/dist/components/InkRoot.svelte +136 -4
- package/dist/components/InkRoot.svelte.d.ts +22 -2
- package/dist/components/InkRoot.svelte.d.ts.map +1 -1
- package/dist/components/InkSearchButton.svelte +56 -0
- package/dist/components/InkSearchButton.svelte.d.ts +5 -0
- package/dist/components/InkSearchButton.svelte.d.ts.map +1 -0
- package/dist/components/InkSignFieldPopover.svelte +187 -0
- package/dist/components/InkSignFieldPopover.svelte.d.ts +10 -0
- package/dist/components/InkSignFieldPopover.svelte.d.ts.map +1 -0
- package/dist/components/InkSignatureDialog.svelte +11 -3
- package/dist/components/InkSignatureDialog.svelte.d.ts +9 -3
- package/dist/components/InkSignatureDialog.svelte.d.ts.map +1 -1
- package/dist/components/InkSignatureMenu.svelte +10 -99
- package/dist/components/InkSignatureMenu.svelte.d.ts.map +1 -1
- package/dist/components/InkViewport.svelte +46 -1
- package/dist/components/InkViewport.svelte.d.ts.map +1 -1
- package/dist/components/SignatureForm.svelte +7 -2
- package/dist/components/SignatureForm.svelte.d.ts +2 -0
- package/dist/components/SignatureForm.svelte.d.ts.map +1 -1
- package/dist/components/SignatureMenuPanel.svelte +127 -0
- package/dist/components/SignatureMenuPanel.svelte.d.ts +13 -0
- package/dist/components/SignatureMenuPanel.svelte.d.ts.map +1 -0
- package/dist/components/search-button.d.ts +10 -0
- package/dist/components/search-button.d.ts.map +1 -0
- package/dist/components/search-button.js +1 -0
- package/dist/context.d.ts +14 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/hooks/useForm.svelte.d.ts +17 -0
- package/dist/hooks/useForm.svelte.d.ts.map +1 -0
- package/dist/hooks/useForm.svelte.js +20 -0
- package/dist/hooks/useSearch.svelte.d.ts +11 -0
- package/dist/hooks/useSearch.svelte.d.ts.map +1 -0
- package/dist/hooks/useSearch.svelte.js +31 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/package.json +6 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ChildSnippet } from './child-snippet.js';
|
|
2
|
-
import type { Annotation, AnnotationChange, AnnotationDefaults, DocumentSource, InkDocument, InkError, InkStatus, PdfAssets, SignatureStore } from '@inkbar/core';
|
|
2
|
+
import type { Annotation, AnnotationChange, AnnotationDefaults, DocumentSource, FieldsChange, FieldValues, FormAction, InkDocument, InkError, InkStatus, PdfAssets, SignatureStore } from '@inkbar/core';
|
|
3
3
|
import type { DecorateAnnotation, InkPlugin, Tool, ToolId, ZoomValue } from '@inkbar/core/dom';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
@@ -17,6 +17,21 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
|
|
|
17
17
|
annotations?: Annotation[] | undefined;
|
|
18
18
|
onAnnotationsChange?: ((next: Annotation[]) => void) | undefined;
|
|
19
19
|
onChange?: ((change: AnnotationChange) => void) | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Pass (with `bind:`) to put the form's field values under the host's control. A commit
|
|
22
|
+
* shows at once and is reported after; the host's push wins. The mode is fixed when a
|
|
23
|
+
* document opens, as for `annotations`.
|
|
24
|
+
*/
|
|
25
|
+
fields?: FieldValues | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Committed field values, in full, with what changed them. Called only while the fields
|
|
28
|
+
* are controlled, after the bound value is written.
|
|
29
|
+
*/
|
|
30
|
+
onFieldsChange?: ((next: FieldValues, change: FieldsChange) => void) | undefined;
|
|
31
|
+
/** The form asked to submit, open a link, send mail, print or prompt. Inkbar does none. */
|
|
32
|
+
onformaction?: ((action: FormAction) => void) | undefined;
|
|
33
|
+
/** Tints fillable form fields. Default true. A change applies to the open document in place. */
|
|
34
|
+
formHighlight?: boolean | undefined;
|
|
20
35
|
tool?: ToolId | undefined;
|
|
21
36
|
onToolChange?: ((tool: ToolId) => void) | undefined;
|
|
22
37
|
/**
|
|
@@ -57,6 +72,11 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
|
|
|
57
72
|
/** Undo history. Defaults to on for uncontrolled, off for controlled. */
|
|
58
73
|
history?: boolean | undefined;
|
|
59
74
|
onReady?: ((doc: InkDocument) => void) | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Opening failed, or later: a form script failed (`FormScriptError`; the form stays
|
|
77
|
+
* fillable), or a signature field refused its signing (`FieldSigned`, `FieldReadOnly`).
|
|
78
|
+
* An error from while the document opened comes after `onReady`.
|
|
79
|
+
*/
|
|
60
80
|
onError?: ((error: InkError) => void) | undefined;
|
|
61
81
|
onActivate?: ((id: string) => void) | undefined;
|
|
62
82
|
/** The root element, for hosts that bind it. */
|
|
@@ -76,7 +96,7 @@ declare const InkRoot: import("svelte").Component<InkRootProps, {
|
|
|
76
96
|
history: InkHistory;
|
|
77
97
|
getDocument: () => InkDocument | null;
|
|
78
98
|
getStatus: () => InkStatus;
|
|
79
|
-
}, "page" | "annotations" | "tool" | "zoom" | "ref">;
|
|
99
|
+
}, "page" | "annotations" | "fields" | "tool" | "zoom" | "ref">;
|
|
80
100
|
type InkRoot = ReturnType<typeof InkRoot>;
|
|
81
101
|
export default InkRoot;
|
|
82
102
|
//# sourceMappingURL=InkRoot.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkRoot.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkRoot.svelte.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"InkRoot.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkRoot.svelte.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* Opens the find bar; pressed while it is open. Pressing it again focuses the field. Place
|
|
4
|
+
* it in a toolbar next to `InkFindBar`, which it needs for the field to focus. Disabled until
|
|
5
|
+
* a document is open.
|
|
6
|
+
*/
|
|
7
|
+
import { Search } from '@inkbar/icons'
|
|
8
|
+
import { Toolbar } from 'bits-ui'
|
|
9
|
+
import { tick } from 'svelte'
|
|
10
|
+
|
|
11
|
+
import { useInkContext } from '../context.js'
|
|
12
|
+
import { useDocument } from '../hooks/useDocument.svelte.js'
|
|
13
|
+
import { useSearch } from '../hooks/useSearch.svelte.js'
|
|
14
|
+
|
|
15
|
+
import { asBitsProps } from './child-snippet.js'
|
|
16
|
+
import InkIcon from './InkIcon.svelte'
|
|
17
|
+
|
|
18
|
+
import type { InkSearchButtonProps } from './search-button.js'
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
class: className,
|
|
22
|
+
children,
|
|
23
|
+
child,
|
|
24
|
+
disabled,
|
|
25
|
+
onclick,
|
|
26
|
+
...rest
|
|
27
|
+
}: InkSearchButtonProps = $props()
|
|
28
|
+
|
|
29
|
+
const ctx = useInkContext('InkSearchButton')
|
|
30
|
+
const search = useSearch()
|
|
31
|
+
const doc = useDocument()
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<Toolbar.Button
|
|
35
|
+
{...asBitsProps(rest)}
|
|
36
|
+
class={['ink-search-button', className]}
|
|
37
|
+
data-ink-search-button=""
|
|
38
|
+
aria-label="Find"
|
|
39
|
+
title="Find"
|
|
40
|
+
aria-pressed={search.state.open}
|
|
41
|
+
data-state={search.state.open ? 'on' : 'off'}
|
|
42
|
+
disabled={!doc.isReady || !!disabled}
|
|
43
|
+
{...child ? { child } : {}}
|
|
44
|
+
onclick={async (e) => {
|
|
45
|
+
onclick?.(e)
|
|
46
|
+
if (e.defaultPrevented) return
|
|
47
|
+
search.open()
|
|
48
|
+
// The bar shows once this update lands; its field takes focus then.
|
|
49
|
+
await tick()
|
|
50
|
+
const field = ctx.rootEl?.querySelector<HTMLInputElement>('[data-ink-find-bar] input')
|
|
51
|
+
field?.focus()
|
|
52
|
+
field?.select()
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
{#if children}{@render children()}{:else}<InkIcon icon={Search} />{/if}
|
|
56
|
+
</Toolbar.Button>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { InkSearchButtonProps } from './search-button.js';
|
|
2
|
+
declare const InkSearchButton: import("svelte").Component<InkSearchButtonProps, {}, "">;
|
|
3
|
+
type InkSearchButton = ReturnType<typeof InkSearchButton>;
|
|
4
|
+
export default InkSearchButton;
|
|
5
|
+
//# sourceMappingURL=InkSearchButton.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InkSearchButton.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSearchButton.svelte.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AA8C/D,QAAA,MAAM,eAAe,0DAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* The signature menu for a signature field, opened from the field's "Sign" button and
|
|
4
|
+
* anchored to its box. It lists the saved signatures and "Create signature", as
|
|
5
|
+
* `InkSignatureMenu` does. Picking one signs the field with it (`signField`); a signature
|
|
6
|
+
* made in `InkSignatureDialog` signs the field once saved, without picking the signature
|
|
7
|
+
* tool. Focus returns to the field. InkViewport mounts it, one per document; hosts compose
|
|
8
|
+
* nothing.
|
|
9
|
+
*/
|
|
10
|
+
import { InkError, signField } from '@inkbar/core'
|
|
11
|
+
import {
|
|
12
|
+
handleMenuKeys,
|
|
13
|
+
SIGNATURE_LABELS,
|
|
14
|
+
signatureMenuModel,
|
|
15
|
+
watchDetached,
|
|
16
|
+
} from '@inkbar/core/dom'
|
|
17
|
+
import { Popover } from 'bits-ui'
|
|
18
|
+
import { untrack } from 'svelte'
|
|
19
|
+
|
|
20
|
+
import { useInkContext } from '../context.js'
|
|
21
|
+
import { useReadable } from '../use-readable.svelte.js'
|
|
22
|
+
|
|
23
|
+
import InkSignatureDialog from './InkSignatureDialog.svelte'
|
|
24
|
+
import { createMenuOpenFocus } from './menu-open-focus.js'
|
|
25
|
+
import SignatureMenuPanel from './SignatureMenuPanel.svelte'
|
|
26
|
+
|
|
27
|
+
import type { InkDocument, SignatureTemplate } from '@inkbar/core'
|
|
28
|
+
import type { SignFieldRequest } from '@inkbar/core/dom'
|
|
29
|
+
|
|
30
|
+
let {
|
|
31
|
+
request,
|
|
32
|
+
onClose,
|
|
33
|
+
}: {
|
|
34
|
+
/** The field to sign; `null` while the menu is closed. */
|
|
35
|
+
request: SignFieldRequest | null
|
|
36
|
+
onClose: () => void
|
|
37
|
+
} = $props()
|
|
38
|
+
|
|
39
|
+
const NO_TEMPLATES: readonly SignatureTemplate[] = []
|
|
40
|
+
|
|
41
|
+
const ctx = useInkContext('InkSignFieldPopover')
|
|
42
|
+
const templates = useReadable(() => ctx.signatures.templates, NO_TEMPLATES)
|
|
43
|
+
// No signature is "chosen" here: each signing picks its own.
|
|
44
|
+
const model = $derived(signatureMenuModel(templates.current, {}))
|
|
45
|
+
const open = $derived(request !== null)
|
|
46
|
+
let menu = $state<HTMLElement | null>(null)
|
|
47
|
+
/** The field the dialog signs once its signature is saved, and the document it is in. */
|
|
48
|
+
let creatingFor = $state.raw<{ req: SignFieldRequest; doc: InkDocument } | null>(null)
|
|
49
|
+
/**
|
|
50
|
+
* The request the menu last opened for, kept to return focus once it closes. Untracked:
|
|
51
|
+
* Bits UI reports the close from an effect teardown, where a reactive read of `request`
|
|
52
|
+
* returns the value from before the close.
|
|
53
|
+
*/
|
|
54
|
+
let last: SignFieldRequest | null = null
|
|
55
|
+
/** Set while the menu closes for the dialog, which takes focus instead of the field. */
|
|
56
|
+
let toDialog = false
|
|
57
|
+
/** Cleared on destroy, so a dialog save that settles after the document went signs nothing. */
|
|
58
|
+
let alive = true
|
|
59
|
+
$effect(() => () => {
|
|
60
|
+
alive = false
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
$effect(() => {
|
|
64
|
+
if (request) last = request
|
|
65
|
+
})
|
|
66
|
+
// The field's box went (its page unmounted, its layer rebuilt): the menu has nothing to
|
|
67
|
+
// stand by.
|
|
68
|
+
$effect(() => {
|
|
69
|
+
const req = request
|
|
70
|
+
if (!req) return
|
|
71
|
+
return watchDetached(req.anchor, () => untrack(onClose))
|
|
72
|
+
})
|
|
73
|
+
// An old removal error is not news when the menu opens again.
|
|
74
|
+
$effect(() => {
|
|
75
|
+
if (open) untrack(() => ctx.signatures.clearRemoveError())
|
|
76
|
+
})
|
|
77
|
+
const openFocus = createMenuOpenFocus()
|
|
78
|
+
$effect(() => {
|
|
79
|
+
if (!open) openFocus.reset()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
/** The field's own button, which focus returns to. */
|
|
83
|
+
const control = (req: SignFieldRequest | null): HTMLElement | null =>
|
|
84
|
+
req?.anchor.querySelector<HTMLElement>('button.ink-form-control') ?? null
|
|
85
|
+
|
|
86
|
+
/** Focus goes back to the field's button, or to the scroll element once the field's box has gone. */
|
|
87
|
+
function returnFocus(req: SignFieldRequest | null): void {
|
|
88
|
+
const c = control(req)
|
|
89
|
+
;(c?.isConnected ? c : ctx.viewportEl.get())?.focus({ preventScroll: true })
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Signs the request's field with `t`; a refusal (signed, read-only by now) goes to `onError`. */
|
|
93
|
+
function sign(req: SignFieldRequest, doc: InkDocument, t: SignatureTemplate): void {
|
|
94
|
+
// The document the request came from is still the open one.
|
|
95
|
+
if (!alive || ctx.document !== doc) return
|
|
96
|
+
try {
|
|
97
|
+
signField(doc, req.field, req.widget, t)
|
|
98
|
+
} catch (e) {
|
|
99
|
+
if (!(e instanceof InkError)) throw e
|
|
100
|
+
ctx.reportError(e)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function choose(t: SignatureTemplate): void {
|
|
105
|
+
const req = request
|
|
106
|
+
const doc = ctx.document
|
|
107
|
+
onClose()
|
|
108
|
+
if (req && doc) sign(req, doc, t)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function create(): void {
|
|
112
|
+
const req = request
|
|
113
|
+
const doc = ctx.document
|
|
114
|
+
if (!req || !doc) return
|
|
115
|
+
toDialog = true
|
|
116
|
+
creatingFor = { req, doc }
|
|
117
|
+
onClose()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function onInteractOutside(e: PointerEvent): void {
|
|
121
|
+
// A press on this field's own button toggles the menu through the engine; it must not
|
|
122
|
+
// also close it here first, or the click would open it again.
|
|
123
|
+
const target = e.target
|
|
124
|
+
if (target instanceof Node && request?.anchor.contains(target)) e.preventDefault()
|
|
125
|
+
}
|
|
126
|
+
</script>
|
|
127
|
+
|
|
128
|
+
<Popover.Root
|
|
129
|
+
bind:open={
|
|
130
|
+
() => open,
|
|
131
|
+
(next) => {
|
|
132
|
+
if (!next) onClose()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
>
|
|
136
|
+
<Popover.Portal>
|
|
137
|
+
{#if request}
|
|
138
|
+
<Popover.Content
|
|
139
|
+
bind:ref={menu}
|
|
140
|
+
role="menu"
|
|
141
|
+
aria-label={SIGNATURE_LABELS.menu}
|
|
142
|
+
class="ink-select-content ink-menu-content"
|
|
143
|
+
data-ink-select-content=""
|
|
144
|
+
data-ink-menu="signature"
|
|
145
|
+
data-ink-sign-field-menu={request.field}
|
|
146
|
+
customAnchor={request.anchor}
|
|
147
|
+
side="bottom"
|
|
148
|
+
align="start"
|
|
149
|
+
sideOffset={4}
|
|
150
|
+
collisionPadding={8}
|
|
151
|
+
onOpenAutoFocus={(e) => openFocus.onOpenAutoFocus(e, menu)}
|
|
152
|
+
onfocusin={openFocus.onfocusin}
|
|
153
|
+
onCloseAutoFocus={(e) => {
|
|
154
|
+
e.preventDefault()
|
|
155
|
+
if (!toDialog) returnFocus(last)
|
|
156
|
+
toDialog = false
|
|
157
|
+
}}
|
|
158
|
+
{onInteractOutside}
|
|
159
|
+
onkeydown={(e) => menu && handleMenuKeys(e, menu)}
|
|
160
|
+
>
|
|
161
|
+
<SignatureMenuPanel
|
|
162
|
+
items={model.items}
|
|
163
|
+
menu={() => menu}
|
|
164
|
+
onChoose={choose}
|
|
165
|
+
onCreate={create}
|
|
166
|
+
/>
|
|
167
|
+
</Popover.Content>
|
|
168
|
+
{/if}
|
|
169
|
+
</Popover.Portal>
|
|
170
|
+
</Popover.Root>
|
|
171
|
+
<InkSignatureDialog
|
|
172
|
+
bind:open={
|
|
173
|
+
() => creatingFor !== null,
|
|
174
|
+
(next) => {
|
|
175
|
+
if (!next) creatingFor = null
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
select={false}
|
|
179
|
+
onSave={(t) => {
|
|
180
|
+
const c = creatingFor
|
|
181
|
+
if (c) sign(c.req, c.doc, t)
|
|
182
|
+
}}
|
|
183
|
+
onCloseAutoFocus={(e) => {
|
|
184
|
+
e.preventDefault()
|
|
185
|
+
returnFocus(last)
|
|
186
|
+
}}
|
|
187
|
+
/>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SignFieldRequest } from '@inkbar/core/dom';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
/** The field to sign; `null` while the menu is closed. */
|
|
4
|
+
request: SignFieldRequest | null;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
};
|
|
7
|
+
declare const InkSignFieldPopover: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type InkSignFieldPopover = ReturnType<typeof InkSignFieldPopover>;
|
|
9
|
+
export default InkSignFieldPopover;
|
|
10
|
+
//# sourceMappingURL=InkSignFieldPopover.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InkSignFieldPopover.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSignFieldPopover.svelte.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAExD,KAAK,gBAAgB,GAAI;IACtB,0DAA0D;IAC1D,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAChC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAC;AA2IJ,QAAA,MAAM,mBAAmB,sDAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
|
|
@@ -4,15 +4,21 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* "Create signature": a modal with Draw, Type and Image tabs. Draw is a pad with the draw
|
|
6
6
|
* tool's renderer; Type sets a name in one of the host's handwriting fonts; Image takes a PNG
|
|
7
|
-
* or JPEG scan. Save stores the template through InkRoot's signature store and
|
|
8
|
-
* for the `signature` tool. Escape, Cancel or a press outside
|
|
7
|
+
* or JPEG scan. Save stores the template through InkRoot's signature store and, unless
|
|
8
|
+
* `select` is false, selects it for the `signature` tool. Escape, Cancel or a press outside
|
|
9
|
+
* closes it.
|
|
9
10
|
*/
|
|
10
11
|
export interface InkSignatureDialogProps {
|
|
11
12
|
open?: boolean
|
|
12
13
|
onOpenChange?: ((open: boolean) => void) | undefined
|
|
13
14
|
/** The fonts the Type tab offers. Default: InkRoot's `signatureFonts`. */
|
|
14
15
|
fonts?: readonly string[] | undefined
|
|
15
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Whether saving selects the new signature for the `signature` tool. Default true. False
|
|
18
|
+
* leaves the tool alone, for a dialog that signs a field with it through `onSave`.
|
|
19
|
+
*/
|
|
20
|
+
select?: boolean | undefined
|
|
21
|
+
/** Called with the new template once it is saved (and selected, with `select`). */
|
|
16
22
|
onSave?: ((template: SignatureTemplate) => void) | undefined
|
|
17
23
|
/** Where focus goes on close; by default, back to what had it before. */
|
|
18
24
|
onCloseAutoFocus?: ((event: Event) => void) | undefined
|
|
@@ -30,6 +36,7 @@
|
|
|
30
36
|
open = $bindable(false),
|
|
31
37
|
onOpenChange,
|
|
32
38
|
fonts,
|
|
39
|
+
select = true,
|
|
33
40
|
onSave,
|
|
34
41
|
onCloseAutoFocus,
|
|
35
42
|
class: className,
|
|
@@ -62,6 +69,7 @@
|
|
|
62
69
|
<Dialog.Title class="ink-dialog-title">{SIGNATURE_LABELS.dialog}</Dialog.Title>
|
|
63
70
|
<SignatureForm
|
|
64
71
|
{fonts}
|
|
72
|
+
{select}
|
|
65
73
|
onSaved={(t) => onSave?.(t)}
|
|
66
74
|
onClose={() => setOpen(false)}
|
|
67
75
|
/>
|
|
@@ -2,15 +2,21 @@ import type { SignatureTemplate } from '@inkbar/core';
|
|
|
2
2
|
/**
|
|
3
3
|
* "Create signature": a modal with Draw, Type and Image tabs. Draw is a pad with the draw
|
|
4
4
|
* tool's renderer; Type sets a name in one of the host's handwriting fonts; Image takes a PNG
|
|
5
|
-
* or JPEG scan. Save stores the template through InkRoot's signature store and
|
|
6
|
-
* for the `signature` tool. Escape, Cancel or a press outside
|
|
5
|
+
* or JPEG scan. Save stores the template through InkRoot's signature store and, unless
|
|
6
|
+
* `select` is false, selects it for the `signature` tool. Escape, Cancel or a press outside
|
|
7
|
+
* closes it.
|
|
7
8
|
*/
|
|
8
9
|
export interface InkSignatureDialogProps {
|
|
9
10
|
open?: boolean;
|
|
10
11
|
onOpenChange?: ((open: boolean) => void) | undefined;
|
|
11
12
|
/** The fonts the Type tab offers. Default: InkRoot's `signatureFonts`. */
|
|
12
13
|
fonts?: readonly string[] | undefined;
|
|
13
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Whether saving selects the new signature for the `signature` tool. Default true. False
|
|
16
|
+
* leaves the tool alone, for a dialog that signs a field with it through `onSave`.
|
|
17
|
+
*/
|
|
18
|
+
select?: boolean | undefined;
|
|
19
|
+
/** Called with the new template once it is saved (and selected, with `select`). */
|
|
14
20
|
onSave?: ((template: SignatureTemplate) => void) | undefined;
|
|
15
21
|
/** Where focus goes on close; by default, back to what had it before. */
|
|
16
22
|
onCloseAutoFocus?: ((event: Event) => void) | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkSignatureDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSignatureDialog.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAErD
|
|
1
|
+
{"version":3,"file":"InkSignatureDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSignatureDialog.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAErD;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACpD,0EAA0E;IAC1E,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC5D,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B;AAmDH,QAAA,MAAM,kBAAkB,iEAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
|
|
@@ -20,15 +20,10 @@
|
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
22
|
<script lang="ts">
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
SIGNATURE_LABELS,
|
|
26
|
-
signatureMenuModel,
|
|
27
|
-
signaturePreview,
|
|
28
|
-
} from '@inkbar/core/dom'
|
|
29
|
-
import { ChevronDown, Plus, Signature, Trash2 } from '@inkbar/icons'
|
|
23
|
+
import { handleMenuKeys, SIGNATURE_LABELS, signatureMenuModel } from '@inkbar/core/dom'
|
|
24
|
+
import { ChevronDown, Signature } from '@inkbar/icons'
|
|
30
25
|
import { Popover, Toolbar } from 'bits-ui'
|
|
31
|
-
import {
|
|
26
|
+
import { untrack } from 'svelte'
|
|
32
27
|
|
|
33
28
|
import { useInkContext } from '../context.js'
|
|
34
29
|
import { useTool } from '../hooks/useTool.svelte.js'
|
|
@@ -38,6 +33,7 @@
|
|
|
38
33
|
import InkIcon from './InkIcon.svelte'
|
|
39
34
|
import InkSignatureDialog from './InkSignatureDialog.svelte'
|
|
40
35
|
import { createMenuOpenFocus } from './menu-open-focus.js'
|
|
36
|
+
import SignatureMenuPanel from './SignatureMenuPanel.svelte'
|
|
41
37
|
|
|
42
38
|
import type { SignatureOptions, SignatureTemplate } from '@inkbar/core'
|
|
43
39
|
|
|
@@ -49,7 +45,6 @@
|
|
|
49
45
|
const current = useTool()
|
|
50
46
|
const signature = useToolOptions<SignatureOptions>('signature')
|
|
51
47
|
const templates = useReadable(() => ctx.signatures.templates, NO_TEMPLATES)
|
|
52
|
-
const removeError = useReadable(() => ctx.signatures.removeError, undefined)
|
|
53
48
|
// An old removal error is not news when the menu opens again.
|
|
54
49
|
$effect(() => {
|
|
55
50
|
if (open) untrack(() => ctx.signatures.clearRemoveError())
|
|
@@ -89,24 +84,6 @@
|
|
|
89
84
|
open = false
|
|
90
85
|
}
|
|
91
86
|
|
|
92
|
-
/** Removes a template; focus moves to the signature now in its row, else "Create signature". */
|
|
93
|
-
function remove(id: string, row: number): void {
|
|
94
|
-
ctx.signatures.remove(id).then(
|
|
95
|
-
async () => {
|
|
96
|
-
await tick()
|
|
97
|
-
if (!menu) return
|
|
98
|
-
const rows = menu.querySelectorAll<HTMLElement>('.ink-signature-item')
|
|
99
|
-
const next =
|
|
100
|
-
rows[Math.min(row, rows.length - 1)] ??
|
|
101
|
-
menu.querySelector<HTMLElement>('[data-ink-signature-create]')
|
|
102
|
-
next?.focus({ preventScroll: true })
|
|
103
|
-
},
|
|
104
|
-
() => {
|
|
105
|
-
// The host's store refused: the signature stays.
|
|
106
|
-
}
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
87
|
function create(): void {
|
|
111
88
|
toDialog = true
|
|
112
89
|
open = false
|
|
@@ -174,78 +151,12 @@
|
|
|
174
151
|
}}
|
|
175
152
|
onkeydown={(e) => menu && handleMenuKeys(e, menu)}
|
|
176
153
|
>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
>
|
|
184
|
-
{#each model.items as item, row (item.id)}
|
|
185
|
-
{@const preview =
|
|
186
|
-
item.template.kind === 'ink' ? signaturePreview(item.template) : null}
|
|
187
|
-
<button
|
|
188
|
-
type="button"
|
|
189
|
-
role="menuitemradio"
|
|
190
|
-
aria-checked={item.checked}
|
|
191
|
-
aria-label={item.label}
|
|
192
|
-
tabindex={-1}
|
|
193
|
-
class="ink-select-item ink-menu-item ink-signature-item"
|
|
194
|
-
data-ink-select-item=""
|
|
195
|
-
data-key={item.id}
|
|
196
|
-
data-state={item.checked ? 'checked' : 'unchecked'}
|
|
197
|
-
onclick={() => choose(item.id)}
|
|
198
|
-
>
|
|
199
|
-
<span class="ink-signature-preview" data-kind={item.template.kind}>
|
|
200
|
-
{#if item.template.kind === 'image'}
|
|
201
|
-
<img src={item.template.imagedata} alt="" draggable="false" />
|
|
202
|
-
{:else if preview}
|
|
203
|
-
<svg viewBox={preview.viewBox} aria-hidden="true">
|
|
204
|
-
{#each preview.paths as d, i (i)}
|
|
205
|
-
<path {d} fill="currentColor" />
|
|
206
|
-
{/each}
|
|
207
|
-
</svg>
|
|
208
|
-
{/if}
|
|
209
|
-
</span>
|
|
210
|
-
</button>
|
|
211
|
-
<button
|
|
212
|
-
type="button"
|
|
213
|
-
role="menuitem"
|
|
214
|
-
aria-label={item.removeLabel}
|
|
215
|
-
title={item.removeLabel}
|
|
216
|
-
tabindex={-1}
|
|
217
|
-
class="ink-menu-item ink-signature-remove"
|
|
218
|
-
data-ink-signature-remove=""
|
|
219
|
-
data-key={item.id}
|
|
220
|
-
onclick={() => remove(item.id, row)}
|
|
221
|
-
>
|
|
222
|
-
<InkIcon icon={Trash2} size={16} />
|
|
223
|
-
</button>
|
|
224
|
-
{/each}
|
|
225
|
-
</div>
|
|
226
|
-
<div role="separator" class="ink-select-separator"></div>
|
|
227
|
-
{/if}
|
|
228
|
-
<button
|
|
229
|
-
type="button"
|
|
230
|
-
role="menuitem"
|
|
231
|
-
tabindex={-1}
|
|
232
|
-
class="ink-select-item ink-menu-item ink-signature-create"
|
|
233
|
-
data-ink-select-item=""
|
|
234
|
-
data-ink-signature-create=""
|
|
235
|
-
onclick={create}
|
|
236
|
-
>
|
|
237
|
-
<InkIcon icon={Plus} size={16} />
|
|
238
|
-
{SIGNATURE_LABELS.create}
|
|
239
|
-
</button>
|
|
240
|
-
{#if removeError.current}
|
|
241
|
-
<p
|
|
242
|
-
class="ink-field-error ink-signature-remove-error"
|
|
243
|
-
role="alert"
|
|
244
|
-
data-ink-signature-remove-error=""
|
|
245
|
-
>
|
|
246
|
-
{removeError.current}
|
|
247
|
-
</p>
|
|
248
|
-
{/if}
|
|
154
|
+
<SignatureMenuPanel
|
|
155
|
+
items={model.items}
|
|
156
|
+
menu={() => menu}
|
|
157
|
+
onChoose={(t) => choose(t.id)}
|
|
158
|
+
onCreate={create}
|
|
159
|
+
/>
|
|
249
160
|
</Popover.Content>
|
|
250
161
|
</Popover.Portal>
|
|
251
162
|
</Popover.Root>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkSignatureMenu.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSignatureMenu.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD;;;;;GAKG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACtC;
|
|
1
|
+
{"version":3,"file":"InkSignatureMenu.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSignatureMenu.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD;;;;;GAKG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACtC;AA2HH,QAAA,MAAM,gBAAgB,2DAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -34,16 +34,28 @@
|
|
|
34
34
|
* Two-way zoom and page: the viewport's own changes are reported through the context, and
|
|
35
35
|
* the host's props are applied only when they differ from the viewport's state, so the echo
|
|
36
36
|
* of a reported value does nothing.
|
|
37
|
+
*
|
|
38
|
+
* Form fields render in the engine's form layer. A signature field's "Sign" opens
|
|
39
|
+
* `InkSignFieldPopover`, and a form script's alert shows in `InkFormAlert`; both are mounted
|
|
40
|
+
* here, so hosts compose nothing for them.
|
|
37
41
|
*/
|
|
38
42
|
import { mountViewer } from '@inkbar/core/dom'
|
|
39
43
|
import { untrack } from 'svelte'
|
|
40
44
|
|
|
41
45
|
import { useInkContext } from '../context.js'
|
|
42
46
|
|
|
47
|
+
import InkFormAlert from './InkFormAlert.svelte'
|
|
43
48
|
import InkPage from './InkPage.svelte'
|
|
49
|
+
import InkSignFieldPopover from './InkSignFieldPopover.svelte'
|
|
44
50
|
|
|
45
51
|
import type { InkDocument, InkStatus } from '@inkbar/core'
|
|
46
|
-
import type {
|
|
52
|
+
import type {
|
|
53
|
+
PageMount,
|
|
54
|
+
SignFieldRequest,
|
|
55
|
+
ToolId,
|
|
56
|
+
ViewerEngine,
|
|
57
|
+
ZoomValue,
|
|
58
|
+
} from '@inkbar/core/dom'
|
|
47
59
|
|
|
48
60
|
let {
|
|
49
61
|
mode = 'continuous',
|
|
@@ -74,6 +86,10 @@
|
|
|
74
86
|
let scroll = $state<HTMLDivElement | null>(null)
|
|
75
87
|
/** Page hosts, mounts and errors the engine reported; InkPage renders portals for them. */
|
|
76
88
|
let pages = $state.raw<MountedPage[]>([])
|
|
89
|
+
/** The signature field whose menu is open. */
|
|
90
|
+
let signRequest = $state.raw<SignFieldRequest | null>(null)
|
|
91
|
+
/** The form script's message on show, and how many have been shown. */
|
|
92
|
+
let alert = $state.raw<{ message: string; shown: number } | null>(null)
|
|
77
93
|
|
|
78
94
|
let engine: ViewerEngine | null = null
|
|
79
95
|
/**
|
|
@@ -101,6 +117,9 @@
|
|
|
101
117
|
builtWith = null
|
|
102
118
|
ctx.setViewport(null, null)
|
|
103
119
|
if (pages.length > 0) pages = []
|
|
120
|
+
// Their fields and the document they came from are gone.
|
|
121
|
+
signRequest = null
|
|
122
|
+
alert = null
|
|
104
123
|
}
|
|
105
124
|
|
|
106
125
|
function setup(
|
|
@@ -129,6 +148,8 @@
|
|
|
129
148
|
// The engine adds the plugins' tools and layers, and decorates through the host, which
|
|
130
149
|
// reads `decorateAnnotation` first.
|
|
131
150
|
...(ctx.pluginHost ? { plugins: ctx.pluginHost } : {}),
|
|
151
|
+
// The highlights draw from the shared search.
|
|
152
|
+
...(ctx.search ? { search: ctx.search } : {}),
|
|
132
153
|
// Read through, so the effect below can re-apply a new function without a rebuild.
|
|
133
154
|
decorateAnnotation: (a) => ctx.decorateAnnotation?.(a),
|
|
134
155
|
...(ctx.toolStyle ? { toolStyle: ctx.toolStyle } : {}),
|
|
@@ -138,6 +159,15 @@
|
|
|
138
159
|
// Read through, so a new `signatures` store reaches the tool as well as the menus.
|
|
139
160
|
signatureLibrary: () => ctx.signatures,
|
|
140
161
|
customAnnotations: custom,
|
|
162
|
+
...(ctx.formHighlight === undefined ? {} : { formHighlight: ctx.formHighlight }),
|
|
163
|
+
// The field's own button again, while its menu is open, closes the menu.
|
|
164
|
+
onSignField: (req) => {
|
|
165
|
+
signRequest = signRequest?.widget === req.widget ? null : req
|
|
166
|
+
},
|
|
167
|
+
onFormAction: (a) => ctx.reportFormAction(a),
|
|
168
|
+
onFormAlert: (message) => {
|
|
169
|
+
alert = { message, shown: (alert?.shown ?? 0) + 1 }
|
|
170
|
+
},
|
|
141
171
|
onActivate: (id) => ctx.setActivated(id),
|
|
142
172
|
onBuild: (vp, tc) => {
|
|
143
173
|
ctx.setViewport(vp, tc)
|
|
@@ -278,6 +308,11 @@
|
|
|
278
308
|
const tc = engine?.tools
|
|
279
309
|
if (tc && tc.active.get() !== t) untrack(() => tc.set(t))
|
|
280
310
|
})
|
|
311
|
+
// The tint follows `formHighlight` in place, without a new document.
|
|
312
|
+
$effect(() => {
|
|
313
|
+
const on = ctx.formHighlight ?? true
|
|
314
|
+
untrack(() => engine?.setFormHighlight(on))
|
|
315
|
+
})
|
|
281
316
|
// The build applied both; these only act on a later change, not on mount.
|
|
282
317
|
$effect(() => {
|
|
283
318
|
const m = mode
|
|
@@ -340,4 +375,14 @@
|
|
|
340
375
|
{pageError}
|
|
341
376
|
/>
|
|
342
377
|
{/each}
|
|
378
|
+
<!-- Keyed by document, so the menu and its dialog start afresh for each one. -->
|
|
379
|
+
{#key buildDocument}
|
|
380
|
+
<InkSignFieldPopover request={signRequest} onClose={() => (signRequest = null)} />
|
|
381
|
+
{/key}
|
|
382
|
+
<InkFormAlert
|
|
383
|
+
message={alert?.message ?? null}
|
|
384
|
+
shown={alert?.shown ?? 0}
|
|
385
|
+
fallback={() => scroll}
|
|
386
|
+
onClose={() => (alert = null)}
|
|
387
|
+
/>
|
|
343
388
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkViewport.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkViewport.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,GAAG,SAAS,CAAA;IACvD,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;CACrE;
|
|
1
|
+
{"version":3,"file":"InkViewport.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkViewport.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,GAAG,SAAS,CAAA;IACvD,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;CACrE;AAsWH,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|