anniedrawing 0.3.1 → 0.3.3

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/README.md +20 -14
  3. package/dist/agent/index.js +1 -1
  4. package/dist/agent/index.js.map +1 -1
  5. package/dist/agent/toolDefs.d.ts +1 -0
  6. package/dist/board.d.ts +7 -1
  7. package/dist/core/index.js +1 -1
  8. package/dist/core/types.d.ts +12 -0
  9. package/dist/docs/agents-repository.md +1 -1
  10. package/dist/docs/agents.md +4 -0
  11. package/dist/docs/api.md +4 -0
  12. package/dist/docs/board-js.md +4 -0
  13. package/dist/docs/decisions.md +8 -2
  14. package/dist/docs/index.html +2 -1
  15. package/dist/docs/llms-full.txt +4 -0
  16. package/dist/docs/llms.txt +4 -0
  17. package/dist/docs/mcp.md +1 -1
  18. package/dist/docs/releasing.md +21 -1
  19. package/dist/docs/security.md +1 -1
  20. package/dist/fellow.d.ts +2 -2
  21. package/dist/fellow.js +1 -1
  22. package/dist/fellow.js.map +1 -1
  23. package/dist/index.js +1 -1
  24. package/dist/shared/board-p60lv7As.js +2 -0
  25. package/dist/shared/board-p60lv7As.js.map +1 -0
  26. package/dist/shared/{cards-DWgSVE54.js → cards-DF0uI4-I.js} +2 -2
  27. package/dist/shared/{cards-DWgSVE54.js.map → cards-DF0uI4-I.js.map} +1 -1
  28. package/dist/shared/{paste-C22i8o-g.js → paste-B8nZA2Gh.js} +2 -2
  29. package/dist/shared/{paste-C22i8o-g.js.map → paste-B8nZA2Gh.js.map} +1 -1
  30. package/dist/shared/{picker-Dv_i4iNP.js → picker-DZpEpkED.js} +2 -2
  31. package/dist/shared/picker-DZpEpkED.js.map +1 -0
  32. package/dist/shared/{ui-Cay6AVqT.js → ui-DWQtW0zJ.js} +2 -2
  33. package/dist/shared/ui-DWQtW0zJ.js.map +1 -0
  34. package/dist/shared/{urlPaste-DN4JtgeB.js → urlPaste-Oc4kZ0P7.js} +2 -2
  35. package/dist/shared/{urlPaste-DN4JtgeB.js.map → urlPaste-Oc4kZ0P7.js.map} +1 -1
  36. package/dist/ui/index.js +1 -1
  37. package/dist/ui/version.d.ts +3 -2
  38. package/llms-full.txt +4 -0
  39. package/llms.txt +4 -0
  40. package/package.json +4 -4
  41. package/dist/shared/board-Bya0O1I7.js +0 -2
  42. package/dist/shared/board-Bya0O1I7.js.map +0 -1
  43. package/dist/shared/picker-Dv_i4iNP.js.map +0 -1
  44. package/dist/shared/ui-Cay6AVqT.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"picker-Dv_i4iNP.js","names":[],"sources":["../../node_modules/@preact/signals-core/dist/signals-core.module.js","../../src/core/migrate.ts","../../src/core/links.ts","../../src/core/doc.ts","../../src/core/clipboard.ts","../../node_modules/quickselect/index.js","../../node_modules/rbush/index.js","../../src/geo/picker.ts"],"sourcesContent":["var i=Symbol.for(\"preact-signals\");function t(){if(!(v>1)){var i,t=!1;!function(){var i=c;c=void 0;while(void 0!==i){var t=i.S;if(t.v===i.v)for(var n=t.t;void 0!==n;n=n.x)if(n.i===i.i)n.i=t.i;i=i.o}}();while(void 0!==h){var n=h;h=void 0;s++;while(void 0!==n){var r=n.u;n.u=void 0;n.f&=-3;if(!(8&n.f)&&w(n))try{n.c()}catch(n){if(!t){i=n;t=!0}}n=r}}s=0;v--;if(t)throw i}else v--}function n(i){if(v>0)return i();e=++u;v++;try{return i()}finally{t()}}var r,o=void 0;function f(i){var t=o,n=r;o=void 0;r=void 0;try{return i()}finally{o=t;r=n}}var h=void 0,v=0,s=0,u=0,e=0,c=void 0,d=0;function a(i){if(void 0!==o){var t=i.n;if(void 0===t||t.t!==o){t={i:0,S:i,p:o.s,n:void 0,t:o,e:void 0,x:void 0,r:t};if(void 0!==o.s)o.s.n=t;o.s=t;i.n=t;if(32&o.f)i.S(t);return t}else if(-1===t.i){t.i=0;if(void 0!==t.n){t.n.p=t.p;if(void 0!==t.p)t.p.n=t.n;t.p=o.s;t.n=void 0;o.s.n=t;o.s=t}return t}}}function l(i,t){this.v=i;this.i=0;this.n=void 0;this.t=void 0;this.l=0;this.W=null==t?void 0:t.watched;this.Z=null==t?void 0:t.unwatched;this.name=null==t?void 0:t.name}l.prototype.brand=i;l.prototype.h=function(){return!0};l.prototype.S=function(i){var t=this,n=this.t;if(n!==i&&void 0===i.e){i.x=n;this.t=i;if(void 0!==n)n.e=i;else f(function(){var i;null==(i=t.W)||i.call(t)})}};l.prototype.U=function(i){var t=this;if(void 0!==this.t){var n=i.e,r=i.x;if(void 0!==n){n.x=r;i.e=void 0}if(void 0!==r){r.e=n;i.x=void 0}if(i===this.t){this.t=r;if(void 0===r)f(function(){var i;null==(i=t.Z)||i.call(t)})}}};l.prototype.subscribe=function(i){var t=this;return j(function(){var n=t.value;f(function(){return i(n)})},{name:\"sub\"})};l.prototype.valueOf=function(){return this.value};l.prototype.toString=function(){return this.value+\"\"};l.prototype.toJSON=function(){return this.value};l.prototype.peek=function(){var i=this;return f(function(){return i.value})};Object.defineProperty(l.prototype,\"value\",{get:function(){var i=a(this);if(void 0!==i)i.i=this.i;return this.v},set:function(i){if(i!==this.v){if(s>100)throw new Error(\"Cycle detected\");!function(i){if(0!==v&&0===s)if(i.l!==e){i.l=e;c={S:i,v:i.v,i:i.i,o:c}}}(this);this.v=i;this.i++;d++;v++;try{for(var n=this.t;void 0!==n;n=n.x)n.t.N()}finally{t()}}}});function y(i,t){return new l(i,t)}function w(i){for(var t=i.s;void 0!==t;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return!0;return!1}function _(i){for(var t=i.s;void 0!==t;t=t.n){var n=t.S.n;if(void 0!==n)t.r=n;t.S.n=t;t.i=-1;if(void 0===t.n){i.s=t;break}}}function b(i){var t=i.s,n=void 0;while(void 0!==t){var r=t.p;if(-1===t.i){t.S.U(t);if(void 0!==r)r.n=t.n;if(void 0!==t.n)t.n.p=r}else n=t;t.S.n=t.r;if(void 0!==t.r)t.r=void 0;t=r}i.s=n}function p(i,t){l.call(this,void 0,t);this.x=i;this.s=void 0;this.g=d-1;this.f=4}p.prototype=new l;p.prototype.h=function(){this.f&=-3;if(1&this.f)return!1;if(32==(36&this.f))return!0;this.f&=-5;if(this.g===d)return!0;this.g=d;this.f|=1;if(this.i>0&&!w(this)){this.f&=-2;return!0}var i=o;try{_(this);o=this;var t=this.x();if(16&this.f||this.v!==t||0===this.i){this.v=t;this.f&=-17;this.i++}}catch(i){this.v=i;this.f|=16;this.i++}o=i;b(this);this.f&=-2;return!0};p.prototype.S=function(i){if(void 0===this.t){this.f|=36;for(var t=this.s;void 0!==t;t=t.n)t.S.S(t)}l.prototype.S.call(this,i)};p.prototype.U=function(i){if(void 0!==this.t){l.prototype.U.call(this,i);if(void 0===this.t){this.f&=-33;for(var t=this.s;void 0!==t;t=t.n)t.S.U(t)}}};p.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var i=this.t;void 0!==i;i=i.x)i.t.N()}};Object.defineProperty(p.prototype,\"value\",{get:function(){if(1&this.f)throw new Error(\"Cycle detected\");var i=a(this);this.h();if(void 0!==i)i.i=this.i;if(16&this.f)throw this.v;return this.v}});function g(i,t){return new p(i,t)}function S(i){var n=i.m;i.m=void 0;if(\"function\"==typeof n){v++;var r=o;o=void 0;try{n()}catch(t){i.f&=-2;i.f|=8;m(i);throw t}finally{o=r;t()}}}function m(i){for(var t=i.s;void 0!==t;t=t.n)t.S.U(t);i.x=void 0;i.s=void 0;S(i)}function x(i){if(o!==this)throw new Error(\"Out-of-order effect\");b(this);o=i;this.f&=-2;if(8&this.f)m(this);t()}function E(i,t){this.x=i;this.m=void 0;this.s=void 0;this.u=void 0;this.f=32;this.name=null==t?void 0:t.name;if(r)r.push(this)}E.prototype.c=function(){var i=this.S();try{if(8&this.f)return;if(void 0===this.x)return;var t=this.x();if(\"function\"==typeof t)this.m=t}finally{i()}};E.prototype.S=function(){if(1&this.f)throw new Error(\"Cycle detected\");this.f|=1;this.f&=-9;S(this);_(this);v++;var i=o;o=this;return x.bind(this,i)};E.prototype.N=function(){if(!(2&this.f)){this.f|=2;this.u=h;h=this}};E.prototype.d=function(){this.f|=8;if(!(1&this.f))m(this)};E.prototype.dispose=function(){this.d()};function j(i,t){var n=new E(i,t);try{n.c()}catch(i){n.d();throw i}var r=n.d.bind(n);r[Symbol.dispose]=r;return r}function C(i){return function(){var t=arguments,r=this;return n(function(){return f(function(){return i.apply(r,[].slice.call(t))})})}}function O(){var i=r;r=[];return function(){var t=r;if(r&&i)i=i.concat(r);r=i;return t}}var k=function(i){for(var t in i){var n=i[t];if(\"function\"==typeof n)i[t]=C(n);else if(\"object\"==typeof n&&null!==n&&!(\"brand\"in n))k(n)}};function T(i){return function(){var t,n,o=O();try{n=i.apply(void 0,[].slice.call(arguments))}catch(i){r=void 0;throw i}finally{t=o()}k(n);n[Symbol.dispose]=C(function(){if(t)for(var i=0;i<t.length;i++)t[i].dispose();t=void 0});return n}}export{p as Computed,E as Effect,l as Signal,C as action,n as batch,g as computed,T as createModel,j as effect,y as signal,f as untracked};//# sourceMappingURL=signals-core.module.js.map\n","import type { AnnieDoc, Item, NewItem } from './types';\nimport { clone, normalizeItem } from './defaults';\nimport { flattenItems } from '../geo/box';\n\n/** Retired containers become editable groups; no child or visible label is discarded. */\nfunction convertContainers(pages: AnnieDoc['pages']) {\n const ids = new Set(\n flattenItems(pages.flatMap((page) => page.items ?? [])).map((item) => item.id),\n );\n const unique = (base: string) => {\n let id = base;\n for (let suffix = 2; ids.has(id); suffix++) id = `${base}_${suffix}`;\n ids.add(id);\n return id;\n };\n const convert = (input: NewItem): NewItem => {\n const children = input.children?.map(convert);\n if (input.kind !== 'frame') return { ...input, ...(children ? { children } : {}) };\n const { clip, title, text, style, ...rest } = input;\n const box = { x: input.x ?? 0, y: input.y ?? 0, w: input.w ?? 600, h: input.h ?? 400 };\n const parts: NewItem[] = [\n {\n kind: 'rect',\n id: unique(`${input.id}_background`),\n ...box,\n rotation: input.rotation,\n style: { fill: 'paper', strokeWidth: 1.5, ...style },\n ...(text ? { text } : {}),\n },\n ];\n const label = typeof title === 'string' ? title : input.name;\n if (label)\n parts.push({\n kind: 'text',\n id: unique(`${input.id}_label`),\n x: box.x,\n y: box.y - 30,\n w: box.w,\n h: 20,\n text: { value: label, size: 14, align: 'start', valign: 'top' },\n });\n return {\n ...rest,\n ...box,\n kind: 'group',\n name: input.name ?? label,\n children: [...parts, ...(children ?? [])],\n };\n };\n return pages.map((page) => ({\n ...page,\n items: Array.isArray(page.items) ? page.items.map(convert) : page.items,\n }));\n}\nexport const CURRENT_VERSION = 2;\nexport const migrations: Record<number, (doc: Record<string, unknown>) => Record<string, unknown>> =\n {\n 1: (doc) => ({\n ...doc,\n format: 'anniedrawing',\n version: 1,\n media: doc.media ?? {},\n meta: doc.meta ?? { title: 'Untitled board' },\n }),\n 2: (doc) => {\n const { sheets, ...rest } = doc;\n const pages = sheets ?? doc.pages;\n return {\n ...rest,\n version: 2,\n pages: Array.isArray(pages)\n ? pages.map((page: Record<string, unknown>) => ({\n ...page,\n name:\n typeof page.name === 'string' && /^Sheet [1-9]\\d*$/.test(page.name)\n ? page.name.replace(/^Sheet /, 'Page ')\n : page.name,\n }))\n : pages,\n };\n },\n };\n\n/** Load any supported version. Retired `frame` items become groups on every import. */\nexport function migrate(\n input: unknown,\n kindDefaults: Record<string, Partial<Item>> = {},\n): AnnieDoc {\n if (!input || typeof input !== 'object') throw new Error('A drawing must be a JSON object.');\n let doc = clone(input) as Record<string, unknown>;\n if (doc.format !== undefined && doc.format !== 'anniedrawing')\n throw new Error('This is not an AnnieDrawing document.');\n const version = doc.version ?? 0;\n if (typeof version !== 'number' || !Number.isInteger(version) || version < 0)\n throw new Error('Invalid drawing version.');\n if (version > CURRENT_VERSION)\n throw new Error(\n `Drawing version ${version} is newer than supported version ${CURRENT_VERSION}.`,\n );\n for (let next = version + 1; next <= CURRENT_VERSION; next++) doc = migrations[next](doc);\n const result = doc as unknown as AnnieDoc;\n if (Array.isArray(result.pages))\n result.pages = convertContainers(result.pages).map((page) => ({\n ...page,\n items: Array.isArray(page.items)\n ? page.items.map((item) => normalizeItem(item, kindDefaults))\n : page.items,\n }));\n return result;\n}\n","export type VideoProvider = 'youtube' | 'vimeo';\nexport interface VideoRef {\n provider: VideoProvider;\n id: string;\n hash?: string;\n}\nexport interface LinkPreview {\n title?: string;\n description?: string;\n image?: string;\n}\n\nconst YT = /^[\\w-]{11}$/;\n/** Raster image data URLs accepted as image items. */\nexport const IMAGE_DATA_URL = /^data:image\\/(png|jpeg|gif|webp|avif);base64,[a-z0-9+/=\\s]+$/i;\n/** Image media table sources, including SVG. */\nexport const MEDIA_DATA_URL =\n /^data:image\\/(png|jpeg|gif|webp|avif|svg\\+xml);base64,[a-z0-9+/=\\s]+$/i;\n\nexport function normalizeHref(value?: string): string | undefined {\n if (typeof value !== 'string') return;\n const text = value.trim();\n if (IMAGE_DATA_URL.test(text)) return text.replace(/\\s+/g, '');\n try {\n const url = new URL(text);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return;\n url.username = url.password = '';\n return url.href;\n } catch {\n return;\n }\n}\n\n/** True for http(s) URLs whose host is not loopback, link-local, ULA, or RFC1918. */\nexport function isPublicHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return false;\n if (url.username || url.password) return false;\n return !isPrivateOrLocalHostname(url.hostname);\n } catch {\n return false;\n }\n}\n\nfunction isPrivateOrLocalHostname(host: string): boolean {\n const hostname = host\n .replace(/^\\[|\\]$/g, '')\n .replace(/\\.+$/, '')\n .toLowerCase();\n if (\n hostname === 'localhost' ||\n hostname === '0.0.0.0' ||\n hostname === '::' ||\n hostname.endsWith('.localhost') ||\n hostname.endsWith('.local') ||\n hostname.endsWith('.internal')\n )\n return true;\n const prefix = hostname.match(/^(\\d{1,3}(?:\\.\\d{1,3}){3})(?:\\.|$)/);\n if (prefix && isPrivateIPv4(prefix[1])) return true;\n const v4 = ipv4Address(hostname);\n if (v4) return isPrivateIPv4(v4);\n const v6 = parseIPv6(hostname);\n if (!v6) return false;\n if (v6.every((part) => part === 0)) return true;\n if (v6[7] === 1 && v6.slice(0, 7).every((part) => part === 0)) return true;\n if ((v6[0] & 0xffc0) === 0xfe80 || (v6[0] & 0xfe00) === 0xfc00 || (v6[0] & 0xff00) === 0xff00)\n return true;\n const mapped = mappedIPv4(v6);\n return mapped ? isPrivateIPv4(mapped) : false;\n}\n\nfunction isPrivateIPv4(value: string): boolean {\n const parts = value.split('.').map(Number);\n if (parts.length !== 4 || parts.some((n) => n > 255)) return false;\n const [a, b] = parts;\n if (a === 0 || a === 10 || a === 127) return true;\n if (a === 169 && b === 254) return true;\n if (a === 192 && b === 168) return true;\n if (a === 172 && b >= 16 && b <= 31) return true;\n if (a === 100 && b >= 64 && b <= 127) return true;\n if (a === 198 && (b === 18 || b === 19)) return true;\n return a >= 224;\n}\n\nfunction ipv4Address(hostname: string): string | undefined {\n if (/^\\d{1,3}(?:\\.\\d{1,3}){3}$/.test(hostname)) return hostname;\n const v6 = parseIPv6(hostname);\n return v6 ? mappedIPv4(v6) : undefined;\n}\n\nfunction mappedIPv4(groups: number[]): string | undefined {\n const last = `${(groups[6] >> 8) & 255}.${groups[6] & 255}.${(groups[7] >> 8) & 255}.${groups[7] & 255}`;\n if (\n groups[0] === 0 &&\n groups[1] === 0 &&\n groups[2] === 0 &&\n groups[3] === 0 &&\n groups[4] === 0 &&\n groups[5] === 0xffff\n )\n return last;\n if (groups[0] === 0x64 && groups[1] === 0xff9b && groups.slice(2, 6).every((part) => part === 0))\n return last;\n return;\n}\n\nfunction parseIPv6(host: string): number[] | undefined {\n if (!host.includes(':')) return;\n let value = host;\n const dotted = value.match(/:(\\d{1,3}(?:\\.\\d{1,3}){3})$/);\n if (dotted) {\n const [a, b, c, d] = dotted[1].split('.').map(Number);\n if ([a, b, c, d].some((n) => n > 255)) return;\n value = `${value.slice(0, -dotted[1].length)}${(a << 8) | b}:${(c << 8) | d}`;\n }\n const halves = value.split('::');\n if (halves.length > 2) return;\n const parse = (side: string | undefined) =>\n side\n ? side\n .split(':')\n .filter(Boolean)\n .map((part) => (/^[0-9a-f]{1,4}$/i.test(part) ? parseInt(part, 16) : NaN))\n : [];\n const head = parse(halves[0]);\n const tail = halves.length === 2 ? parse(halves[1]) : [];\n if (head.some(Number.isNaN) || tail.some(Number.isNaN)) return;\n if (halves.length === 1) return head.length === 8 ? head : undefined;\n const missing = 8 - head.length - tail.length;\n if (missing < 0) return;\n return [...head, ...Array(missing).fill(0), ...tail];\n}\n\nexport function hostnameOf(href: string): string {\n try {\n return new URL(href).hostname.replace(/^www\\./, '');\n } catch {\n return href;\n }\n}\n\nexport function parseVideo(href?: string): VideoRef | undefined {\n const normalized = normalizeHref(href);\n if (!normalized || normalized.startsWith('data:')) return;\n const url = new URL(normalized);\n const host = url.hostname.replace(/^(www|m)\\./, '');\n const parts = url.pathname.split('/').filter(Boolean);\n if (host.includes('youtu')) {\n const id =\n host === 'youtu.be'\n ? parts[0]\n : (url.searchParams.get('v') ??\n parts[parts.findIndex((part) => /^(embed|shorts|live|v)$/.test(part)) + 1]);\n if (id && YT.test(id)) return { provider: 'youtube', id };\n }\n if (!/^(player\\.)?vimeo\\.com$/.test(host)) return;\n const start = parts[0] === 'video' || host.startsWith('player') ? 1 : 0;\n const id = parts[start];\n if (!id || !/^\\d+$/.test(id)) return;\n const hash = url.searchParams.get('h') ?? parts[start + 1]?.match(/^[\\w]+$/)?.[0];\n return { provider: 'vimeo', id, ...(hash ? { hash } : {}) };\n}\n\nexport function videoEmbed(href?: string): string | undefined {\n const video = parseVideo(href);\n if (!video) return;\n return video.provider === 'youtube'\n ? `https://www.youtube-nocookie.com/embed/${video.id}?rel=0`\n : `https://player.vimeo.com/video/${video.id}${video.hash ? `?h=${encodeURIComponent(video.hash)}` : ''}`;\n}\n","import { batch, signal, type Signal, type ReadonlySignal } from '@preact/signals-core';\nimport type {\n AnnieDoc,\n ApplyIssue,\n ApplyResult,\n ChangeEvent,\n ChangeSlice,\n DocModel,\n DocOptions,\n Item,\n NewItem,\n Op,\n Page,\n Style,\n} from './types';\nimport { kindsSince } from './catalog';\nimport {\n aliasStyle,\n clone,\n defaultDoc,\n kindDefaultsFrom,\n minimalItem,\n normalizeItem,\n storedEndpoint,\n} from './defaults';\nimport type { ItemStamp } from '../agent/describe';\nimport { allItems, detachMissingEndpoints, pageRoots, remapAgentCreateIds } from './item';\nimport { DocumentSchema, LIMITS, OpSchema, schemaError } from './schema';\nimport { migrate } from './migrate';\nimport { pageId } from './ids';\nimport { flattenItems, intersects, itemBounds } from '../geo/box';\nimport { placeItem } from '../agent/place';\nimport { queryDoc } from '../agent/query';\nimport { describeDoc } from '../agent/describe';\nimport { MEDIA_DATA_URL, normalizeHref, parseVideo } from './links';\ninterface Location {\n item: Item;\n list: Item[];\n index: number;\n parent?: Item;\n page: Page;\n}\ninterface Entry {\n ops: Op[];\n inverse: Op[];\n before: AnnieDoc;\n after: AnnieDoc;\n origin: string;\n label?: string;\n}\nconst equal = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\nfunction escapeHtml(html: string, sanitize?: DocOptions['sanitizeHTML']): string {\n return sanitize\n ? sanitize(html)\n : html\n .replace(/&(?!(?:amp|lt|gt|quot|apos|#\\d+|#x[\\da-f]+);)/gi, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\nconst SANITIZER_PROBE = '<img src=\"x\" onerror=\"alert(1)\"><script>alert(1)</script>';\nfunction assertEffectiveSanitizer(sanitize: (html: string) => string): void {\n let out: string;\n try {\n out = sanitize(SANITIZER_PROBE);\n } catch (error) {\n throw new Error(\n `sanitizeHTML failed on a safety probe (${error instanceof Error ? error.message : error}).`,\n );\n }\n if (typeof out !== 'string') throw new Error('sanitizeHTML must return a string.');\n const lower = out.toLowerCase();\n if (lower.includes('onerror') || /<script\\b/.test(lower))\n throw new Error(\n 'sanitizeHTML must strip active HTML. Do not pass an identity function or a no-op.',\n );\n}\nfunction assertPagePatch(patch: object): void {\n if (Object.keys(patch).some((key) => key !== 'name' && key !== 'background'))\n throw new Error(\n 'page.set may only update name and background. Use item operations to change page content.',\n );\n}\nfunction locate(doc: AnnieDoc, id: string): Location | undefined {\n for (const page of doc.pages) {\n const walk = (list: Item[], parent?: Item): Location | undefined => {\n for (let index = 0; index < list.length; index++) {\n const item = list[index];\n if (item.id === id) return { item, list, index, parent, page };\n if (item.children) {\n const found = walk(item.children, item);\n if (found) return found;\n }\n }\n };\n const result = walk(page.items);\n if (result) return result;\n }\n}\nfunction requireItem(doc: AnnieDoc, id: string): Location {\n const result = locate(doc, id);\n if (!result) {\n const candidates = allItems(doc)\n .map((i) => i.id)\n .slice(0, 5);\n throw new Error(\n `Item ${id} does not exist.${candidates.length ? ` Known ids: ${candidates.join(', ')}.` : ''}`,\n );\n }\n return result;\n}\nfunction mergePatch<T extends object>(target: T, patch: Partial<T>, nested: string[] = []): T {\n const next = { ...target } as Record<string, unknown>;\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) {\n delete next[key];\n continue;\n }\n if (nested.includes(key) && value && typeof value === 'object' && !Array.isArray(value)) {\n const old = next[key];\n next[key] = mergePatch(old && typeof old === 'object' ? (old as object) : {}, value);\n } else next[key] = clone(value);\n }\n return next as T;\n}\nfunction inversePatch(\n target: object,\n patch: object,\n nested: string[] = [],\n): Record<string, unknown> {\n const before = target as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(patch)) {\n const value = (patch as Record<string, unknown>)[key];\n result[key] =\n nested.includes(key) &&\n value &&\n typeof value === 'object' &&\n before[key] &&\n typeof before[key] === 'object'\n ? inversePatch(before[key] as object, value as object)\n : clone(before[key]);\n }\n return result;\n}\nfunction assertSafeJSON(value: unknown, depth = 0, seen = new Set<unknown>()): void {\n if (depth > LIMITS.maxJsonDepth)\n throw new Error(`Document data exceeds maximum nesting depth ${LIMITS.maxJsonDepth}.`);\n if (\n value === undefined ||\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'string'\n )\n return;\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) throw new Error('All numbers must be finite.');\n return;\n }\n if (typeof value !== 'object') throw new Error('Document values must be plain JSON data.');\n if (seen.has(value)) throw new Error('Circular document data is not supported.');\n const proto = Object.getPrototypeOf(value);\n if (!Array.isArray(value) && proto !== Object.prototype && proto !== null)\n throw new Error('Document values must be plain JSON objects.');\n seen.add(value);\n for (const [key, child] of Object.entries(value)) {\n if (['__proto__', 'prototype', 'constructor'].includes(key))\n throw new Error(`Unsafe property ${key}.`);\n assertSafeJSON(child, depth + 1, seen);\n }\n seen.delete(value);\n}\nfunction validateDoc(\n doc: AnnieDoc,\n options: DocOptions = {},\n origin = 'user',\n restrictedMedia?: Set<string>,\n): void {\n assertSafeJSON(doc);\n const error = schemaError(DocumentSchema, doc);\n if (error) throw new Error(error);\n const ids = new Set<string>(),\n pageIds = new Set<string>();\n let count = 0;\n for (const page of doc.pages) {\n if (pageIds.has(page.id)) throw new Error(`Duplicate page id ${page.id}.`);\n pageIds.add(page.id);\n const walk = (list: Item[], depth: number) => {\n if (depth > LIMITS.maxDepth) throw new Error('Item nesting is too deep.');\n for (const item of list) {\n count++;\n if (typeof item.id !== 'string' || !item.id)\n throw new Error('Every item must have a stable string id.');\n for (const field of ['x', 'y', 'w', 'h'] as const)\n if (typeof item[field] !== 'number' || !Number.isFinite(item[field]))\n throw new Error(`Item ${item.id} requires finite ${field}.`);\n if (ids.has(item.id)) throw new Error(`Duplicate item id ${item.id}.`);\n ids.add(item.id);\n if (item.children && item.kind !== 'group')\n throw new Error(`Only groups may contain children (${item.id}).`);\n if (item.kind === 'connector' && (!item.from || !item.to))\n throw new Error(`Connector ${item.id} needs both from and to endpoints.`);\n if (item.kind === 'image' && (!item.media || !doc.media[item.media]))\n throw new Error(`Image ${item.id} references missing media ${item.media ?? '(unset)'}.`);\n if (item.kind === 'video' || item.kind === 'link' || item.href !== undefined) {\n if (!normalizeHref(item.href)) throw new Error(`Bad href (${item.id}).`);\n if (item.kind === 'video' && !parseVideo(item.href))\n throw new Error(`Bad video (${item.id}).`);\n }\n const customSchema = options.kinds?.find((kind) => kind.kind === item.kind)?.schema;\n if (customSchema) {\n const customError = schemaError(customSchema as Parameters<typeof schemaError>[0], item);\n if (customError) throw new Error(`${item.kind} ${item.id}: ${customError}`);\n }\n if (item.children) walk(item.children, depth + 1);\n }\n };\n walk(page.items, 0);\n }\n if (count > LIMITS.maxItems)\n throw new Error(`A document may contain at most ${LIMITS.maxItems} items.`);\n for (const page of doc.pages) {\n const local = flattenItems(page.items),\n localIds = new Map(local.map((i) => [i.id, i]));\n for (const item of local)\n for (const endpoint of [item.from, item.to])\n if (endpoint && 'item' in endpoint) {\n const target = localIds.get(endpoint.item);\n if (!target)\n throw new Error(`Endpoint ${endpoint.item} does not exist on page ${page.id}.`);\n if (target.kind === 'connector' || target.id === item.id)\n throw new Error(\n `Connector endpoints must attach to a non-connector item (${endpoint.item}).`,\n );\n }\n }\n for (const [mediaId, media] of Object.entries(doc.media)) {\n const data = MEDIA_DATA_URL.test(media.src);\n let url: URL | undefined;\n try {\n url = new URL(media.src);\n } catch {\n /* Validation below reports a useful error. */\n }\n if (!data && (!url || !['http:', 'https:'].includes(url.protocol)))\n throw new Error('Images must use an image data URL or an HTTP(S) URL.');\n if (url && (url.username || url.password))\n throw new Error('Image URLs must not include credentials.');\n if (\n origin !== 'user' &&\n (!restrictedMedia || restrictedMedia.has(mediaId)) &&\n !data &&\n url &&\n !options.allowedImageOrigins?.includes(url.origin)\n )\n throw new Error(\n `Image origin ${url.origin} is not allowed. Pass allowedImageOrigins when creating the board.`,\n );\n }\n}\nfunction cleanHref(item: Item): void {\n if (item.href === undefined) return;\n const href = normalizeHref(item.href);\n if (!href) throw new Error(`Bad href (${item.id}).`);\n item.href = href;\n item.children?.forEach(cleanHref);\n}\nfunction sanitizeAgentItems(item: Item, sanitizeHTML?: DocOptions['sanitizeHTML']): void {\n if (item.html !== undefined) item.html = escapeHtml(item.html, sanitizeHTML);\n if (item.mount) delete item.mount;\n item.children?.forEach((child) => sanitizeAgentItems(child, sanitizeHTML));\n}\nfunction perform(\n doc: AnnieDoc,\n raw: Op,\n origin: string,\n options: DocOptions = {},\n): {\n op: Op;\n inverse: Op[];\n created: string[];\n} {\n const op = clone(raw),\n kindDefaults = kindDefaultsFrom(options.kinds);\n const outline = (item: Item) =>\n options.kinds?.find((kind) => kind.kind === item.kind)?.outline?.(item);\n let inverse: Op[] = [],\n created: string[] = [];\n if (op.op === 'add') {\n let item = normalizeItem(op.item, kindDefaults);\n if (origin !== 'user') sanitizeAgentItems(item, options.sanitizeHTML);\n cleanHref(item);\n const parentId = op.parent ?? op.place?.inside,\n parent = parentId ? requireItem(doc, parentId) : undefined;\n if (parent && parent.item.kind !== 'group')\n throw new Error(`Parent ${parentId} must be a group.`);\n const page = parent?.page ?? doc.pages.find((page) => (op.page ? page.id === op.page : true));\n if (!page) throw new Error(`Page ${op.page ?? '(first)'} does not exist.`);\n if (parent && op.page && op.page !== parent.page.id)\n throw new Error('Parent and page must refer to the same page.');\n if (op.place) {\n const gap =\n op.place.gap ?? (origin.startsWith('agent:') ? (options.agentPlaceGap ?? 32) : 32);\n item = placeItem(item, { ...op.place, gap }, flattenItems(page.items));\n }\n const list = parent ? (parent.item.children ??= []) : page.items;\n if (op.index !== undefined && op.index > list.length)\n throw new Error('Insert index is outside the target list.');\n list.splice(op.index ?? list.length, 0, item);\n inverse = [{ op: 'remove', id: item.id }];\n created = flattenItems([item]).map((i) => i.id);\n return {\n op: {\n op: 'add',\n item: clone(item),\n page: page.id,\n ...(parent ? { parent: parent.item.id } : {}),\n ...(op.index !== undefined ? { index: op.index } : {}),\n },\n inverse,\n created,\n };\n }\n if (op.op === 'set') {\n const at = requireItem(doc, op.id);\n const oldLookup = Object.hasOwn(op.patch, 'children')\n ? new Map(allItems(doc).map((item) => [item.id, item]))\n : undefined;\n if (Object.hasOwn(op.patch, 'id') && op.patch.id !== op.id)\n throw new Error('Item ids cannot be changed.');\n inverse = [\n { op: 'set', id: op.id, patch: inversePatch(at.item, op.patch, ['style', 'text', 'data']) },\n ];\n const incoming = clone(op.patch);\n const { from, to, style, children, ...rest } = incoming;\n const patch: Partial<Item> = { ...(rest as Partial<Item>) };\n if (Object.hasOwn(incoming, 'style')) patch.style = aliasStyle(style as Style | undefined);\n if (Object.hasOwn(incoming, 'from')) patch.from = storedEndpoint(from);\n if (Object.hasOwn(incoming, 'to')) patch.to = storedEndpoint(to);\n if (Object.hasOwn(incoming, 'children'))\n patch.children = children\n ? (children as NewItem[]).map((child) => normalizeItem(child, kindDefaults))\n : undefined;\n for (const field of ['kind', 'x', 'y', 'w', 'h'] as const)\n if (Object.hasOwn(patch, field) && patch[field] === undefined)\n throw new Error(`Required field ${field} cannot be deleted.`);\n if (typeof patch.href === 'string') {\n const href = normalizeHref(patch.href);\n if (!href) throw new Error(`Bad href (${op.id}).`);\n patch.href = href;\n }\n if (origin !== 'user') {\n if (typeof patch.html === 'string') patch.html = escapeHtml(patch.html, options.sanitizeHTML);\n if (Object.hasOwn(patch, 'mount')) delete patch.mount;\n if (patch.children)\n patch.children.forEach((child) => sanitizeAgentItems(child, options.sanitizeHTML));\n }\n at.list[at.index] = mergePatch(at.item, patch, ['style', 'text', 'data']);\n if (oldLookup) {\n const newDescendants = new Set(\n flattenItems(at.list[at.index].children ?? []).map((item) => item.id),\n );\n created = [...newDescendants].filter((id) => !oldLookup.has(id));\n inverse.push(...detachMissingEndpoints(pageRoots(doc), oldLookup, outline));\n }\n return { op: { ...op, patch }, inverse, created };\n }\n if (op.op === 'remove') {\n const at = requireItem(doc, op.id),\n lookup = new Map(allItems(doc).map((i) => [i.id, i]));\n inverse = [\n {\n op: 'add',\n item: clone(at.item),\n page: at.page.id,\n ...(at.parent ? { parent: at.parent.id } : {}),\n index: at.index,\n },\n ];\n at.list.splice(at.index, 1);\n inverse.push(...detachMissingEndpoints(pageRoots(doc), lookup, outline));\n }\n if (op.op === 'order') {\n const at = requireItem(doc, op.id),\n to =\n typeof op.to === 'number'\n ? op.to\n : op.to === 'front'\n ? at.list.length - 1\n : op.to === 'back'\n ? 0\n : op.to === 'forward'\n ? Math.min(at.list.length - 1, at.index + 1)\n : Math.max(0, at.index - 1);\n if (to >= at.list.length) throw new Error('Order index is outside the item list.');\n at.list.splice(at.index, 1);\n at.list.splice(to, 0, at.item);\n inverse = [{ op: 'order', id: op.id, to: at.index }];\n }\n if (op.op === 'reparent') {\n const at = requireItem(doc, op.id),\n parent = op.parent ? requireItem(doc, op.parent) : undefined;\n if (parent && parent.item.kind !== 'group') throw new Error('New parent must be a group.');\n if (parent && flattenItems([at.item]).some((i) => i.id === parent.item.id))\n throw new Error('An item cannot be placed inside itself or a descendant.');\n if (parent && parent.page.id !== at.page.id)\n throw new Error('Reparenting across pages is not supported.');\n inverse = [{ op: 'reparent', id: op.id, parent: at.parent?.id ?? null, index: at.index }];\n at.list.splice(at.index, 1);\n const list = parent ? (parent.item.children ??= []) : at.page.items;\n if (op.index !== undefined && op.index > list.length)\n throw new Error('Reparent index is outside the target list.');\n list.splice(op.index ?? list.length, 0, at.item);\n }\n if (op.op === 'page.add') {\n const page: Page = {\n ...op.page,\n id: op.page.id ?? pageId(),\n items: (op.page.items ?? []).map((item) => normalizeItem(item, kindDefaults)),\n };\n if (origin !== 'user')\n page.items.forEach((item) => sanitizeAgentItems(item, options.sanitizeHTML));\n if (op.index !== undefined && op.index > doc.pages.length)\n throw new Error('Page insert index is outside the page list.');\n doc.pages.splice(op.index ?? doc.pages.length, 0, page);\n inverse = [{ op: 'page.remove', id: page.id }];\n created = flattenItems(page.items).map((i) => i.id);\n return {\n op: {\n op: 'page.add',\n page: clone(page),\n ...(op.index !== undefined ? { index: op.index } : {}),\n },\n inverse,\n created,\n };\n }\n if (op.op === 'page.set') {\n assertPagePatch(op.patch);\n const page = doc.pages.find((page) => page.id === op.id);\n if (!page) throw new Error(`Page ${op.id} does not exist.`);\n inverse = [{ op: 'page.set', id: op.id, patch: inversePatch(page, op.patch) }];\n Object.assign(page, mergePatch(page, op.patch));\n for (const key of Object.keys(op.patch))\n if ((op.patch as Record<string, unknown>)[key] === undefined)\n delete (page as unknown as Record<string, unknown>)[key];\n }\n if (op.op === 'page.remove') {\n const index = doc.pages.findIndex((page) => page.id === op.id);\n if (index < 0) throw new Error(`Page ${op.id} does not exist.`);\n const [page] = doc.pages.splice(index, 1);\n inverse = [{ op: 'page.add', page: clone(page), index }];\n }\n if (op.op === 'meta.set') {\n inverse = [{ op: 'meta.set', patch: inversePatch(doc.meta, op.patch) }];\n doc.meta = mergePatch(doc.meta, op.patch);\n }\n if (op.op === 'media.set') {\n inverse = doc.media[op.id]\n ? [{ op: 'media.set', id: op.id, media: clone(doc.media[op.id]) }]\n : [{ op: 'media.remove', id: op.id }];\n doc.media[op.id] = clone(op.media);\n }\n if (op.op === 'media.remove') {\n if (!doc.media[op.id]) throw new Error(`Media ${op.id} does not exist.`);\n inverse = [{ op: 'media.set', id: op.id, media: clone(doc.media[op.id]) }];\n delete doc.media[op.id];\n }\n return { op, inverse, created };\n}\nfunction revertedPatch(\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n current: Record<string, unknown>,\n nested: string[] = [],\n): Record<string, unknown> {\n const patch: Record<string, unknown> = {};\n for (const key of new Set([...Object.keys(before), ...Object.keys(after)])) {\n if (equal(before[key], after[key])) continue;\n if (\n nested.includes(key) &&\n current[key] &&\n typeof current[key] === 'object' &&\n (before[key] === undefined || typeof before[key] === 'object') &&\n (after[key] === undefined || typeof after[key] === 'object')\n ) {\n const sub = revertedPatch(\n (before[key] ?? {}) as Record<string, unknown>,\n (after[key] ?? {}) as Record<string, unknown>,\n current[key] as Record<string, unknown>,\n );\n if (Object.keys(sub).length) patch[key] = sub;\n } else if (equal(current[key], after[key])) patch[key] = clone(before[key]);\n }\n return patch;\n}\nfunction selectiveInverse(entry: Entry, current: AnnieDoc): Op[] {\n return entry.inverse.flatMap<Op>((op) => {\n if (op.op === 'set') {\n const before = locate(entry.before, op.id)?.item,\n after = locate(entry.after, op.id)?.item,\n now = locate(current, op.id)?.item;\n if (!before || !after || !now) return [];\n const patch = revertedPatch(before, after, now, ['style', 'text', 'data']);\n return Object.keys(patch).length ? [{ ...op, patch }] : [];\n }\n if (op.op === 'meta.set') {\n const patch = revertedPatch(entry.before.meta, entry.after.meta, current.meta);\n return Object.keys(patch).length ? [{ ...op, patch }] : [];\n }\n if (op.op === 'remove') return locate(current, op.id) ? [op] : [];\n if (op.op === 'add') return locate(current, String(op.item.id)) ? [] : [op];\n if (op.op === 'order' || op.op === 'reparent') {\n const now = locate(current, op.id),\n after = locate(entry.after, op.id);\n if (!now || !after || now.parent?.id !== after.parent?.id || now.page.id !== after.page.id)\n return [];\n return [op];\n }\n if (op.op === 'media.set' || op.op === 'media.remove')\n return equal(current.media[op.id], entry.after.media[op.id]) ? [op] : [];\n if (op.op === 'page.set') {\n assertPagePatch(op.patch);\n const before = entry.before.pages.find((page) => page.id === op.id),\n after = entry.after.pages.find((page) => page.id === op.id),\n now = current.pages.find((page) => page.id === op.id);\n if (!before || !after || !now) return [];\n const patch = revertedPatch(\n before as unknown as Record<string, unknown>,\n after as unknown as Record<string, unknown>,\n now as unknown as Record<string, unknown>,\n );\n delete patch.items;\n return Object.keys(patch).length ? [{ ...op, patch }] : [];\n }\n return [op];\n });\n}\nexport function createDoc(initial?: AnnieDoc, options: DocOptions = {}): DocModel {\n if (options.sanitizeHTML) assertEffectiveSanitizer(options.sanitizeHTML);\n const loadInitial = (doc: AnnieDoc) => {\n return migrate(doc, kindDefaultsFrom(options.kinds));\n };\n let state = initial ? loadInitial(initial) : defaultDoc();\n validateDoc(state, options);\n let index = new Map(allItems(state).map((item) => [item.id, item]));\n const observedItems = new Map<string, Signal<Item | undefined>>(),\n observedFields = new Map<string, Map<keyof Item, Signal<unknown>>>(),\n observedChildren = new Map<string, Signal<readonly string[]>>();\n const frozenCopy = <T>(value: T): T => {\n const result = clone(value);\n const freeze = (node: unknown) => {\n if (node && typeof node === 'object') {\n Object.values(node).forEach(freeze);\n Object.freeze(node);\n }\n };\n freeze(result);\n return result;\n };\n const childIds = (id: string) =>\n (index.get(id)?.children ?? state.pages.find((page) => page.id === id)?.items ?? []).map(\n (item) => item.id,\n );\n const reindex = () => {\n index = new Map(allItems(state).map((item) => [item.id, item]));\n batch(() => {\n for (const [id, observed] of observedItems) {\n const next = index.get(id);\n if (!equal(observed.peek(), next)) observed.value = frozenCopy(next);\n }\n for (const [id, fields] of observedFields)\n for (const [key, observed] of fields) {\n const next = index.get(id)?.[key];\n if (!equal(observed.peek(), next)) observed.value = frozenCopy(next);\n }\n for (const [id, observed] of observedChildren) {\n const next = childIds(id);\n if (!equal(observed.peek(), next)) observed.value = Object.freeze(next);\n }\n });\n };\n const listeners = new Set<(event: ChangeEvent) => void>(),\n history: Entry[] = [],\n future: Entry[] = [];\n let revision = 0;\n const sessionLog: ChangeSlice[] = [];\n const written = new Map<string, ItemStamp>(),\n removed = new Map<string, ItemStamp>();\n const hideAgent = () => options.agentHistory === 'hidden';\n const agentOrigin = (origin: string) => origin.startsWith('agent:');\n const walkBack = (stack: { origin: string }[], keep: (origin: string) => boolean) => {\n let index = stack.length - 1;\n while (index >= 0 && !keep(stack[index].origin)) index--;\n return index;\n };\n const pageOf = (doc: AnnieDoc) => {\n const map = new Map<string, string>();\n for (const page of doc.pages)\n for (const item of flattenItems(page.items)) map.set(item.id, page.id);\n return map;\n };\n const stampTransition = (before: AnnieDoc, after: AnnieDoc, rev: number, origin: string) => {\n const beforeItems = new Map(allItems(before).map((item) => [item.id, item])),\n afterItems = new Map(allItems(after).map((item) => [item.id, item])),\n beforePages = pageOf(before),\n afterPages = pageOf(after);\n for (const [id, item] of afterItems) {\n const prev = beforeItems.get(id);\n if (!prev || !equal(prev, item)) {\n written.set(id, { revision: rev, origin, kind: item.kind, page: afterPages.get(id)! });\n removed.delete(id);\n }\n }\n for (const [id, item] of beforeItems) {\n if (!afterItems.has(id)) {\n written.delete(id);\n removed.set(id, { revision: rev, origin, kind: item.kind, page: beforePages.get(id)! });\n }\n }\n };\n const resetSession = () => {\n revision = 0;\n sessionLog.length = 0;\n written.clear();\n removed.clear();\n };\n const commitSession = (\n slice: Omit<ChangeSlice, 'revision'>,\n before: AnnieDoc,\n after: AnnieDoc,\n ) => {\n revision += 1;\n stampTransition(before, after, revision, slice.origin);\n sessionLog.push({ ...slice, revision, ops: clone(slice.ops) });\n if (sessionLog.length > LIMITS.maxSessionLog) sessionLog.shift();\n return revision;\n };\n const emit = (\n entry: Pick<Entry, 'ops' | 'inverse' | 'origin' | 'label'> & { revision: number },\n ) => {\n for (const callback of listeners) {\n try {\n callback(\n clone({\n ops: entry.ops,\n inverse: entry.inverse,\n origin: entry.origin,\n label: entry.label,\n revision: entry.revision,\n }),\n );\n } catch {\n /* A subscriber cannot roll back a committed transaction. */\n }\n }\n };\n const model: DocModel = {\n itemSignal(id) {\n let observed = observedItems.get(id);\n if (!observed) {\n observed = signal(frozenCopy(index.get(id)));\n observedItems.set(id, observed);\n }\n return observed;\n },\n fieldSignal(id, key) {\n let fields = observedFields.get(id);\n if (!fields) {\n fields = new Map();\n observedFields.set(id, fields);\n }\n let observed = fields.get(key);\n if (!observed) {\n observed = signal<unknown>(frozenCopy(index.get(id)?.[key]));\n fields.set(key, observed);\n }\n return observed as ReadonlySignal<Item[typeof key] | undefined>;\n },\n childrenSignal(id) {\n let observed = observedChildren.get(id);\n if (!observed) {\n observed = signal<readonly string[]>(Object.freeze(childIds(id)));\n observedChildren.set(id, observed);\n }\n return observed;\n },\n apply(ops, applyOptions = {}) {\n const result: ApplyResult = { ok: false, created: [], errors: [], warnings: [] },\n origin = applyOptions.origin ?? 'api',\n lenient = !!applyOptions.lenient;\n if (options.readonly) {\n result.errors.push({ index: 0, code: 'READONLY', message: 'This document is read-only.' });\n return result;\n }\n const batchLimit = origin === 'user' ? LIMITS.maxItems : LIMITS.maxBatch;\n if (!Array.isArray(ops) || ops.length > batchLimit) {\n result.errors.push({\n index: 0,\n code: 'BATCH_LIMIT',\n message: `A batch must be an array of at most ${batchLimit} operations for origin ${origin}.`,\n });\n return result;\n }\n let draft: AnnieDoc;\n try {\n assertSafeJSON(ops);\n draft = clone(state);\n } catch (error) {\n result.errors.push({\n index: 0,\n code: 'INVALID_DATA',\n message: String(error instanceof Error ? error.message : error),\n });\n return result;\n }\n const remapped = origin.startsWith('agent:')\n ? remapAgentCreateIds(draft, ops)\n : { ops, warnings: [] as ApplyIssue[] };\n result.warnings.push(...remapped.warnings);\n const concrete: Op[] = [],\n inverse: Op[] = [],\n failures: ApplyIssue[] = [];\n const creationOps = new Map<string, number>();\n const mediaIds = () =>\n new Set(concrete.filter((op) => op.op === 'media.set').map((op) => op.id));\n const batch = remapped.ops;\n for (let index = 0; index < batch.length; index++) {\n const snapshot = lenient ? clone(draft) : undefined;\n try {\n const error = schemaError(OpSchema, batch[index]);\n if (error) throw new Error(error);\n const change = perform(draft, batch[index], origin, options);\n if (origin !== 'user' && result.created.length + change.created.length > LIMITS.maxBatch)\n throw new Error(\n `An agent batch may create at most ${LIMITS.maxBatch} items, including nested children.`,\n );\n if (lenient)\n validateDoc(\n draft,\n options,\n origin,\n new Set([...mediaIds(), ...(change.op.op === 'media.set' ? [change.op.id] : [])]),\n );\n concrete.push(change.op);\n inverse.unshift(...change.inverse);\n result.created.push(...change.created);\n change.created.forEach((id) => creationOps.set(id, index));\n } catch (error) {\n if (snapshot) draft = snapshot;\n failures.push({\n index,\n code: 'INVALID_OP',\n message: `${batch[index]?.op ?? 'operation'} #${index + 1}: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n if (!lenient && !failures.length) {\n try {\n validateDoc(draft, options, origin, mediaIds());\n } catch (error) {\n failures.push({\n index: Math.max(0, ops.length - 1),\n code: 'INVALID_DOCUMENT',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n if (!lenient && failures.length) {\n result.errors = failures;\n result.created = [];\n result.warnings = [];\n return result;\n }\n if (lenient && !concrete.length) {\n result.skipped = failures;\n result.created = [];\n return result;\n }\n if (lenient && failures.length) result.skipped = failures;\n const all = allItems(draft),\n lookup = new Map(all.map((i) => [i.id, i]));\n for (const id of result.created) {\n const item = lookup.get(id);\n if (!item) continue;\n if (\n item.kind !== 'connector' &&\n all.some(\n (other) =>\n other.id !== id &&\n !other.children?.length &&\n other.kind !== 'connector' &&\n intersects(itemBounds(item, lookup), itemBounds(other, lookup)),\n )\n )\n result.warnings.push({\n index: creationOps.get(id) ?? 0,\n code: 'OVERLAPS_EXISTING',\n message: `Item ${id} overlaps another item.`,\n });\n }\n result.ok = true;\n if (applyOptions.dryRun || !concrete.length) return result;\n const entry: Entry = {\n ops: concrete,\n inverse,\n before: state,\n after: draft,\n origin,\n label: applyOptions.label,\n };\n state = draft;\n reindex();\n const previous = history.at(-1);\n if (\n applyOptions.merge &&\n previous &&\n previous.origin === origin &&\n previous.label === entry.label\n ) {\n previous.ops.push(...entry.ops);\n previous.inverse.unshift(...entry.inverse);\n previous.after = state;\n } else {\n history.push(entry);\n if (history.length > LIMITS.maxHistory) history.shift();\n }\n future.length = 0;\n emit({\n ...entry,\n revision: commitSession(\n { origin, label: applyOptions.label, ops: concrete },\n entry.before,\n state,\n ),\n });\n return result;\n },\n get(id) {\n return clone(index.get(id));\n },\n query(selector) {\n return queryDoc(state, selector);\n },\n describe(describeOptions) {\n return describeDoc(state, describeOptions, { written, removed });\n },\n changesSince(since, changeOptions) {\n const cursor = revision;\n if (!Number.isFinite(since) || since >= cursor) return { cursor, since, changes: [] };\n const oldest = sessionLog[0];\n if (oldest && since + 1 < oldest.revision)\n return { cursor, since, changes: [], truncated: true };\n let changes = sessionLog.filter((slice) => slice.revision > since);\n const origin = changeOptions?.origin;\n if (origin === 'agent') changes = changes.filter((slice) => agentOrigin(slice.origin));\n else if (origin !== undefined) changes = changes.filter((slice) => slice.origin === origin);\n return { cursor, since, changes: clone(changes) };\n },\n kindsSince(since) {\n return kindsSince(since);\n },\n toJSON(saveOptions) {\n const json = clone(state);\n if (saveOptions?.compact === false) return json;\n for (const page of json.pages)\n page.items = page.items.map((item) => minimalItem(item, kindDefaultsFrom(options.kinds)));\n return json;\n },\n undo(undoOptions) {\n if (options.readonly) return false;\n const index = undoOptions?.origin\n ? walkBack(history, (origin) => origin === undoOptions.origin)\n : hideAgent()\n ? walkBack(history, (origin) => !agentOrigin(origin))\n : history.length - 1;\n if (index < 0) return false;\n const entry = history[index],\n selective = index !== history.length - 1,\n ops = selective ? selectiveInverse(entry, state) : entry.inverse,\n draft = clone(state),\n actual: Op[] = [],\n redo: Op[] = [];\n try {\n for (const op of ops) {\n const result = perform(draft, op, 'user', options);\n actual.push(result.op);\n redo.unshift(...result.inverse);\n }\n validateDoc(draft, options);\n } catch {\n return false;\n }\n const reverse: Entry = {\n ops: actual,\n inverse: redo,\n before: state,\n after: draft,\n origin: entry.origin,\n label: entry.label,\n };\n const before = state;\n state = draft;\n reindex();\n history.splice(index, 1);\n future.push(reverse);\n const label = `Undo ${entry.label ?? 'change'}`;\n emit({\n ops: actual,\n inverse: redo,\n origin: entry.origin,\n label,\n revision: commitSession({ origin: entry.origin, label, ops: actual }, before, state),\n });\n return true;\n },\n redo() {\n if (options.readonly) return false;\n const index = hideAgent()\n ? walkBack(future, (origin) => !agentOrigin(origin))\n : future.length - 1;\n if (index < 0) return false;\n const reverse = future[index];\n const draft = clone(state),\n ops: Op[] = [],\n inverse: Op[] = [];\n try {\n for (const op of reverse.inverse) {\n const change = perform(draft, op, 'user', options);\n ops.push(change.op);\n inverse.unshift(...change.inverse);\n }\n validateDoc(draft, options);\n } catch {\n return false;\n }\n const entry: Entry = {\n ops,\n inverse,\n before: state,\n after: draft,\n origin: reverse.origin,\n label: reverse.label,\n };\n const before = state;\n state = draft;\n reindex();\n future.splice(index, 1);\n history.push(entry);\n const label = `Redo ${entry.label ?? 'change'}`;\n emit({\n ops,\n inverse,\n origin: entry.origin,\n label,\n revision: commitSession({ origin: entry.origin, label, ops }, before, state),\n });\n return true;\n },\n load(doc) {\n if (options.readonly) throw new Error('This document is read-only.');\n const next = loadInitial(doc);\n validateDoc(next, options);\n state = next;\n reindex();\n history.length = 0;\n future.length = 0;\n resetSession();\n emit({ ops: [], inverse: [], origin: 'api', label: 'Load document', revision: 0 });\n },\n clear() {\n if (options.readonly) throw new Error('This document is read-only.');\n state = defaultDoc();\n reindex();\n history.length = 0;\n future.length = 0;\n resetSession();\n emit({ ops: [], inverse: [], origin: 'api', label: 'Clear document', revision: 0 });\n },\n on(_type, callback) {\n listeners.add(callback);\n return () => listeners.delete(callback);\n },\n get revision() {\n return revision;\n },\n get canUndo() {\n return hideAgent() ? history.some((entry) => !agentOrigin(entry.origin)) : history.length > 0;\n },\n get canRedo() {\n return hideAgent() ? future.some((entry) => !agentOrigin(entry.origin)) : future.length > 0;\n },\n };\n return model;\n}\n","/** First non-comment `text/uri-list` line, then `text/plain`. */\nexport function clipboardText(data: DataTransfer | null | undefined): string {\n const line = data\n ?.getData('text/uri-list')\n ?.split(/\\r?\\n/)\n .find((entry) => entry && !entry.startsWith('#'));\n return line?.trim() || data?.getData('text/plain') || '';\n}\n","\n/**\n * Rearranges items so that all items in the [left, k] are the smallest.\n * The k-th element will have the (k - left + 1)-th smallest value in [left, right].\n *\n * @template T\n * @param {T[]} arr the array to partially sort (in place)\n * @param {number} k middle index for partial sorting (as defined above)\n * @param {number} [left=0] left index of the range to sort\n * @param {number} [right=arr.length-1] right index\n * @param {(a: T, b: T) => number} [compare = (a, b) => a - b] compare function\n */\nexport default function quickselect(arr, k, left = 0, right = arr.length - 1, compare = defaultCompare) {\n\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp(2 * z / 3);\n const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselect(arr, k, newLeft, newRight, compare);\n }\n\n const t = arr[k];\n let i = left;\n /** @type {number} */\n let j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\n/**\n * @template T\n * @param {T[]} arr\n * @param {number} i\n * @param {number} j\n */\nfunction swap(arr, i, j) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\n/**\n * @template T\n * @param {T} a\n * @param {T} b\n * @returns {number}\n */\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","import quickselect from 'quickselect';\n\nexport default class RBush {\n constructor(maxEntries = 9) {\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n this.clear();\n }\n\n all() {\n return this._all(this.data, []);\n }\n\n search(bbox) {\n let node = this.data;\n const result = [];\n\n if (!intersects(bbox, node)) return result;\n\n const toBBox = this.toBBox;\n const nodesToSearch = [];\n\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return result;\n }\n\n collides(bbox) {\n let node = this.data;\n\n if (!intersects(bbox, node)) return false;\n\n const nodesToSearch = [];\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? this.toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) return true;\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return false;\n }\n\n load(data) {\n if (!(data && data.length)) return this;\n\n if (data.length < this._minEntries) {\n for (let i = 0; i < data.length; i++) {\n this.insert(data[i]);\n }\n return this;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n let node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n const tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n\n return this;\n }\n\n insert(item) {\n if (item) this._insert(item, this.data.height - 1);\n return this;\n }\n\n clear() {\n this.data = createNode([]);\n return this;\n }\n\n remove(item, equalsFn) {\n if (!item) return this;\n\n let node = this.data;\n const bbox = this.toBBox(item);\n const path = [];\n const indexes = [];\n let i, parent, goingUp;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n\n if (!node) { // go up\n node = path.pop();\n parent = path[path.length - 1];\n i = indexes.pop();\n goingUp = true;\n }\n\n if (node.leaf) { // check current node\n const index = findItem(item, node.children, equalsFn);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n return this;\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n path.push(node);\n indexes.push(i);\n i = 0;\n parent = node;\n node = node.children[0];\n\n } else if (parent) { // go right\n i++;\n node = parent.children[i];\n goingUp = false;\n\n } else node = null; // nothing found\n }\n\n return this;\n }\n\n toBBox(item) { return item; }\n\n compareMinX(a, b) { return a.minX - b.minX; }\n compareMinY(a, b) { return a.minY - b.minY; }\n\n toJSON() { return this.data; }\n\n fromJSON(data) {\n this.data = data;\n return this;\n }\n\n _all(node, result) {\n const nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push(...node.children);\n else nodesToSearch.push(...node.children);\n\n node = nodesToSearch.pop();\n }\n return result;\n }\n\n _build(items, left, right, height) {\n\n const N = right - left + 1;\n let M = this._maxEntries;\n let node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n const N2 = Math.ceil(N / M);\n const N1 = N2 * Math.ceil(Math.sqrt(M));\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (let i = left; i <= right; i += N1) {\n\n const right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (let j = i; j <= right2; j += N2) {\n\n const right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n }\n\n _chooseSubtree(bbox, node, level, path) {\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) break;\n\n let minArea = Infinity;\n let minEnlargement = Infinity;\n let targetNode;\n\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const area = bboxArea(child);\n const enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n }\n\n _insert(item, level, isNode) {\n const bbox = isNode ? item : this.toBBox(item);\n const insertPath = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n const node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n }\n\n // split overflowed node into two\n _split(insertPath, level) {\n const node = insertPath[level];\n const M = node.children.length;\n const m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n const splitIndex = this._chooseSplitIndex(node, m, M);\n\n const newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n }\n\n _splitRoot(node, newNode) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n }\n\n _chooseSplitIndex(node, m, M) {\n let index;\n let minOverlap = Infinity;\n let minArea = Infinity;\n\n for (let i = m; i <= M - m; i++) {\n const bbox1 = distBBox(node, 0, i, this.toBBox);\n const bbox2 = distBBox(node, i, M, this.toBBox);\n\n const overlap = intersectionArea(bbox1, bbox2);\n const area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index || M - m;\n }\n\n // sorts node children by the best axis for split\n _chooseSplitAxis(node, m, M) {\n const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;\n const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;\n const xMargin = this._allDistMargin(node, m, M, compareMinX);\n const yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) node.children.sort(compareMinX);\n }\n\n // total margin of all possible split distributions where each node is at least m full\n _allDistMargin(node, m, M, compare) {\n node.children.sort(compare);\n\n const toBBox = this.toBBox;\n const leftBBox = distBBox(node, 0, m, toBBox);\n const rightBBox = distBBox(node, M - m, M, toBBox);\n let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);\n\n for (let i = m; i < M - m; i++) {\n const child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (let i = M - m - 1; i >= m; i--) {\n const child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n }\n\n _adjustParentBBoxes(bbox, path, level) {\n // adjust bboxes along the given tree path\n for (let i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n }\n\n _condense(path) {\n // go through the path, removing empty nodes and updating bboxes\n for (let i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n\n } else this.clear();\n\n } else calcBBox(path[i], this.toBBox);\n }\n }\n}\n\nfunction findItem(item, items, equalsFn) {\n if (!equalsFn) return items.indexOf(item);\n\n for (let i = 0; i < items.length; i++) {\n if (equalsFn(item, items[i])) return i;\n }\n return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n if (!destNode) destNode = createNode(null);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (let i = k; i < p; i++) {\n const child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a, b) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n const minX = Math.max(a.minX, b.minX);\n const minY = Math.max(a.minY, b.minY);\n const maxX = Math.min(a.maxX, b.maxX);\n const maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) *\n Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n return a.minX <= b.minX &&\n a.minY <= b.minY &&\n b.maxX <= a.maxX &&\n b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n return b.minX <= a.maxX &&\n b.minY <= a.maxY &&\n b.maxX >= a.minX &&\n b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n return {\n children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n const stack = [left, right];\n\n while (stack.length) {\n right = stack.pop();\n left = stack.pop();\n\n if (right - left <= n) continue;\n\n const mid = left + Math.ceil((right - left) / n / 2) * n;\n quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n","import RBush from 'rbush';\nimport type { Box, Item, Outline, Point } from '../core/types';\nimport { contains, containsPoint, flattenItems, itemBounds, type ItemLookup } from './box';\nimport { pointInPolygon, rotatePoint, segmentDistance } from './vec';\nimport { routeConnector, type OutlineResolver } from './router';\ninterface Entry {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n item: Item;\n order: number;\n parents: Item[];\n}\nexport interface PickOptions {\n tolerance?: number;\n enteredGroup?: string;\n includeLocked?: boolean;\n outline?: OutlineResolver;\n ignore?: (item: Item) => boolean;\n}\nexport function hitTest(\n item: Item,\n point: Point,\n tolerance = 4,\n lookup?: ItemLookup,\n outline?: Outline | Outline[] | OutlineResolver,\n): boolean {\n const resolveOutline = typeof outline === 'function' ? outline : undefined;\n if (item.kind === 'group') return containsPoint(itemBounds(item, lookup, resolveOutline), point);\n if (item.kind === 'connector') {\n const points = routeConnector(item, lookup, resolveOutline).points;\n return points\n .slice(1)\n .some(\n (p, i) =>\n segmentDistance(point, points[i], p) <= tolerance + (item.style?.strokeWidth ?? 2) / 2,\n );\n }\n const p = rotatePoint(\n point,\n { x: item.x + item.w / 2, y: item.y + item.h / 2 },\n -(item.rotation ?? 0),\n ),\n x = p.x - item.x,\n y = p.y - item.y,\n stroke = tolerance + (item.style?.strokeWidth ?? 2) / 2;\n const linePoints =\n item.points ??\n (item.kind === 'line'\n ? [\n [0, 0],\n [item.w, item.h],\n ]\n : undefined);\n if ((item.kind === 'line' || item.kind === 'path') && linePoints) {\n const pts = linePoints.map(([px, py]) => ({ x: item.x + px, y: item.y + py }));\n return (\n (item.closed && pointInPolygon(p, pts)) ||\n pts.slice(1).some((pt, i) => segmentDistance(p, pts[i], pt) <= stroke)\n );\n }\n const filled =\n !!item.text?.value ||\n (item.style?.fill !== undefined && item.style.fill !== 'none') ||\n ['note', 'text', 'image', 'video', 'link', 'html', 'group'].includes(item.kind);\n const resolvedOutline = typeof outline === 'function' ? outline(item) : outline;\n if (resolvedOutline) {\n const outlines = Array.isArray(resolvedOutline) ? resolvedOutline : [resolvedOutline],\n local = { x, y };\n return outlines.some((shape) => {\n if (!shape.points.length) return false;\n if (shape.closed && filled && pointInPolygon(local, shape.points)) return true;\n const points = shape.closed ? [...shape.points, shape.points[0]] : shape.points;\n return points.length === 1\n ? segmentDistance(local, points[0], points[0]) <= stroke\n : points\n .slice(1)\n .some((point, index) => segmentDistance(local, points[index], point) <= stroke);\n });\n }\n if (item.kind === 'ellipse') {\n const rx = item.w / 2,\n ry = item.h / 2;\n if (!rx || !ry) return false;\n const d = Math.hypot((x - rx) / rx, (y - ry) / ry),\n edge = stroke / Math.min(rx, ry);\n return filled ? d <= 1 + edge : Math.abs(d - 1) <= edge;\n }\n if (item.kind === 'diamond') {\n const vertices = [\n { x: item.w / 2, y: 0 },\n { x: item.w, y: item.h / 2 },\n { x: item.w / 2, y: item.h },\n { x: 0, y: item.h / 2 },\n ],\n local = { x, y };\n return (\n (filled && pointInPolygon(local, vertices)) ||\n vertices.some((a, i) => segmentDistance(local, a, vertices[(i + 1) % 4]) <= stroke)\n );\n }\n const outer = x >= -stroke && x <= item.w + stroke && y >= -stroke && y <= item.h + stroke;\n return (\n outer && (filled || x <= stroke || x >= item.w - stroke || y <= stroke || y >= item.h - stroke)\n );\n}\nexport class SpatialIndex {\n private tree = new RBush<Entry>();\n private lookup = new Map<string, Item>();\n private entries = new Map<string, Entry>();\n constructor(\n items: Item[] = [],\n private outline?: OutlineResolver,\n ) {\n this.set(items);\n }\n set(items: Item[], outline: OutlineResolver | undefined = this.outline): void {\n this.outline = outline;\n this.tree.clear();\n this.lookup = new Map(flattenItems(items).map((i) => [i.id, i]));\n const entries: Entry[] = [];\n let order = 0;\n const walk = (list: Item[], parents: Item[]) => {\n for (const item of list) {\n const b = itemBounds(item, this.lookup, this.outline);\n entries.push({\n minX: b.x,\n minY: b.y,\n maxX: b.x + b.w,\n maxY: b.y + b.h,\n item,\n order: order++,\n parents,\n });\n if (item.children) walk(item.children, [...parents, item]);\n }\n };\n walk(items, []);\n this.entries = new Map(entries.map((entry) => [entry.item.id, entry]));\n this.tree.load(entries);\n }\n search(box: Box): Item[] {\n return this.tree\n .search({ minX: box.x, minY: box.y, maxX: box.x + box.w, maxY: box.y + box.h })\n .filter((e) => !e.item.hidden && !e.parents.some((p) => p.hidden))\n .sort((a, b) => a.order - b.order)\n .map((e) => e.item);\n }\n enclosed(\n box: Box,\n options: { enteredGroup?: string; ignore?: (item: Item) => boolean } = {},\n ): Item[] {\n const selected = new Map<string, Entry>();\n const candidates = this.tree.search({\n minX: box.x,\n minY: box.y,\n maxX: box.x + box.w,\n maxY: box.y + box.h,\n });\n const visibleBounds = (entry: Entry): Box | undefined => {\n if (\n entry.item.hidden ||\n entry.item.locked ||\n options.ignore?.(entry.item) ||\n entry.parents.some((parent) => parent.hidden || parent.locked || options.ignore?.(parent))\n )\n return;\n return {\n x: entry.minX,\n y: entry.minY,\n w: entry.maxX - entry.minX,\n h: entry.maxY - entry.minY,\n };\n };\n for (const candidate of candidates) {\n const visible = visibleBounds(candidate);\n if (!visible || !contains(box, visible)) continue;\n const groups = candidate.parents.filter((parent) => parent.kind === 'group');\n const entered = groups.findIndex((parent) => parent.id === options.enteredGroup);\n const outer = groups[entered + 1];\n const entry = outer ? this.entries.get(outer.id)! : candidate;\n if (entry.item.id === options.enteredGroup) continue;\n const bounds = entry === candidate ? visible : visibleBounds(entry);\n if (bounds && contains(box, bounds)) selected.set(entry.item.id, entry);\n }\n return [...selected.values()].sort((a, b) => a.order - b.order).map((entry) => entry.item);\n }\n pick(point: Point, options: PickOptions = {}): Item | undefined {\n const tolerance = options.tolerance ?? 6;\n const found = this.tree\n .search({\n minX: point.x - tolerance,\n minY: point.y - tolerance,\n maxX: point.x + tolerance,\n maxY: point.y + tolerance,\n })\n .sort((a, b) => b.order - a.order);\n for (const e of found) {\n if (\n e.item.hidden ||\n options.ignore?.(e.item) ||\n (!options.includeLocked && e.item.locked) ||\n e.parents.some(\n (p) => p.hidden || options.ignore?.(p) || (!options.includeLocked && p.locked),\n )\n )\n continue;\n if (!hitTest(e.item, point, tolerance, this.lookup, options.outline ?? this.outline))\n continue;\n const groups = e.parents.filter((p) => p.kind === 'group');\n const entered = groups.findIndex((p) => p.id === options.enteredGroup);\n const outer = groups[entered + 1];\n return outer ?? e.item;\n }\n return undefined;\n }\n}\n"],"x_google_ignoreList":[0,5,6],"mappings":"mRAAA,IAAmc,EAA/b,EAAE,OAAO,IAAI,kBAAkB,SAAS,IAAI,GAAK,EAAE,EAA8T,QAA3T,CAAC,IAAI,EAAE,GAAE,EAAuI,KAApI,WAAY,IAAI,EAAE,EAAW,IAAT,OAAO,OAAa,IAAI,GAAE,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAM,IAAA,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,EAAE,EAAK,EAAE,IAAI,EAAE,IAAE,EAAE,EAAE,EAAE,GAAE,EAAE,EAAE,CAAC,CAAC,CAAhI,QAA+I,IAAI,GAAE,CAAC,IAAI,EAAE,EAAe,IAAb,OAAO,EAAE,SAAe,IAAI,GAAE,CAAC,IAAI,EAAE,EAAE,EAAqB,GAAnB,EAAE,OAAO,EAAE,EAAE,IAAG,IAAQ,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,CAAA,MAAO,GAAO,IAAG,EAAE,EAAE,GAAE,EAAG,CAAC,EAAE,CAAC,CAAC,CAAS,GAAR,EAAE,EAAE,IAAO,EAAE,MAAM,CAAC,CAAS,CAA6E,IAAA,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,GAAG,CAAA,QAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,QAAQ,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,IAAI,GAAG,EAAE,IAAI,EAA6G,OAA1G,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,QAAW,IAAI,EAAE,IAAE,EAAE,EAAE,EAAE,GAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAK,GAAG,EAAE,GAAE,EAAE,EAAE,GAAU,EAAO,IAAG,IAAK,EAAE,EAA+F,OAA5F,EAAE,EAAE,OAAU,IAAI,EAAE,IAAG,EAAE,EAAE,EAAE,EAAE,OAAU,IAAI,EAAE,IAAE,EAAE,EAAE,EAAE,EAAE,GAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAS,CAAE,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,OAAO,EAAE,EAAE,QAAQ,KAAK,EAAE,MAAM,OAAO,EAAE,EAAE,UAAU,KAAK,KAAK,MAAM,OAAO,EAAE,EAAE,IAAI,CAAwnC,SAAS,EAAE,EAAE,GAAG,OAAO,IAAI,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,OAAM,EAAG,OAAM,CAAE,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAqC,QAA3B,IAAI,IAAE,EAAE,EAAE,GAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAE,OAAW,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,GAAsB,IAAnB,IAAI,EAAE,EAAE,EAAE,OAAO,OAAa,IAAI,GAAE,CAAC,IAAI,EAAE,EAAE,GAAK,IAAK,EAAE,GAAG,EAAE,EAAE,EAAE,QAAW,IAAI,IAAE,EAAE,EAAE,EAAE,QAAU,IAAI,EAAE,IAAE,EAAE,EAAE,EAAE,IAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAU,IAAI,EAAE,IAAE,EAAE,OAAO,GAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAy9B,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,EAAa,GAAX,EAAE,OAAO,EAAK,mBAAmB,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,GAAG,CAAA,MAAO,GAAuB,MAApB,EAAE,IAAG,EAAG,EAAE,GAAG,EAAE,EAAE,GAAS,CAAC,CAAA,QAAS,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI,KAAK,MAAM,IAAI,MAAM,uBAAuB,EAAE,MAAM,EAAE,EAAE,KAAK,IAAG,EAAM,EAAE,KAAK,GAAE,EAAE,MAAM,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,KAAK,MAAM,OAAO,EAAE,EAAE,KAAQ,GAAE,EAAE,KAAK,KAAK,CAA3iG,EAAE,UAAU,MAAM,EAAE,EAAE,UAAU,EAAE,WAAW,OAAM,CAAE,EAAE,EAAE,UAAU,EAAE,SAAS,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,EAAK,IAAI,QAAQ,IAAI,EAAE,IAAG,EAAE,EAAE,EAAE,KAAK,EAAE,OAAU,IAAI,EAAE,EAAE,EAAE,EAAO,EAAE,WAAW,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,SAAS,GAAG,IAAI,EAAE,KAAK,QAAQ,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,OAAU,IAAI,IAAG,EAAE,EAAE,EAAE,EAAE,OAAO,QAAU,IAAI,IAAG,EAAE,EAAE,EAAE,EAAE,OAAO,GAAK,IAAI,KAAK,IAAG,KAAK,EAAE,OAAU,IAAI,GAAE,EAAE,WAAW,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,UAAU,SAAS,GAAG,IAAI,EAAE,KAAK,OAAgiG,SAAW,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,CAAA,MAAO,GAAS,MAAN,EAAE,IAAU,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,GAAuB,OAApB,EAAE,OAAO,SAAS,EAAS,CAAC,CAAzoG,CAAE,WAAW,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,OAAO,EAAE,EAAE,UAAU,QAAQ,WAAW,OAAO,KAAK,KAAK,EAAE,EAAE,UAAU,SAAS,WAAW,OAAO,KAAK,MAAM,EAAE,EAAE,EAAE,UAAU,OAAO,WAAW,OAAO,KAAK,KAAK,EAAE,EAAE,UAAU,KAAK,WAAW,IAAI,EAAE,KAAK,OAAO,EAAE,WAAW,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,eAAe,EAAE,UAAU,QAAQ,CAAC,IAAI,WAAW,IAAI,EAAE,EAAE,MAA+B,YAAjB,IAAI,IAAE,EAAE,EAAE,KAAK,GAAS,KAAK,CAAC,EAAE,IAAI,SAAS,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,MAAM,IAAI,MAAM,mBAAkB,SAAU,GAAM,IAAI,GAAG,IAAI,GAAK,EAAE,IAAI,IAAG,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAvE,CAAyE,MAAM,KAAK,EAAE,EAAE,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,KAAK,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAA,QAAS,GAAG,CAAC,CAAC,IAAihB,EAAE,UAAU,IAAI,EAAE,EAAE,UAAU,EAAE,WAAsB,GAAX,KAAK,IAAG,EAAM,EAAE,KAAK,EAAE,OAAM,EAAG,GAAG,KAAK,GAAG,KAAK,GAAG,OAAM,EAAc,GAAX,KAAK,IAAG,EAAM,KAAK,IAAI,EAAE,OAAM,EAAsB,GAAnB,KAAK,EAAE,EAAE,KAAK,GAAG,EAAK,KAAK,EAAE,IAAI,EAAE,MAAkB,OAAX,KAAK,IAAG,GAAS,EAAG,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,KAAK,KAAO,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,IAAI,KAAK,KAAG,KAAK,EAAE,EAAE,KAAK,IAAG,GAAI,KAAK,IAAI,CAAA,MAAO,GAAG,KAAK,EAAE,EAAE,KAAK,GAAG,GAAG,KAAK,GAAG,CAAwB,OAAvB,EAAE,EAAE,EAAE,MAAM,KAAK,IAAG,GAAS,CAAE,EAAE,EAAE,UAAU,EAAE,SAAS,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC,KAAK,GAAG,GAAG,IAAI,IAAI,EAAE,KAAK,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,GAAG,QAAQ,IAAI,KAAK,IAAG,EAAE,UAAU,EAAE,KAAK,KAAK,QAAW,IAAI,KAAK,GAAE,CAAC,KAAK,IAAG,GAAI,IAAI,IAAI,EAAE,KAAK,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAE,EAAE,EAAE,UAAU,EAAE,WAAW,KAAK,EAAE,KAAK,GAAG,CAAC,KAAK,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,OAAO,eAAe,EAAE,UAAU,QAAQ,CAAC,IAAI,WAAW,GAAG,EAAE,KAAK,EAAE,MAAM,IAAI,MAAM,kBAAkB,IAAI,EAAE,EAAE,MAAwC,GAAlC,KAAK,SAAY,IAAI,IAAE,EAAE,EAAE,KAAK,GAAK,GAAG,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC,IAAsf,EAAE,UAAU,EAAE,WAAW,IAAI,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE,KAAK,EAAE,OAAO,QAAQ,IAAI,KAAK,EAAE,OAAO,IAAI,EAAE,KAAK,IAAO,mBAAmB,IAAE,KAAK,EAAE,EAAC,CAAA,QAAS,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,WAAW,GAAG,EAAE,KAAK,EAAE,MAAM,IAAI,MAAM,kBAAkB,KAAK,GAAG,EAAE,KAAK,IAAG,EAAG,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI,EAAE,EAAS,OAAP,EAAE,KAAY,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,WAAgB,EAAE,KAAK,IAAI,KAAK,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,KAAK,GAAG,EAAO,EAAE,KAAK,GAAG,EAAE,KAAK,EAAE,EAAE,UAAU,QAAQ,WAAW,KAAK,GAAG,ECsDxhJ,IACa,EACX,CACE,EAAI,IAAA,IACC,EACH,OAAQ,eACR,QAAS,EACT,MAAO,EAAI,OAAS,CAAC,EACrB,KAAM,EAAI,MAAQ,CAAE,MAAO,oBAE7B,EAAI,IACF,MAAM,OAAE,KAAW,GAAS,EACtB,EAAQ,GAAU,EAAI,MAC5B,MAAO,IACF,EACH,QAAS,EACT,MAAO,MAAM,QAAQ,GACjB,EAAM,IAAK,IAAA,IACN,EACH,KACuB,iBAAd,EAAK,MAAqB,mBAAmB,KAAK,EAAK,MAC1D,EAAK,KAAK,QAAQ,UAAW,SAC7B,EAAK,QAEb,KAMZ,SAAgB,EACd,EACA,EAA8C,CAAC,GAE/C,IAAK,GAA0B,iBAAV,EAAoB,MAAM,IAAI,MAAM,oCACzD,IAAI,EAAM,EAAM,GAChB,QAAmB,IAAf,EAAI,QAAuC,iBAAf,EAAI,OAClC,MAAM,IAAI,MAAM,yCAClB,MAAM,EAAU,EAAI,SAAW,EAC/B,GAAuB,iBAAZ,IAAyB,OAAO,UAAU,IAAY,EAAU,EACzE,MAAM,IAAI,MAAM,4BAClB,GAAI,EAAA,EACF,MAAM,IAAI,MACR,mBAAmB,wCAEvB,IAAK,IAAI,EAAO,EAAU,EAAG,GAAA,EAAyB,IAAQ,EAAM,EAAW,GAAM,GACrF,MAAM,EAAS,EAQf,OAPI,MAAM,QAAQ,EAAO,SACvB,EAAO,MAjGX,SAA2B,GACzB,MAAM,EAAM,IAAI,IACd,EAAa,EAAM,QAAS,GAAS,EAAK,OAAS,KAAK,IAAK,GAAS,EAAK,KAEvE,EAAU,IACd,IAAI,EAAK,EACT,IAAK,IAAI,EAAS,EAAG,EAAI,IAAI,GAAK,IAAU,EAAK,GAAG,KAAQ,IAE5D,OADA,EAAI,IAAI,GACD,GAEH,EAAW,IACf,MAAM,EAAW,EAAM,UAAU,IAAI,GACrC,GAAmB,UAAf,EAAM,KAAkB,MAAO,IAAK,KAAW,EAAW,CAAE,YAAa,CAAC,GAC9E,MAAM,KAAE,EAAA,MAAM,EAAA,KAAO,EAAA,MAAM,KAAU,GAAS,EACxC,EAAM,CAAE,EAAG,EAAM,GAAK,EAAG,EAAG,EAAM,GAAK,EAAG,EAAG,EAAM,GAAK,IAAK,EAAG,EAAM,GAAK,KAC3E,EAAmB,CACvB,CACE,KAAM,OACN,GAAI,EAAO,GAAG,EAAM,oBACjB,EACH,SAAU,EAAM,SAChB,MAAO,CAAE,KAAM,QAAS,YAAa,OAAQ,MACzC,EAAO,CAAE,QAAS,CAAC,IAGrB,EAAyB,iBAAV,EAAqB,EAAQ,EAAM,KAWxD,OAVI,GACF,EAAM,KAAK,CACT,KAAM,OACN,GAAI,EAAO,GAAG,EAAM,YACpB,EAAG,EAAI,EACP,EAAG,EAAI,EAAI,GACX,EAAG,EAAI,EACP,EAAG,GACH,KAAM,CAAE,MAAO,EAAO,KAAM,GAAI,MAAO,QAAS,OAAQ,SAErD,IACF,KACA,EACH,KAAM,QACN,KAAM,EAAM,MAAQ,EACpB,SAAU,IAAI,KAAW,GAAY,MAGzC,OAAO,EAAM,IAAK,IAAA,IACb,EACH,MAAO,MAAM,QAAQ,EAAK,OAAS,EAAK,MAAM,IAAI,GAAW,EAAK,QAEtE,CAiDmB,CAAkB,EAAO,OAAO,IAAK,IAAA,IAC/C,EACH,MAAO,MAAM,QAAQ,EAAK,OACtB,EAAK,MAAM,IAAK,GAAS,EAAc,EAAM,IAC7C,EAAK,UAEN,CACT,CCjGA,IAAM,GAAK,cAEE,GAAiB,gEAEjB,GACX,yEAEF,SAAgB,GAAc,GAC5B,GAAqB,iBAAV,EAAoB,OAC/B,MAAM,EAAO,EAAM,OACnB,GAAI,GAAe,KAAK,GAAO,OAAO,EAAK,QAAQ,OAAQ,IAC3D,IACE,MAAM,EAAM,IAAI,IAAI,GACpB,GAAqB,UAAjB,EAAI,UAAyC,WAAjB,EAAI,SAAuB,OAE3D,OADA,EAAI,SAAW,EAAI,SAAW,GACvB,EAAI,IACb,CAAA,MACE,MACF,CACF,CAGA,SAAgB,GAAgB,GAC9B,IACE,MAAM,EAAM,IAAI,IAAI,GACpB,OAAqB,UAAjB,EAAI,UAAyC,WAAjB,EAAI,aAChC,EAAI,WAAY,EAAI,WAO5B,SAAkC,GAChC,MAAM,EAAW,EACd,QAAQ,WAAY,IACpB,QAAQ,OAAQ,IAChB,cACH,GACe,cAAb,GACa,YAAb,GACa,OAAb,GACA,EAAS,SAAS,eAClB,EAAS,SAAS,WAClB,EAAS,SAAS,aAElB,OAAO,EACT,MAAM,EAAS,EAAS,MAAM,sCAC9B,GAAI,GAAU,GAAc,EAAO,IAAK,OAAO,EAC/C,MAAM,EAyBR,SAAqB,GACnB,GAAI,4BAA4B,KAAK,GAAW,OAAO,EACvD,MAAM,EAAK,GAAU,GACrB,OAAO,EAAK,GAAW,QAAM,CAC/B,CA7Ba,CAAY,GACvB,GAAI,EAAI,OAAO,GAAc,GAC7B,MAAM,EAAK,GAAU,GACrB,IAAK,EAAI,OAAO,EAChB,GAAI,EAAG,MAAO,GAAkB,IAAT,GAAa,OAAO,EAC3C,GAAc,IAAV,EAAG,IAAY,EAAG,MAAM,EAAG,GAAG,MAAO,GAAkB,IAAT,GAAa,OAAO,EACtE,GAAyB,QAAZ,MAAR,EAAG,KAAgD,QAAZ,MAAR,EAAG,OAAgD,OAApB,EAAG,IACpE,OAAO,EACT,MAAM,EAAS,GAAW,GAC1B,QAAO,GAAS,GAAc,EAChC,CAhCY,CAAyB,EAAI,UACvC,CAAA,MACE,OAAO,CACT,CACF,CA8BA,SAAS,GAAc,GACrB,MAAM,EAAQ,EAAM,MAAM,KAAK,IAAI,QACnC,GAAqB,IAAjB,EAAM,QAAgB,EAAM,KAAM,GAAM,EAAI,KAAM,OAAO,EAC7D,MAAO,EAAG,GAAK,EACf,OAAU,IAAN,GAAiB,KAAN,GAAkB,MAAN,IACjB,MAAN,GAAmB,MAAN,IACP,MAAN,GAAmB,MAAN,IACP,MAAN,GAAa,GAAK,IAAM,GAAK,KACvB,MAAN,GAAa,GAAK,IAAM,GAAK,MACvB,MAAN,IAAoB,KAAN,GAAkB,KAAN,IACvB,GAAK,QACd,CAQA,SAAS,GAAW,GAClB,MAAM,EAAO,GAAI,EAAO,IAAM,EAAK,OAAmB,IAAZ,EAAO,MAAa,EAAO,IAAM,EAAK,OAAmB,IAAZ,EAAO,KAC9F,OACgB,IAAd,EAAO,IACO,IAAd,EAAO,IACO,IAAd,EAAO,IACO,IAAd,EAAO,IACO,IAAd,EAAO,IACO,QAAd,EAAO,IAGS,MAAd,EAAO,IAA6B,QAAd,EAAO,IAAiB,EAAO,MAAM,EAAG,GAAG,MAAO,GAAkB,IAAT,GAD5E,OACT,CAGF,CAEA,SAAS,GAAU,GACjB,IAAK,EAAK,SAAS,KAAM,OACzB,IAAI,EAAQ,EACZ,MAAM,EAAS,EAAM,MAAM,+BAC3B,GAAI,EAAQ,CACV,MAAO,EAAG,EAAG,EAAG,GAAK,EAAO,GAAG,MAAM,KAAK,IAAI,QAC9C,GAAI,CAAC,EAAG,EAAG,EAAG,GAAG,KAAM,GAAM,EAAI,KAAM,OACvC,EAAQ,GAAG,EAAM,MAAM,GAAI,EAAO,GAAG,UAAW,GAAK,EAAK,KAAM,GAAK,EAAK,GAC5E,CACA,MAAM,EAAS,EAAM,MAAM,MAC3B,GAAI,EAAO,OAAS,EAAG,OACvB,MAAM,EAAS,GACb,EACI,EACG,MAAM,KACN,OAAO,SACP,IAAK,GAAU,mBAAmB,KAAK,GAAQ,SAAS,EAAM,IAAM,KACvE,GACA,EAAO,EAAM,EAAO,IACpB,EAAyB,IAAlB,EAAO,OAAe,EAAM,EAAO,IAAM,GACtD,GAAI,EAAK,KAAK,OAAO,QAAU,EAAK,KAAK,OAAO,OAAQ,OACxD,GAAsB,IAAlB,EAAO,OAAc,OAAuB,IAAhB,EAAK,OAAe,OAAO,EAC3D,MAAM,EAAU,EAAI,EAAK,OAAS,EAAK,OACvC,OAAI,EAAU,OAAd,EACO,IAAI,KAAS,MAAM,GAAS,KAAK,MAAO,EACjD,CAEA,SAAgB,GAAW,GACzB,IACE,OAAO,IAAI,IAAI,GAAM,SAAS,QAAQ,SAAU,GAClD,CAAA,MACE,OAAO,CACT,CACF,CAEA,SAAgB,GAAW,GACzB,MAAM,EAAa,GAAc,GACjC,IAAK,GAAc,EAAW,WAAW,SAAU,OACnD,MAAM,EAAM,IAAI,IAAI,GACd,EAAO,EAAI,SAAS,QAAQ,aAAc,IAC1C,EAAQ,EAAI,SAAS,MAAM,KAAK,OAAO,SAC7C,GAAI,EAAK,SAAS,SAAU,CAC1B,MAAM,EACK,aAAT,EACI,EAAM,GACL,EAAI,aAAa,IAAI,MACtB,EAAM,EAAM,UAAW,GAAS,0BAA0B,KAAK,IAAS,GAC9E,GAAI,GAAM,GAAG,KAAK,GAAK,MAAO,CAAE,SAAU,UAAW,KACvD,CACA,IAAK,0BAA0B,KAAK,GAAO,OAC3C,MAAM,EAAqB,UAAb,EAAM,IAAkB,EAAK,WAAW,UAAY,EAAI,EAChE,EAAK,EAAM,GACjB,IAAK,IAAO,QAAQ,KAAK,GAAK,OAC9B,MAAM,EAAO,EAAI,aAAa,IAAI,MAAQ,EAAM,EAAQ,IAAI,MAAM,aAAa,GAC/E,MAAO,CAAE,SAAU,QAAS,QAAQ,EAAO,CAAE,QAAS,CAAC,EACzD,CAEA,SAAgB,GAAW,GACzB,MAAM,EAAQ,GAAW,GACzB,GAAK,EACL,MAA0B,YAAnB,EAAM,SACT,0CAA0C,EAAM,WAChD,kCAAkC,EAAM,KAAK,EAAM,KAAO,MAAM,mBAAmB,EAAM,QAAU,IACzG,CCzHA,IAAM,GAAA,CAAS,EAAY,IAAe,KAAK,UAAU,KAAO,KAAK,UAAU,GAC/E,SAAS,GAAW,EAAc,GAChC,OAAO,EACH,EAAS,GACT,EACG,QAAQ,kDAAmD,SAC3D,QAAQ,KAAM,QACd,QAAQ,KAAM,QACd,QAAQ,KAAM,UACd,QAAQ,KAAM,QACvB,CAkBA,SAAS,GAAgB,GACvB,GAAI,OAAO,KAAK,GAAO,KAAM,GAAgB,SAAR,GAA0B,eAAR,GACrD,MAAM,IAAI,MACR,4FAEN,CACA,SAAS,GAAO,EAAe,GAC7B,IAAK,MAAM,KAAQ,EAAI,MAAO,CAC5B,MAAM,EAAA,CAAQ,EAAc,KAC1B,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAK,OAAQ,IAAS,CAChD,MAAM,EAAO,EAAK,GAClB,GAAI,EAAK,KAAO,EAAI,MAAO,CAAE,OAAM,OAAM,QAAO,SAAQ,QACxD,GAAI,EAAK,SAAU,CACjB,MAAM,EAAQ,EAAK,EAAK,SAAU,GAClC,GAAI,EAAO,OAAO,CACpB,CACF,GAEI,EAAS,EAAK,EAAK,OACzB,GAAI,EAAQ,OAAO,CACrB,CACF,CACA,SAAS,GAAY,EAAe,GAClC,MAAM,EAAS,GAAO,EAAK,GAC3B,IAAK,EAAQ,CACX,MAAM,EAAa,EAAS,GACzB,IAAK,GAAM,EAAE,IACb,MAAM,EAAG,GACZ,MAAM,IAAI,MACR,QAAQ,oBAAqB,EAAW,OAAS,eAAe,EAAW,KAAK,SAAW,KAE/F,CACA,OAAO,CACT,CACA,SAAS,GAA6B,EAAW,EAAmB,EAAmB,IACrF,MAAM,EAAO,IAAK,GAClB,IAAK,MAAO,EAAK,KAAU,OAAO,QAAQ,GACxC,QAAc,IAAV,EAIJ,GAAI,EAAO,SAAS,IAAQ,GAA0B,iBAAV,IAAuB,MAAM,QAAQ,GAAQ,CACvF,MAAM,EAAM,EAAK,GACjB,EAAK,GAAO,GAAW,GAAsB,iBAAR,EAAoB,EAAiB,CAAC,EAAG,EAChF,MAAO,EAAK,GAAO,EAAM,eANhB,EAAK,GAQhB,OAAO,CACT,CACA,SAAS,GACP,EACA,EACA,EAAmB,IAEnB,MAAM,EAAS,EACT,EAAkC,CAAC,EACzC,IAAK,MAAM,KAAO,OAAO,KAAK,GAAQ,CACpC,MAAM,EAAS,EAAkC,GACjD,EAAO,GACL,EAAO,SAAS,IAChB,GACiB,iBAAV,GACP,EAAO,IACgB,iBAAhB,EAAO,GACV,GAAa,EAAO,GAAgB,GACpC,EAAM,EAAO,GACrB,CACA,OAAO,CACT,CACA,SAAS,GAAe,EAAgB,EAAQ,EAAG,iBAAO,IAAI,KAC5D,GAAI,EAAQ,EAAO,aACjB,MAAM,IAAI,MAAM,+CAA+C,EAAO,iBACxE,GACE,SAEiB,kBAAV,GACU,iBAAV,EAEP,OACF,GAAqB,iBAAV,EAAoB,CAC7B,IAAK,OAAO,SAAS,GAAQ,MAAM,IAAI,MAAM,+BAC7C,MACF,CACA,GAAqB,iBAAV,EAAoB,MAAM,IAAI,MAAM,4CAC/C,GAAI,EAAK,IAAI,GAAQ,MAAM,IAAI,MAAM,4CACrC,MAAM,EAAQ,OAAO,eAAe,GACpC,IAAK,MAAM,QAAQ,IAAU,IAAU,OAAO,WAAuB,OAAV,EACzD,MAAM,IAAI,MAAM,+CAClB,EAAK,IAAI,GACT,IAAK,MAAO,EAAK,KAAU,OAAO,QAAQ,GAAQ,CAChD,GAAI,CAAC,YAAa,YAAa,eAAe,SAAS,GACrD,MAAM,IAAI,MAAM,mBAAmB,MACrC,GAAe,EAAO,EAAQ,EAAG,EACnC,CACA,EAAK,OAAO,EACd,CACA,SAAS,GACP,EACA,EAAsB,CAAC,EACvB,EAAS,OACT,GAEA,GAAe,GACf,MAAM,EAAQ,EAAY,EAAgB,GAC1C,GAAI,EAAO,MAAM,IAAI,MAAM,GAC3B,MAAM,iBAAM,IAAI,IACd,iBAAU,IAAI,IAChB,IAAI,EAAQ,EACZ,IAAK,MAAM,KAAQ,EAAI,MAAO,CAC5B,GAAI,EAAQ,IAAI,EAAK,IAAK,MAAM,IAAI,MAAM,qBAAqB,EAAK,OACpE,EAAQ,IAAI,EAAK,IACjB,MAAM,EAAA,CAAQ,EAAc,KAC1B,GAAI,EAAQ,EAAO,SAAU,MAAM,IAAI,MAAM,6BAC7C,IAAK,MAAM,KAAQ,EAAM,CAEvB,GADA,IACuB,iBAAZ,EAAK,KAAoB,EAAK,GACvC,MAAM,IAAI,MAAM,4CAClB,IAAK,MAAM,IAAS,CAAC,IAAK,IAAK,IAAK,KAClC,GAA2B,iBAAhB,EAAK,KAAwB,OAAO,SAAS,EAAK,IAC3D,MAAM,IAAI,MAAM,QAAQ,EAAK,sBAAsB,MACvD,GAAI,EAAI,IAAI,EAAK,IAAK,MAAM,IAAI,MAAM,qBAAqB,EAAK,OAEhE,GADA,EAAI,IAAI,EAAK,IACT,EAAK,UAA0B,UAAd,EAAK,KACxB,MAAM,IAAI,MAAM,qCAAqC,EAAK,QAC5D,KAAkB,cAAd,EAAK,MAA0B,EAAK,MAAS,EAAK,IACpD,MAAM,IAAI,MAAM,aAAa,EAAK,wCACpC,KAAkB,UAAd,EAAK,MAAsB,EAAK,OAAU,EAAI,MAAM,EAAK,QAC3D,MAAM,IAAI,MAAM,SAAS,EAAK,+BAA+B,EAAK,OAAS,cAC7E,GAAkB,UAAd,EAAK,MAAkC,SAAd,EAAK,WAAiC,IAAd,EAAK,KAAoB,CAC5E,IAAK,GAAc,EAAK,MAAO,MAAM,IAAI,MAAM,aAAa,EAAK,QACjE,GAAkB,UAAd,EAAK,OAAqB,GAAW,EAAK,MAC5C,MAAM,IAAI,MAAM,cAAc,EAAK,OACvC,CACA,MAAM,EAAe,EAAQ,OAAO,KAAM,GAAS,EAAK,OAAS,EAAK,OAAO,OAC7E,GAAI,EAAc,CAChB,MAAM,EAAc,EAAY,EAAmD,GACnF,GAAI,EAAa,MAAM,IAAI,MAAM,GAAG,EAAK,QAAQ,EAAK,OAAO,IAC/D,CACI,EAAK,UAAU,EAAK,EAAK,SAAU,EAAQ,EACjD,GAEF,EAAK,EAAK,MAAO,EACnB,CACA,GAAI,EAAQ,EAAO,SACjB,MAAM,IAAI,MAAM,kCAAkC,EAAO,mBAC3D,IAAK,MAAM,KAAQ,EAAI,MAAO,CAC5B,MAAM,EAAQ,EAAa,EAAK,OAC9B,EAAW,IAAI,IAAI,EAAM,IAAK,GAAM,CAAC,EAAE,GAAI,KAC7C,IAAK,MAAM,KAAQ,EACjB,IAAK,MAAM,IAAY,CAAC,EAAK,KAAM,EAAK,IACtC,GAAI,GAAY,SAAU,EAAU,CAClC,MAAM,EAAS,EAAS,IAAI,EAAS,MACrC,IAAK,EACH,MAAM,IAAI,MAAM,YAAY,EAAS,+BAA+B,EAAK,OAC3E,GAAoB,cAAhB,EAAO,MAAwB,EAAO,KAAO,EAAK,GACpD,MAAM,IAAI,MACR,4DAA4D,EAAS,SAE3E,CACN,CACA,IAAK,MAAO,EAAS,KAAU,OAAO,QAAQ,EAAI,OAAQ,CACxD,MAAM,EAAO,GAAe,KAAK,EAAM,KACvC,IAAI,EACJ,IACE,EAAM,IAAI,IAAI,EAAM,IACtB,CAAA,MAEA,CACA,KAAK,GAAU,GAAQ,CAAC,QAAS,UAAU,SAAS,EAAI,WACtD,MAAM,IAAI,MAAM,wDAClB,GAAI,IAAQ,EAAI,UAAY,EAAI,UAC9B,MAAM,IAAI,MAAM,4CAClB,GACa,SAAX,KACE,GAAmB,EAAgB,IAAI,MACxC,GACD,IACC,EAAQ,qBAAqB,SAAS,EAAI,QAE3C,MAAM,IAAI,MACR,gBAAgB,EAAI,2EAE1B,CACF,CACA,SAAS,GAAU,GACjB,QAAkB,IAAd,EAAK,KAAoB,OAC7B,MAAM,EAAO,GAAc,EAAK,MAChC,IAAK,EAAM,MAAM,IAAI,MAAM,aAAa,EAAK,QAC7C,EAAK,KAAO,EACZ,EAAK,UAAU,QAAQ,GACzB,CACA,SAAS,GAAmB,EAAY,QACpB,IAAd,EAAK,OAAoB,EAAK,KAAO,GAAW,EAAK,KAAM,IAC3D,EAAK,cAAc,EAAK,MAC5B,EAAK,UAAU,QAAS,GAAU,GAAmB,EAAO,GAC9D,CACA,SAAS,GACP,EACA,EACA,EACA,EAAsB,CAAC,GAMvB,MAAM,EAAK,EAAM,GACf,EAAe,EAAiB,EAAQ,OACpC,EAAW,GACf,EAAQ,OAAO,KAAM,GAAS,EAAK,OAAS,EAAK,OAAO,UAAU,GACpE,IAAI,EAAgB,GAClB,EAAoB,GACtB,GAAc,QAAV,EAAG,GAAc,CACnB,IAAI,EAAO,EAAc,EAAG,KAAM,GACnB,SAAX,GAAmB,GAAmB,EAAM,EAAQ,cACxD,GAAU,GACV,MAAM,EAAW,EAAG,QAAU,EAAG,OAAO,OACtC,EAAS,EAAW,GAAY,EAAK,QAAY,EACnD,GAAI,GAA+B,UAArB,EAAO,KAAK,KACxB,MAAM,IAAI,MAAM,UAAU,sBAC5B,MAAM,EAAO,GAAQ,MAAQ,EAAI,MAAM,KAAM,IAAU,EAAG,MAAO,EAAK,KAAO,EAAG,MAChF,IAAK,EAAM,MAAM,IAAI,MAAM,QAAQ,EAAG,MAAQ,6BAC9C,GAAI,GAAU,EAAG,MAAQ,EAAG,OAAS,EAAO,KAAK,GAC/C,MAAM,IAAI,MAAM,gDAClB,GAAI,EAAG,MAAO,CACZ,MAAM,EACJ,EAAG,MAAM,MAAQ,EAAO,WAAW,UAAa,EAAQ,eAAiB,GAAM,IACjF,EAAO,EAAU,EAAM,IAAK,EAAG,MAAO,OAAO,EAAa,EAAK,OACjE,CACA,MAAM,EAAO,EAAU,EAAO,KAAK,WAAa,GAAM,EAAK,MAC3D,QAAiB,IAAb,EAAG,OAAuB,EAAG,MAAQ,EAAK,OAC5C,MAAM,IAAI,MAAM,4CAIlB,OAHA,EAAK,OAAO,EAAG,OAAS,EAAK,OAAQ,EAAG,GACxC,EAAU,CAAC,CAAE,GAAI,SAAU,GAAI,EAAK,KACpC,EAAU,EAAa,CAAC,IAAO,IAAK,GAAM,EAAE,IACrC,CACL,GAAI,CACF,GAAI,MACJ,KAAM,EAAM,GACZ,KAAM,EAAK,MACP,EAAS,CAAE,OAAQ,EAAO,KAAK,IAAO,CAAC,UAC1B,IAAb,EAAG,MAAsB,CAAE,MAAO,EAAG,OAAU,CAAC,GAEtD,UACA,UAEJ,CACA,GAAc,QAAV,EAAG,GAAc,CACnB,MAAM,EAAK,GAAY,EAAK,EAAG,IACzB,EAAY,OAAO,OAAO,EAAG,MAAO,YACtC,IAAI,IAAI,EAAS,GAAK,IAAK,GAAS,CAAC,EAAK,GAAI,UAC9C,EACJ,GAAI,OAAO,OAAO,EAAG,MAAO,OAAS,EAAG,MAAM,KAAO,EAAG,GACtD,MAAM,IAAI,MAAM,+BAClB,EAAU,CACR,CAAE,GAAI,MAAO,GAAI,EAAG,GAAI,MAAO,GAAa,EAAG,KAAM,EAAG,MAAO,CAAC,QAAS,OAAQ,WAEnF,MAAM,EAAW,EAAM,EAAG,QACpB,KAAE,EAAA,GAAM,EAAA,MAAI,EAAA,SAAO,KAAa,GAAS,EACzC,EAAuB,IAAM,GAC/B,OAAO,OAAO,EAAU,WAAU,EAAM,MAAQ,EAAW,IAC3D,OAAO,OAAO,EAAU,UAAS,EAAM,KAAO,EAAe,IAC7D,OAAO,OAAO,EAAU,QAAO,EAAM,GAAK,EAAe,IACzD,OAAO,OAAO,EAAU,cAC1B,EAAM,SAAW,EACZ,EAAuB,IAAK,GAAU,EAAc,EAAO,SAC5D,GACN,IAAK,MAAM,IAAS,CAAC,OAAQ,IAAK,IAAK,IAAK,KAC1C,GAAI,OAAO,OAAO,EAAO,SAA2B,IAAjB,EAAM,GACvC,MAAM,IAAI,MAAM,kBAAkB,wBACtC,GAA0B,iBAAf,EAAM,KAAmB,CAClC,MAAM,EAAO,GAAc,EAAM,MACjC,IAAK,EAAM,MAAM,IAAI,MAAM,aAAa,EAAG,QAC3C,EAAM,KAAO,CACf,CAeA,MAde,SAAX,IACwB,iBAAf,EAAM,OAAmB,EAAM,KAAO,GAAW,EAAM,KAAM,EAAQ,eAC5E,OAAO,OAAO,EAAO,iBAAiB,EAAM,MAC5C,EAAM,UACR,EAAM,SAAS,QAAS,GAAU,GAAmB,EAAO,EAAQ,gBAExE,EAAG,KAAK,EAAG,OAAS,GAAW,EAAG,KAAM,EAAO,CAAC,QAAS,OAAQ,SAC7D,IAIF,EAAU,IAAI,IAHa,IACzB,EAAa,EAAG,KAAK,EAAG,OAAO,UAAY,IAAI,IAAK,GAAS,EAAK,MAEtC,OAAQ,IAAQ,EAAU,IAAI,IAC5D,EAAQ,QAAQ,EAAuB,EAAU,GAAM,EAAW,KAE7D,CAAE,GAAI,IAAK,EAAI,SAAS,UAAS,UAC1C,CACA,GAAc,WAAV,EAAG,GAAiB,CACtB,MAAM,EAAK,GAAY,EAAK,EAAG,IAC7B,EAAS,IAAI,IAAI,EAAS,GAAK,IAAK,GAAM,CAAC,EAAE,GAAI,KACnD,EAAU,CACR,CACE,GAAI,MACJ,KAAM,EAAM,EAAG,MACf,KAAM,EAAG,KAAK,MACV,EAAG,OAAS,CAAE,OAAQ,EAAG,OAAO,IAAO,CAAC,EAC5C,MAAO,EAAG,QAGd,EAAG,KAAK,OAAO,EAAG,MAAO,GACzB,EAAQ,QAAQ,EAAuB,EAAU,GAAM,EAAQ,GACjE,CACA,GAAc,UAAV,EAAG,GAAgB,CACrB,MAAM,EAAK,GAAY,EAAK,EAAG,IAC7B,EACmB,iBAAV,EAAG,GACN,EAAG,GACO,UAAV,EAAG,GACD,EAAG,KAAK,OAAS,EACP,SAAV,EAAG,GACD,EACU,YAAV,EAAG,GACD,KAAK,IAAI,EAAG,KAAK,OAAS,EAAG,EAAG,MAAQ,GACxC,KAAK,IAAI,EAAG,EAAG,MAAQ,GACrC,GAAI,GAAM,EAAG,KAAK,OAAQ,MAAM,IAAI,MAAM,yCAC1C,EAAG,KAAK,OAAO,EAAG,MAAO,GACzB,EAAG,KAAK,OAAO,EAAI,EAAG,EAAG,MACzB,EAAU,CAAC,CAAE,GAAI,QAAS,GAAI,EAAG,GAAI,GAAI,EAAG,OAC9C,CACA,GAAc,aAAV,EAAG,GAAmB,CACxB,MAAM,EAAK,GAAY,EAAK,EAAG,IAC7B,EAAS,EAAG,OAAS,GAAY,EAAK,EAAG,aAAU,EACrD,GAAI,GAA+B,UAArB,EAAO,KAAK,KAAkB,MAAM,IAAI,MAAM,+BAC5D,GAAI,GAAU,EAAa,CAAC,EAAG,OAAO,KAAM,GAAM,EAAE,KAAO,EAAO,KAAK,IACrE,MAAM,IAAI,MAAM,2DAClB,GAAI,GAAU,EAAO,KAAK,KAAO,EAAG,KAAK,GACvC,MAAM,IAAI,MAAM,8CAClB,EAAU,CAAC,CAAE,GAAI,WAAY,GAAI,EAAG,GAAI,OAAQ,EAAG,QAAQ,IAAM,KAAM,MAAO,EAAG,QACjF,EAAG,KAAK,OAAO,EAAG,MAAO,GACzB,MAAM,EAAO,EAAU,EAAO,KAAK,WAAa,GAAM,EAAG,KAAK,MAC9D,QAAiB,IAAb,EAAG,OAAuB,EAAG,MAAQ,EAAK,OAC5C,MAAM,IAAI,MAAM,8CAClB,EAAK,OAAO,EAAG,OAAS,EAAK,OAAQ,EAAG,EAAG,KAC7C,CACA,GAAc,aAAV,EAAG,GAAmB,CACxB,MAAM,EAAa,IACd,EAAG,KACN,GAAI,EAAG,KAAK,IAAM,IAClB,OAAQ,EAAG,KAAK,OAAS,IAAI,IAAK,GAAS,EAAc,EAAM,KAIjE,GAFe,SAAX,GACF,EAAK,MAAM,QAAS,GAAS,GAAmB,EAAM,EAAQ,oBAC/C,IAAb,EAAG,OAAuB,EAAG,MAAQ,EAAI,MAAM,OACjD,MAAM,IAAI,MAAM,+CAIlB,OAHA,EAAI,MAAM,OAAO,EAAG,OAAS,EAAI,MAAM,OAAQ,EAAG,GAClD,EAAU,CAAC,CAAE,GAAI,cAAe,GAAI,EAAK,KACzC,EAAU,EAAa,EAAK,OAAO,IAAK,GAAM,EAAE,IACzC,CACL,GAAI,CACF,GAAI,WACJ,KAAM,EAAM,WACK,IAAb,EAAG,MAAsB,CAAE,MAAO,EAAG,OAAU,CAAC,GAEtD,UACA,UAEJ,CACA,GAAc,aAAV,EAAG,GAAmB,CACxB,GAAgB,EAAG,OACnB,MAAM,EAAO,EAAI,MAAM,KAAM,GAAS,EAAK,KAAO,EAAG,IACrD,IAAK,EAAM,MAAM,IAAI,MAAM,QAAQ,EAAG,sBACtC,EAAU,CAAC,CAAE,GAAI,WAAY,GAAI,EAAG,GAAI,MAAO,GAAa,EAAM,EAAG,SACrE,OAAO,OAAO,EAAM,GAAW,EAAM,EAAG,QACxC,IAAK,MAAM,KAAO,OAAO,KAAK,EAAG,YACoB,IAA9C,EAAG,MAAkC,WAChC,EAA4C,EAC1D,CACA,GAAc,gBAAV,EAAG,GAAsB,CAC3B,MAAM,EAAQ,EAAI,MAAM,UAAW,GAAS,EAAK,KAAO,EAAG,IAC3D,GAAI,EAAQ,EAAG,MAAM,IAAI,MAAM,QAAQ,EAAG,sBAC1C,MAAO,GAAQ,EAAI,MAAM,OAAO,EAAO,GACvC,EAAU,CAAC,CAAE,GAAI,WAAY,KAAM,EAAM,GAAO,SAClD,CAWA,GAVc,aAAV,EAAG,KACL,EAAU,CAAC,CAAE,GAAI,WAAY,MAAO,GAAa,EAAI,KAAM,EAAG,SAC9D,EAAI,KAAO,GAAW,EAAI,KAAM,EAAG,QAEvB,cAAV,EAAG,KACL,EAAU,EAAI,MAAM,EAAG,IACnB,CAAC,CAAE,GAAI,YAAa,GAAI,EAAG,GAAI,MAAO,EAAM,EAAI,MAAM,EAAG,OACzD,CAAC,CAAE,GAAI,eAAgB,GAAI,EAAG,KAClC,EAAI,MAAM,EAAG,IAAM,EAAM,EAAG,QAEhB,iBAAV,EAAG,GAAuB,CAC5B,IAAK,EAAI,MAAM,EAAG,IAAK,MAAM,IAAI,MAAM,SAAS,EAAG,sBACnD,EAAU,CAAC,CAAE,GAAI,YAAa,GAAI,EAAG,GAAI,MAAO,EAAM,EAAI,MAAM,EAAG,cAC5D,EAAI,MAAM,EAAG,GACtB,CACA,MAAO,CAAE,KAAI,UAAS,UACxB,CACA,SAAS,GACP,EACA,EACA,EACA,EAAmB,IAEnB,MAAM,EAAiC,CAAC,EACxC,IAAK,MAAM,mBAAO,IAAI,IAAI,IAAI,OAAO,KAAK,MAAY,OAAO,KAAK,KAChE,IAAI,GAAM,EAAO,GAAM,EAAM,IAC7B,IACE,EAAO,SAAS,KAChB,EAAQ,IACgB,iBAAjB,EAAQ,SACE,IAAhB,EAAO,IAA6C,iBAAhB,EAAO,SAC5B,IAAf,EAAM,IAA4C,iBAAf,EAAM,GAQjC,GAAM,EAAQ,GAAM,EAAM,MAAO,EAAM,GAAO,EAAM,EAAO,SAPpE,CACA,MAAM,EAAM,GACT,EAAO,IAAQ,CAAC,EAChB,EAAM,IAAQ,CAAC,EAChB,EAAQ,IAEN,OAAO,KAAK,GAAK,SAAQ,EAAM,GAAO,EAC5C,CAEF,OAAO,CACT,CA2CA,SAAgB,GAAU,EAAoB,EAAsB,CAAC,GAC/D,EAAQ,cA9dd,SAAkC,GAChC,IAAI,EACJ,IACE,EAAM,EAJc,6DAKtB,CAAA,MAAS,GACP,MAAM,IAAI,MACR,0CAA0C,aAAiB,MAAQ,EAAM,QAAU,MAEvF,CACA,GAAmB,iBAAR,EAAkB,MAAM,IAAI,MAAM,sCAC7C,MAAM,EAAQ,EAAI,cAClB,GAAI,EAAM,SAAS,YAAc,YAAY,KAAK,GAChD,MAAM,IAAI,MACR,oFAEN,CA+c4B,CAAyB,EAAQ,cAC3D,MAAM,EAAe,GACZ,EAAQ,EAAK,EAAiB,EAAQ,QAE/C,IAAI,EAAQ,EAAU,EAAY,GAAW,IAC7C,GAAY,EAAO,GACnB,IAAI,EAAQ,IAAI,IAAI,EAAS,GAAO,IAAK,GAAS,CAAC,EAAK,GAAI,KAC5D,MAAM,iBAAgB,IAAI,IACxB,iBAAiB,IAAI,IACrB,iBAAmB,IAAI,IACnB,EAAiB,IACrB,MAAM,EAAS,EAAM,GACf,EAAU,IACV,GAAwB,iBAAT,IACjB,OAAO,OAAO,GAAM,QAAQ,GAC5B,OAAO,OAAO,KAIlB,OADA,EAAO,GACA,GAEH,EAAY,IACf,EAAM,IAAI,IAAK,UAAY,EAAM,MAAM,KAAM,GAAS,EAAK,KAAO,IAAK,OAAS,IAAI,IAClF,GAAS,EAAK,IAEb,EAAA,KACJ,EAAQ,IAAI,IAAI,EAAS,GAAO,IAAK,GAAS,CAAC,EAAK,GAAI,KHtjB6T,SAAW,GAAG,GAAG,EAAE,EAAE,OAAO,IAAI,IAAI,EAAE,IAAI,IAAI,OAAO,GAAG,CAAA,QAAS,GAAG,CAAC,CGujB1b,CAAA,KACE,IAAK,MAAO,EAAI,KAAa,EAAe,CAC1C,MAAM,EAAO,EAAM,IAAI,GAClB,GAAM,EAAS,OAAQ,KAAO,EAAS,MAAQ,EAAW,GACjE,CACA,IAAK,MAAO,EAAI,KAAW,EACzB,IAAK,MAAO,EAAK,KAAa,EAAQ,CACpC,MAAM,EAAO,EAAM,IAAI,KAAM,GACxB,GAAM,EAAS,OAAQ,KAAO,EAAS,MAAQ,EAAW,GACjE,CACF,IAAK,MAAO,EAAI,KAAa,EAAkB,CAC7C,MAAM,EAAO,EAAS,GACjB,GAAM,EAAS,OAAQ,KAAO,EAAS,MAAQ,OAAO,OAAO,GACpE,KAGE,iBAAY,IAAI,IACpB,EAAmB,GACnB,EAAkB,GACpB,IAAI,EAAW,EACf,MAAM,EAA4B,GAC5B,iBAAU,IAAI,IAClB,iBAAU,IAAI,IACV,EAAA,IAA2C,WAAzB,EAAQ,aAC1B,EAAe,GAAmB,EAAO,WAAW,UACpD,EAAA,CAAY,EAA6B,KAC7C,IAAI,EAAQ,EAAM,OAAS,EAC3B,KAAO,GAAS,IAAM,EAAK,EAAM,GAAO,SAAS,IACjD,OAAO,GAEH,EAAU,IACd,MAAM,iBAAM,IAAI,IAChB,IAAK,MAAM,KAAQ,EAAI,MACrB,IAAK,MAAM,KAAQ,EAAa,EAAK,OAAQ,EAAI,IAAI,EAAK,GAAI,EAAK,IACrE,OAAO,GAqBH,EAAA,KACJ,EAAW,EACX,EAAW,OAAS,EACpB,EAAQ,QACR,EAAQ,SAEJ,EAAA,CACJ,EACA,EACA,KAEA,GAAY,EA9BR,EAAmB,EAAkB,EAAiB,EAAa,KACvE,MAAM,EAAc,IAAI,IAAI,EAAS,GAAQ,IAAK,GAAS,CAAC,EAAK,GAAI,KACnE,EAAa,IAAI,IAAI,EAAS,GAAO,IAAK,GAAS,CAAC,EAAK,GAAI,KAC7D,EAAc,EAAO,GACrB,EAAa,EAAO,GACtB,IAAK,MAAO,EAAI,KAAS,EAAY,CACnC,MAAM,EAAO,EAAY,IAAI,GACxB,GAAS,GAAM,EAAM,KACxB,EAAQ,IAAI,EAAI,CAAE,SAAU,EAAK,SAAQ,KAAM,EAAK,KAAM,KAAM,EAAW,IAAI,KAC/E,EAAQ,OAAO,GAEnB,CACA,IAAK,MAAO,EAAI,KAAS,EAClB,EAAW,IAAI,KAClB,EAAQ,OAAO,GACf,EAAQ,IAAI,EAAI,CAAE,SAAU,EAAK,SAAQ,KAAM,EAAK,KAAM,KAAM,EAAY,IAAI,OAgBpF,CAAgB,EAAQ,EAAO,EAAU,EAAM,QAC/C,EAAW,KAAK,IAAK,EAAO,WAAU,IAAK,EAAM,EAAM,OACnD,EAAW,OAAS,EAAO,eAAe,EAAW,QAClD,GAEH,EACJ,IAEA,IAAK,MAAM,KAAY,EACrB,IACE,EACE,EAAM,CACJ,IAAK,EAAM,IACX,QAAS,EAAM,QACf,OAAQ,EAAM,OACd,MAAO,EAAM,MACb,SAAU,EAAM,WAGtB,CAAA,MAEA,GAmVJ,MAAO,CA/UL,UAAA,CAAW,GACT,IAAI,EAAW,EAAc,IAAI,GAKjC,OAJK,IACH,EAAW,EAAO,EAAW,EAAM,IAAI,KACvC,EAAc,IAAI,EAAI,IAEjB,CACT,EACA,WAAA,CAAY,EAAI,GACd,IAAI,EAAS,EAAe,IAAI,GAC3B,IACH,iBAAS,IAAI,IACb,EAAe,IAAI,EAAI,IAEzB,IAAI,EAAW,EAAO,IAAI,GAK1B,OAJK,IACH,EAAW,EAAgB,EAAW,EAAM,IAAI,KAAM,KACtD,EAAO,IAAI,EAAK,IAEX,CACT,EACA,cAAA,CAAe,GACb,IAAI,EAAW,EAAiB,IAAI,GAKpC,OAJK,IACH,EAAW,EAA0B,OAAO,OAAO,EAAS,KAC5D,EAAiB,IAAI,EAAI,IAEpB,CACT,EACA,KAAA,CAAM,EAAK,EAAe,CAAC,GACzB,MAAM,EAAsB,CAAE,IAAI,EAAO,QAAS,GAAI,OAAQ,GAAI,SAAU,IAC1E,EAAS,EAAa,QAAU,MAChC,IAAY,EAAa,QAC3B,GAAI,EAAQ,SAEV,OADA,EAAO,OAAO,KAAK,CAAE,MAAO,EAAG,KAAM,WAAY,QAAS,gCACnD,EAET,MAAM,EAAwB,SAAX,EAAoB,EAAO,SAAW,EAAO,SAChE,IAAK,MAAM,QAAQ,IAAQ,EAAI,OAAS,EAMtC,OALA,EAAO,OAAO,KAAK,CACjB,MAAO,EACP,KAAM,cACN,QAAS,uCAAuC,2BAAoC,OAE/E,EAET,IAAI,EACJ,IACE,GAAe,GACf,EAAQ,EAAM,EAChB,CAAA,MAAS,GAMP,OALA,EAAO,OAAO,KAAK,CACjB,MAAO,EACP,KAAM,eACN,QAAS,OAAO,aAAiB,MAAQ,EAAM,QAAU,KAEpD,CACT,CACA,MAAM,EAAW,EAAO,WAAW,UAC/B,EAAoB,EAAO,GAC3B,CAAE,MAAK,SAAU,IACrB,EAAO,SAAS,QAAQ,EAAS,UACjC,MAAM,EAAiB,GACrB,EAAgB,GAChB,EAAyB,GACrB,iBAAc,IAAI,IAClB,EAAA,IACJ,IAAI,IAAI,EAAS,OAAQ,GAAiB,cAAV,EAAG,IAAoB,IAAK,GAAO,EAAG,KAClE,EAAQ,EAAS,IACvB,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAM,OAAQ,IAAS,CACjD,MAAM,EAAW,EAAU,EAAM,QAAS,EAC1C,IACE,MAAM,EAAQ,EAAY,EAAU,EAAM,IAC1C,GAAI,EAAO,MAAM,IAAI,MAAM,GAC3B,MAAM,EAAS,GAAQ,EAAO,EAAM,GAAQ,EAAQ,GACpD,GAAe,SAAX,GAAqB,EAAO,QAAQ,OAAS,EAAO,QAAQ,OAAS,EAAO,SAC9E,MAAM,IAAI,MACR,qCAAqC,EAAO,8CAE5C,GACF,GACE,EACA,EACA,iBACA,IAAI,IAAI,IAAI,OAAiC,cAAjB,EAAO,GAAG,GAAqB,CAAC,EAAO,GAAG,IAAM,MAEhF,EAAS,KAAK,EAAO,IACrB,EAAQ,WAAW,EAAO,SAC1B,EAAO,QAAQ,QAAQ,EAAO,SAC9B,EAAO,QAAQ,QAAS,GAAO,EAAY,IAAI,EAAI,GACrD,CAAA,MAAS,GACH,IAAU,EAAQ,GACtB,EAAS,KAAK,CACZ,QACA,KAAM,aACN,QAAS,GAAG,EAAM,IAAQ,IAAM,gBAAgB,EAAQ,MAAM,aAAiB,MAAQ,EAAM,QAAU,OAAO,MAElH,CACF,CACA,IAAK,IAAY,EAAS,OACxB,IACE,GAAY,EAAO,EAAS,EAAQ,IACtC,CAAA,MAAS,GACP,EAAS,KAAK,CACZ,MAAO,KAAK,IAAI,EAAG,EAAI,OAAS,GAChC,KAAM,mBACN,QAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,IAE7D,CAEF,IAAK,GAAW,EAAS,OAIvB,OAHA,EAAO,OAAS,EAChB,EAAO,QAAU,GACjB,EAAO,SAAW,GACX,EAET,GAAI,IAAY,EAAS,OAGvB,OAFA,EAAO,QAAU,EACjB,EAAO,QAAU,GACV,EAEL,GAAW,EAAS,SAAQ,EAAO,QAAU,GACjD,MAAM,EAAM,EAAS,GACnB,EAAS,IAAI,IAAI,EAAI,IAAK,GAAM,CAAC,EAAE,GAAI,KACzC,IAAK,MAAM,KAAM,EAAO,QAAS,CAC/B,MAAM,EAAO,EAAO,IAAI,GACnB,IAEW,cAAd,EAAK,MACL,EAAI,KACD,GACC,EAAM,KAAO,IACZ,EAAM,UAAU,QACF,cAAf,EAAM,MACN,EAAW,EAAW,EAAM,GAAS,EAAW,EAAO,MAG3D,EAAO,SAAS,KAAK,CACnB,MAAO,EAAY,IAAI,IAAO,EAC9B,KAAM,oBACN,QAAS,QAAQ,6BAEvB,CAEA,GADA,EAAO,IAAK,EACR,EAAa,SAAW,EAAS,OAAQ,OAAO,EACpD,MAAM,EAAe,CACnB,IAAK,EACL,UACA,OAAQ,EACR,MAAO,EACP,SACA,MAAO,EAAa,OAEtB,EAAQ,EACR,IACA,MAAM,EAAW,EAAQ,IAAG,GAuB5B,OArBE,EAAa,OACb,GACA,EAAS,SAAW,GACpB,EAAS,QAAU,EAAM,OAEzB,EAAS,IAAI,QAAQ,EAAM,KAC3B,EAAS,QAAQ,WAAW,EAAM,SAClC,EAAS,MAAQ,IAEjB,EAAQ,KAAK,GACT,EAAQ,OAAS,EAAO,YAAY,EAAQ,SAElD,EAAO,OAAS,EAChB,EAAK,IACA,EACH,SAAU,EACR,CAAE,SAAQ,MAAO,EAAa,MAAO,IAAK,GAC1C,EAAM,OACN,KAGG,CACT,EACA,IAAI,GACK,EAAM,EAAM,IAAI,IAEzB,MAAM,GACG,EAAS,EAAO,GAEzB,SAAS,GACA,EAAY,EAAO,EAAiB,CAAE,UAAS,YAExD,YAAA,CAAa,EAAO,GAClB,MAAM,EAAS,EACf,IAAK,OAAO,SAAS,IAAU,GAAS,EAAQ,MAAO,CAAE,SAAQ,QAAO,QAAS,IACjF,MAAM,EAAS,EAAW,GAC1B,GAAI,GAAU,EAAQ,EAAI,EAAO,SAC/B,MAAO,CAAE,SAAQ,QAAO,QAAS,GAAI,WAAW,GAClD,IAAI,EAAU,EAAW,OAAQ,GAAU,EAAM,SAAW,GAC5D,MAAM,EAAS,GAAe,OAG9B,MAFe,UAAX,EAAoB,EAAU,EAAQ,OAAQ,GAAU,EAAY,EAAM,cAC1D,IAAX,IAAsB,EAAU,EAAQ,OAAQ,GAAU,EAAM,SAAW,IAC7E,CAAE,SAAQ,QAAO,QAAS,EAAM,GACzC,EACA,WAAW,GACF,EAAW,GAEpB,MAAA,CAAO,GACL,MAAM,EAAO,EAAM,GACnB,IAA6B,IAAzB,GAAa,QAAmB,OAAO,EAC3C,IAAK,MAAM,KAAQ,EAAK,MACtB,EAAK,MAAQ,EAAK,MAAM,IAAK,GAAS,EAAY,EAAM,EAAiB,EAAQ,SACnF,OAAO,CACT,EACA,IAAA,CAAK,GACH,GAAI,EAAQ,SAAU,OAAO,EAC7B,MAAM,EAAQ,GAAa,OACvB,EAAS,EAAU,GAAW,IAAW,EAAY,QACrD,IACE,EAAS,EAAU,IAAY,EAAY,IAC3C,EAAQ,OAAS,EACvB,GAAI,EAAQ,EAAG,OAAO,EACtB,MAAM,EAAQ,EAAQ,GAEpB,EADY,IAAU,EAAQ,OAAS,EA9X/C,SAA0B,EAAc,GACtC,OAAO,EAAM,QAAQ,QAAa,IAChC,GAAc,QAAV,EAAG,GAAc,CACnB,MAAM,EAAS,GAAO,EAAM,OAAQ,EAAG,KAAK,KAC1C,EAAQ,GAAO,EAAM,MAAO,EAAG,KAAK,KACpC,EAAM,GAAO,EAAS,EAAG,KAAK,KAChC,IAAK,IAAW,IAAU,EAAK,MAAO,GACtC,MAAM,EAAQ,GAAc,EAAQ,EAAO,EAAK,CAAC,QAAS,OAAQ,SAClE,OAAO,OAAO,KAAK,GAAO,OAAS,CAAC,IAAK,EAAI,UAAW,EAC1D,CACA,GAAc,aAAV,EAAG,GAAmB,CACxB,MAAM,EAAQ,GAAc,EAAM,OAAO,KAAM,EAAM,MAAM,KAAM,EAAQ,MACzE,OAAO,OAAO,KAAK,GAAO,OAAS,CAAC,IAAK,EAAI,UAAW,EAC1D,CACA,GAAc,WAAV,EAAG,GAAiB,OAAO,GAAO,EAAS,EAAG,IAAM,CAAC,GAAM,GAC/D,GAAc,QAAV,EAAG,GAAc,OAAO,GAAO,EAAS,OAAO,EAAG,KAAK,KAAO,GAAK,CAAC,GACxE,GAAc,UAAV,EAAG,IAA4B,aAAV,EAAG,GAAmB,CAC7C,MAAM,EAAM,GAAO,EAAS,EAAG,IAC7B,EAAQ,GAAO,EAAM,MAAO,EAAG,IACjC,OAAK,GAAQ,GAAS,EAAI,QAAQ,KAAO,EAAM,QAAQ,IAAM,EAAI,KAAK,KAAO,EAAM,KAAK,GAEjF,CAAC,GADC,EAEX,CACA,GAAc,cAAV,EAAG,IAAgC,iBAAV,EAAG,GAC9B,OAAO,GAAM,EAAQ,MAAM,EAAG,IAAK,EAAM,MAAM,MAAM,EAAG,KAAO,CAAC,GAAM,GACxE,GAAc,aAAV,EAAG,GAAmB,CACxB,GAAgB,EAAG,OACnB,MAAM,EAAS,EAAM,OAAO,MAAM,KAAM,GAAS,EAAK,KAAO,EAAG,IAC9D,EAAQ,EAAM,MAAM,MAAM,KAAM,GAAS,EAAK,KAAO,EAAG,IACxD,EAAM,EAAQ,MAAM,KAAM,GAAS,EAAK,KAAO,EAAG,IACpD,IAAK,IAAW,IAAU,EAAK,MAAO,GACtC,MAAM,EAAQ,GACZ,EACA,EACA,GAGF,cADO,EAAM,MACN,OAAO,KAAK,GAAO,OAAS,CAAC,IAAK,EAAI,UAAW,EAC1D,CACA,MAAO,CAAC,IAEZ,CAsV0B,CAAiB,EAAO,GAAS,EAAM,QACzD,EAAQ,EAAM,GACd,EAAe,GACf,EAAa,GACf,IACE,IAAK,MAAM,KAAM,EAAK,CACpB,MAAM,EAAS,GAAQ,EAAO,EAAI,OAAQ,GAC1C,EAAO,KAAK,EAAO,IACnB,EAAK,WAAW,EAAO,QACzB,CACA,GAAY,EAAO,EACrB,CAAA,MACE,OAAO,CACT,CACA,MAAM,EAAiB,CACrB,IAAK,EACL,QAAS,EACT,OAAQ,EACR,MAAO,EACP,OAAQ,EAAM,OACd,MAAO,EAAM,OAET,EAAS,EACf,EAAQ,EACR,IACA,EAAQ,OAAO,EAAO,GACtB,EAAO,KAAK,GACZ,MAAM,EAAQ,QAAQ,EAAM,OAAS,WAQrC,OAPA,EAAK,CACH,IAAK,EACL,QAAS,EACT,OAAQ,EAAM,OACd,QACA,SAAU,EAAc,CAAE,OAAQ,EAAM,OAAQ,QAAO,IAAK,GAAU,EAAQ,MAEzE,CACT,EACA,IAAA,GACE,GAAI,EAAQ,SAAU,OAAO,EAC7B,MAAM,EAAQ,IACV,EAAS,EAAS,IAAY,EAAY,IAC1C,EAAO,OAAS,EACpB,GAAI,EAAQ,EAAG,OAAO,EACtB,MAAM,EAAU,EAAO,GACjB,EAAQ,EAAM,GAClB,EAAY,GACZ,EAAgB,GAClB,IACE,IAAK,MAAM,KAAM,EAAQ,QAAS,CAChC,MAAM,EAAS,GAAQ,EAAO,EAAI,OAAQ,GAC1C,EAAI,KAAK,EAAO,IAChB,EAAQ,WAAW,EAAO,QAC5B,CACA,GAAY,EAAO,EACrB,CAAA,MACE,OAAO,CACT,CACA,MAAM,EAAe,CACnB,MACA,UACA,OAAQ,EACR,MAAO,EACP,OAAQ,EAAQ,OAChB,MAAO,EAAQ,OAEX,EAAS,EACf,EAAQ,EACR,IACA,EAAO,OAAO,EAAO,GACrB,EAAQ,KAAK,GACb,MAAM,EAAQ,QAAQ,EAAM,OAAS,WAQrC,OAPA,EAAK,CACH,MACA,UACA,OAAQ,EAAM,OACd,QACA,SAAU,EAAc,CAAE,OAAQ,EAAM,OAAQ,QAAO,OAAO,EAAQ,MAEjE,CACT,EACA,IAAA,CAAK,GACH,GAAI,EAAQ,SAAU,MAAM,IAAI,MAAM,+BACtC,MAAM,EAAO,EAAY,GACzB,GAAY,EAAM,GAClB,EAAQ,EACR,IACA,EAAQ,OAAS,EACjB,EAAO,OAAS,EAChB,IACA,EAAK,CAAE,IAAK,GAAI,QAAS,GAAI,OAAQ,MAAO,MAAO,gBAAiB,SAAU,GAChF,EACA,KAAA,GACE,GAAI,EAAQ,SAAU,MAAM,IAAI,MAAM,+BACtC,EAAQ,IACR,IACA,EAAQ,OAAS,EACjB,EAAO,OAAS,EAChB,IACA,EAAK,CAAE,IAAK,GAAI,QAAS,GAAI,OAAQ,MAAO,MAAO,iBAAkB,SAAU,GACjF,EACA,GAAA,CAAG,EAAO,KACR,EAAU,IAAI,GACd,IAAa,EAAU,OAAO,IAEhC,YAAI,GACF,OAAO,CACT,EACA,WAAI,GACF,OAAO,IAAc,EAAQ,KAAM,IAAW,EAAY,EAAM,SAAW,EAAQ,OAAS,CAC9F,EACA,WAAI,GACF,OAAO,IAAc,EAAO,KAAM,IAAW,EAAY,EAAM,SAAW,EAAO,OAAS,CAC5F,EAGJ,CCl+BA,SAAgB,GAAc,GAK5B,OAJa,GACT,QAAQ,kBACR,MAAM,SACP,KAAM,GAAU,IAAU,EAAM,WAAW,QACjC,QAAU,GAAM,QAAQ,eAAiB,EACxD,CCKA,SAAwB,GAAY,EAAK,EAAG,EAAO,EAAG,EAAQ,EAAI,OAAS,EAAG,EAAU,IAEpF,KAAO,EAAQ,GAAM,CACjB,GAAI,EAAQ,EAAO,IAAK,CACpB,MAAM,EAAI,EAAQ,EAAO,EACnB,EAAI,EAAI,EAAO,EACf,EAAI,KAAK,IAAI,GACb,EAAI,GAAM,KAAK,IAAI,EAAI,EAAI,GAC3B,EAAK,GAAM,KAAK,KAAK,EAAI,GAAK,EAAI,GAAK,IAAM,EAAI,EAAI,EAAI,GAAI,EAAK,GAGxE,GAAY,EAAK,EAFD,KAAK,IAAI,EAAM,KAAK,MAAM,EAAI,EAAI,EAAI,EAAI,IACzC,KAAK,IAAI,EAAO,KAAK,MAAM,GAAK,EAAI,GAAK,EAAI,EAAI,IAC3B,EAC3C,CAEA,MAAM,EAAI,EAAI,GACd,IAAI,EAAI,EAEJ,EAAI,EAKR,IAHA,GAAK,EAAK,EAAM,GACZ,EAAQ,EAAI,GAAQ,GAAK,GAAG,GAAK,EAAK,EAAM,GAEzC,EAAI,GAAG,CAIV,IAHA,GAAK,EAAK,EAAG,GACb,IACA,IACO,EAAQ,EAAI,GAAI,GAAK,GAAG,IAC/B,KAAO,EAAQ,EAAI,GAAI,GAAK,GAAG,GACnC,CAE8B,IAA1B,EAAQ,EAAI,GAAO,GAAU,GAAK,EAAK,EAAM,IAE7C,IACA,GAAK,EAAK,EAAG,IAGb,GAAK,IAAG,EAAO,EAAI,GACnB,GAAK,IAAG,EAAQ,EAAI,EAC5B,CACJ,CAQA,SAAS,GAAK,EAAK,EAAG,GAClB,MAAM,EAAM,EAAI,GAChB,EAAI,GAAK,EAAI,GACb,EAAI,GAAK,CACb,CAQA,SAAS,GAAe,EAAG,GACvB,OAAO,EAAI,GAAI,EAAK,EAAI,EAAI,EAAI,CACpC,CCvEA,IAAqB,GAArB,MACI,WAAA,CAAY,EAAa,GAErB,KAAK,YAAc,KAAK,IAAI,EAAG,GAC/B,KAAK,YAAc,KAAK,IAAI,EAAG,KAAK,KAAwB,GAAnB,KAAK,cAC9C,KAAK,OACT,CAEA,GAAA,GACI,OAAO,KAAK,KAAK,KAAK,KAAM,GAChC,CAEA,MAAA,CAAO,GACH,IAAI,EAAO,KAAK,KAChB,MAAM,EAAS,GAEf,IAAK,GAAW,EAAM,GAAO,OAAO,EAEpC,MAAM,EAAS,KAAK,OACd,EAAgB,GAEtB,KAAO,GAAM,CACT,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,SAAS,OAAQ,IAAK,CAC3C,MAAM,EAAQ,EAAK,SAAS,GACtB,EAAY,EAAK,KAAO,EAAO,GAAS,EAE1C,GAAW,EAAM,KACb,EAAK,KAAM,EAAO,KAAK,GAClB,GAAS,EAAM,GAAY,KAAK,KAAK,EAAO,GAChD,EAAc,KAAK,GAEhC,CACA,EAAO,EAAc,KACzB,CAEA,OAAO,CACX,CAEA,QAAA,CAAS,GACL,IAAI,EAAO,KAAK,KAEhB,IAAK,GAAW,EAAM,GAAO,OAAO,EAEpC,MAAM,EAAgB,GACtB,KAAO,GAAM,CACT,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,SAAS,OAAQ,IAAK,CAC3C,MAAM,EAAQ,EAAK,SAAS,GACtB,EAAY,EAAK,KAAO,KAAK,OAAO,GAAS,EAEnD,GAAI,GAAW,EAAM,GAAY,CAC7B,GAAI,EAAK,MAAQ,GAAS,EAAM,GAAY,OAAO,EACnD,EAAc,KAAK,EACvB,CACJ,CACA,EAAO,EAAc,KACzB,CAEA,OAAO,CACX,CAEA,IAAA,CAAK,GACD,IAAM,IAAQ,EAAK,OAAS,OAAO,KAEnC,GAAI,EAAK,OAAS,KAAK,YAAa,CAChC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAC7B,KAAK,OAAO,EAAK,IAErB,OAAO,IACX,CAGA,IAAI,EAAO,KAAK,OAAO,EAAK,QAAS,EAAG,EAAK,OAAS,EAAG,GAEzD,GAAK,KAAK,KAAK,SAAS,OAIjB,GAAI,KAAK,KAAK,SAAW,EAAK,OAEjC,KAAK,WAAW,KAAK,KAAM,OAExB,CACH,GAAI,KAAK,KAAK,OAAS,EAAK,OAAQ,CAEhC,MAAM,EAAU,KAAK,KACrB,KAAK,KAAO,EACZ,EAAO,CACX,CAGA,KAAK,QAAQ,EAAM,KAAK,KAAK,OAAS,EAAK,OAAS,GAAG,EAC3D,MAhBI,KAAK,KAAO,EAkBhB,OAAO,IACX,CAEA,MAAA,CAAO,GAEH,OADI,GAAM,KAAK,QAAQ,EAAM,KAAK,KAAK,OAAS,GACzC,IACX,CAEA,KAAA,GAEI,OADA,KAAK,KAAO,GAAW,IAChB,IACX,CAEA,MAAA,CAAO,EAAM,GACT,IAAK,EAAM,OAAO,KAElB,IAAI,EAAO,KAAK,KAChB,MAAM,EAAO,KAAK,OAAO,GACnB,EAAO,GACP,EAAU,GAChB,IAAI,EAAG,EAAQ,EAGf,KAAO,GAAQ,EAAK,QAAQ,CASxB,GAPK,IACD,EAAO,EAAK,MACZ,EAAS,EAAK,EAAK,OAAS,GAC5B,EAAI,EAAQ,MACZ,GAAU,GAGV,EAAK,KAAM,CACX,MAAM,EAAQ,GAAS,EAAM,EAAK,SAAU,GAE5C,IAAc,IAAV,EAKA,OAHA,EAAK,SAAS,OAAO,EAAO,GAC5B,EAAK,KAAK,GACV,KAAK,UAAU,GACR,IAEf,CAEK,GAAY,EAAK,OAAQ,GAAS,EAAM,GAOlC,GACP,IACA,EAAO,EAAO,SAAS,GACvB,GAAU,GAEP,EAAO,MAXV,EAAK,KAAK,GACV,EAAQ,KAAK,GACb,EAAI,EACJ,EAAS,EACT,EAAO,EAAK,SAAS,GAQ7B,CAEA,OAAO,IACX,CAEA,MAAA,CAAO,GAAQ,OAAO,CAAM,CAE5B,WAAA,CAAY,EAAG,GAAK,OAAO,EAAE,KAAO,EAAE,IAAM,CAC5C,WAAA,CAAY,EAAG,GAAK,OAAO,EAAE,KAAO,EAAE,IAAM,CAE5C,MAAA,GAAW,OAAO,KAAK,IAAM,CAE7B,QAAA,CAAS,GAEL,OADA,KAAK,KAAO,EACL,IACX,CAEA,IAAA,CAAK,EAAM,GACP,MAAM,EAAgB,GACtB,KAAO,GACC,EAAK,KAAM,EAAO,QAAQ,EAAK,UAC9B,EAAc,QAAQ,EAAK,UAEhC,EAAO,EAAc,MAEzB,OAAO,CACX,CAEA,MAAA,CAAO,EAAO,EAAM,EAAO,GAEvB,MAAM,EAAI,EAAQ,EAAO,EACzB,IACI,EADA,EAAI,KAAK,YAGb,GAAI,GAAK,EAIL,OAFA,EAAO,GAAW,EAAM,MAAM,EAAM,EAAQ,IAC5C,GAAS,EAAM,KAAK,QACb,EAGN,IAED,EAAS,KAAK,KAAK,KAAK,IAAI,GAAK,KAAK,IAAI,IAG1C,EAAI,KAAK,KAAK,EAAI,KAAK,IAAI,EAAG,EAAS,KAG3C,EAAO,GAAW,IAClB,EAAK,MAAO,EACZ,EAAK,OAAS,EAId,MAAM,EAAK,KAAK,KAAK,EAAI,GACnB,EAAK,EAAK,KAAK,KAAK,KAAK,KAAK,IAEpC,GAAY,EAAO,EAAM,EAAO,EAAI,KAAK,aAEzC,IAAK,IAAI,EAAI,EAAM,GAAK,EAAO,GAAK,EAAI,CAEpC,MAAM,EAAS,KAAK,IAAI,EAAI,EAAK,EAAG,GAEpC,GAAY,EAAO,EAAG,EAAQ,EAAI,KAAK,aAEvC,IAAK,IAAI,EAAI,EAAG,GAAK,EAAQ,GAAK,EAAI,CAElC,MAAM,EAAS,KAAK,IAAI,EAAI,EAAK,EAAG,GAGpC,EAAK,SAAS,KAAK,KAAK,OAAO,EAAO,EAAG,EAAQ,EAAS,GAC9D,CACJ,CAIA,OAFA,GAAS,EAAM,KAAK,QAEb,CACX,CAEA,cAAA,CAAe,EAAM,EAAM,EAAO,GAC9B,KACI,EAAK,KAAK,IAEN,EAAK,MAAQ,EAAK,OAAS,IAAM,GAH5B,CAKT,IAEI,EAFA,EAAU,IACV,EAAiB,IAGrB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,SAAS,OAAQ,IAAK,CAC3C,MAAM,EAAQ,EAAK,SAAS,GACtB,EAAO,GAAS,GAChB,EAAc,GAAa,EAAM,GAAS,EAG5C,EAAc,GACd,EAAiB,EACjB,EAAU,EAAO,EAAU,EAAO,EAClC,EAAa,GAEN,IAAgB,GAEnB,EAAO,IACP,EAAU,EACV,EAAa,EAGzB,CAEA,EAAO,GAAc,EAAK,SAAS,EACvC,CAEA,OAAO,CACX,CAEA,OAAA,CAAQ,EAAM,EAAO,GACjB,MAAM,EAAO,EAAS,EAAO,KAAK,OAAO,GACnC,EAAa,GAGb,EAAO,KAAK,eAAe,EAAM,KAAK,KAAM,EAAO,GAOzD,IAJA,EAAK,SAAS,KAAK,GACnB,GAAO,EAAM,GAGN,GAAS,GACR,EAAW,GAAO,SAAS,OAAS,KAAK,aACzC,KAAK,OAAO,EAAY,GACxB,IAKR,KAAK,oBAAoB,EAAM,EAAY,EAC/C,CAGA,MAAA,CAAO,EAAY,GACf,MAAM,EAAO,EAAW,GAClB,EAAI,EAAK,SAAS,OAClB,EAAI,KAAK,YAEf,KAAK,iBAAiB,EAAM,EAAG,GAE/B,MAAM,EAAa,KAAK,kBAAkB,EAAM,EAAG,GAE7C,EAAU,GAAW,EAAK,SAAS,OAAO,EAAY,EAAK,SAAS,OAAS,IACnF,EAAQ,OAAS,EAAK,OACtB,EAAQ,KAAO,EAAK,KAEpB,GAAS,EAAM,KAAK,QACpB,GAAS,EAAS,KAAK,QAEnB,EAAO,EAAW,EAAQ,GAAG,SAAS,KAAK,GAC1C,KAAK,WAAW,EAAM,EAC/B,CAEA,UAAA,CAAW,EAAM,GAEb,KAAK,KAAO,GAAW,CAAC,EAAM,IAC9B,KAAK,KAAK,OAAS,EAAK,OAAS,EACjC,KAAK,KAAK,MAAO,EACjB,GAAS,KAAK,KAAM,KAAK,OAC7B,CAEA,iBAAA,CAAkB,EAAM,EAAG,GACvB,IAAI,EACA,EAAa,IACb,EAAU,IAEd,IAAK,IAAI,EAAI,EAAG,GAAK,EAAI,EAAG,IAAK,CAC7B,MAAM,EAAQ,GAAS,EAAM,EAAG,EAAG,KAAK,QAClC,EAAQ,GAAS,EAAM,EAAG,EAAG,KAAK,QAElC,EAAU,GAAiB,EAAO,GAClC,EAAO,GAAS,GAAS,GAAS,GAGpC,EAAU,GACV,EAAa,EACb,EAAQ,EAER,EAAU,EAAO,EAAU,EAAO,GAE3B,IAAY,GAEf,EAAO,IACP,EAAU,EACV,EAAQ,EAGpB,CAEA,OAAO,GAAS,EAAI,CACxB,CAGA,gBAAA,CAAiB,EAAM,EAAG,GACtB,MAAM,EAAc,EAAK,KAAO,KAAK,YAAc,GAC7C,EAAc,EAAK,KAAO,KAAK,YAAc,GACnC,KAAK,eAAe,EAAM,EAAG,EAAG,GAChC,KAAK,eAAe,EAAM,EAAG,EAAG,IAIzB,EAAK,SAAS,KAAK,EAC9C,CAGA,cAAA,CAAe,EAAM,EAAG,EAAG,GACvB,EAAK,SAAS,KAAK,GAEnB,MAAM,EAAS,KAAK,OACd,EAAW,GAAS,EAAM,EAAG,EAAG,GAChC,EAAY,GAAS,EAAM,EAAI,EAAG,EAAG,GAC3C,IAAI,EAAS,GAAW,GAAY,GAAW,GAE/C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAI,EAAG,IAAK,CAC5B,MAAM,EAAQ,EAAK,SAAS,GAC5B,GAAO,EAAU,EAAK,KAAO,EAAO,GAAS,GAC7C,GAAU,GAAW,EACzB,CAEA,IAAK,IAAI,EAAI,EAAI,EAAI,EAAG,GAAK,EAAG,IAAK,CACjC,MAAM,EAAQ,EAAK,SAAS,GAC5B,GAAO,EAAW,EAAK,KAAO,EAAO,GAAS,GAC9C,GAAU,GAAW,EACzB,CAEA,OAAO,CACX,CAEA,mBAAA,CAAoB,EAAM,EAAM,GAE5B,IAAK,IAAI,EAAI,EAAO,GAAK,EAAG,IACxB,GAAO,EAAK,GAAI,EAExB,CAEA,SAAA,CAAU,GAEN,IAAK,IAAyB,EAArB,EAAI,EAAK,OAAS,EAAa,GAAK,EAAG,IACZ,IAA5B,EAAK,GAAG,SAAS,OACb,EAAI,GACJ,EAAW,EAAK,EAAI,GAAG,SACvB,EAAS,OAAO,EAAS,QAAQ,EAAK,IAAK,IAExC,KAAK,QAET,GAAS,EAAK,GAAI,KAAK,OAEtC,GAGJ,SAAS,GAAS,EAAM,EAAO,GAC3B,IAAK,EAAU,OAAO,EAAM,QAAQ,GAEpC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAC9B,GAAI,EAAS,EAAM,EAAM,IAAK,OAAO,EAEzC,OAAO,CACX,CAGA,SAAS,GAAS,EAAM,GACpB,GAAS,EAAM,EAAG,EAAK,SAAS,OAAQ,EAAQ,EACpD,CAGA,SAAS,GAAS,EAAM,EAAG,EAAG,EAAQ,GAC7B,IAAU,EAAW,GAAW,OACrC,EAAS,KAAO,IAChB,EAAS,KAAO,IAChB,EAAS,MAAO,IAChB,EAAS,MAAO,IAEhB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,IAAK,CACxB,MAAM,EAAQ,EAAK,SAAS,GAC5B,GAAO,EAAU,EAAK,KAAO,EAAO,GAAS,EACjD,CAEA,OAAO,CACX,CAEA,SAAS,GAAO,EAAG,GAKf,OAJA,EAAE,KAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAC5B,EAAE,KAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAC5B,EAAE,KAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAC5B,EAAE,KAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MACrB,CACX,CAEA,SAAS,GAAgB,EAAG,GAAK,OAAO,EAAE,KAAO,EAAE,IAAM,CACzD,SAAS,GAAgB,EAAG,GAAK,OAAO,EAAE,KAAO,EAAE,IAAM,CAEzD,SAAS,GAAS,GAAO,OAAQ,EAAE,KAAO,EAAE,OAAS,EAAE,KAAO,EAAE,KAAO,CACvE,SAAS,GAAW,GAAK,OAAQ,EAAE,KAAO,EAAE,MAAS,EAAE,KAAO,EAAE,KAAO,CAEvE,SAAS,GAAa,EAAG,GACrB,OAAQ,KAAK,IAAI,EAAE,KAAM,EAAE,MAAQ,KAAK,IAAI,EAAE,KAAM,EAAE,QAC9C,KAAK,IAAI,EAAE,KAAM,EAAE,MAAQ,KAAK,IAAI,EAAE,KAAM,EAAE,MAC1D,CAEA,SAAS,GAAiB,EAAG,GACzB,MAAM,EAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAC1B,EAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAC1B,EAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAC1B,EAAO,KAAK,IAAI,EAAE,KAAM,EAAE,MAEhC,OAAO,KAAK,IAAI,EAAG,EAAO,GACnB,KAAK,IAAI,EAAG,EAAO,EAC9B,CAEA,SAAS,GAAS,EAAG,GACjB,OAAO,EAAE,MAAQ,EAAE,MACZ,EAAE,MAAQ,EAAE,MACZ,EAAE,MAAQ,EAAE,MACZ,EAAE,MAAQ,EAAE,IACvB,CAEA,SAAS,GAAW,EAAG,GACnB,OAAO,EAAE,MAAQ,EAAE,MACZ,EAAE,MAAQ,EAAE,MACZ,EAAE,MAAQ,EAAE,MACZ,EAAE,MAAQ,EAAE,IACvB,CAEA,SAAS,GAAW,GAChB,MAAO,CACH,WACA,OAAQ,EACR,MAAM,EACN,KAAM,IACN,KAAM,IACN,MAAM,IACN,MAAM,IAEd,CAKA,SAAS,GAAY,EAAK,EAAM,EAAO,EAAG,GACtC,MAAM,EAAQ,CAAC,EAAM,GAErB,KAAO,EAAM,QAAQ,CAIjB,IAHA,EAAQ,EAAM,QACd,EAAO,EAAM,QAEO,EAAG,SAEvB,MAAM,EAAM,EAAO,KAAK,MAAM,EAAQ,GAAQ,EAAI,GAAK,EACvD,GAAY,EAAK,EAAK,EAAM,EAAO,GAEnC,EAAM,KAAK,EAAM,EAAK,EAAK,EAC/B,CACJ,CC1eA,SAAgB,GACd,EACA,EACA,EAAY,EACZ,EACA,GAEA,MAAM,EAAoC,mBAAZ,EAAyB,OAAU,EACjE,GAAkB,UAAd,EAAK,KAAkB,OAAO,EAAc,EAAW,EAAM,EAAQ,GAAiB,GAC1F,GAAkB,cAAd,EAAK,KAAsB,CAC7B,MAAM,EAAS,EAAe,EAAM,EAAQ,GAAgB,OAC5D,OAAO,EACJ,MAAM,GACN,KAAA,CACE,EAAG,IACF,EAAgB,EAAO,EAAO,GAAI,IAAM,GAAa,EAAK,OAAO,aAAe,GAAK,EAE7F,CACA,MAAM,EAAI,EACN,EACA,CAAE,EAAG,EAAK,EAAI,EAAK,EAAI,EAAG,EAAG,EAAK,EAAI,EAAK,EAAI,KAC7C,EAAK,UAAY,IAErB,EAAI,EAAE,EAAI,EAAK,EACf,EAAI,EAAE,EAAI,EAAK,EACf,EAAS,GAAa,EAAK,OAAO,aAAe,GAAK,EAClD,EACJ,EAAK,SACU,SAAd,EAAK,KACF,CACE,CAAC,EAAG,GACJ,CAAC,EAAK,EAAG,EAAK,SAEhB,GACN,IAAmB,SAAd,EAAK,MAAiC,SAAd,EAAK,OAAoB,EAAY,CAChE,MAAM,EAAM,EAAW,IAAA,EAAM,EAAI,MAAA,CAAW,EAAG,EAAK,EAAI,EAAI,EAAG,EAAK,EAAI,KACxE,OACG,EAAK,QAAU,EAAe,EAAG,IAClC,EAAI,MAAM,GAAG,KAAA,CAAM,EAAI,IAAM,EAAgB,EAAG,EAAI,GAAI,IAAO,EAEnE,CACA,MAAM,IACF,EAAK,MAAM,YACS,IAArB,EAAK,OAAO,MAA0C,SAApB,EAAK,MAAM,MAC9C,CAAC,OAAQ,OAAQ,QAAS,QAAS,OAAQ,OAAQ,SAAS,SAAS,EAAK,MACtE,EAAqC,mBAAZ,EAAyB,EAAQ,GAAQ,EACxE,GAAI,EAAiB,CACnB,MAAM,EAAW,MAAM,QAAQ,GAAmB,EAAkB,CAAC,GACnE,EAAQ,CAAE,IAAG,KACf,OAAO,EAAS,KAAM,IACpB,IAAK,EAAM,OAAO,OAAQ,OAAO,EACjC,GAAI,EAAM,QAAU,GAAU,EAAe,EAAO,EAAM,QAAS,OAAO,EAC1E,MAAM,EAAS,EAAM,OAAS,IAAI,EAAM,OAAQ,EAAM,OAAO,IAAM,EAAM,OACzE,OAAyB,IAAlB,EAAO,OACV,EAAgB,EAAO,EAAO,GAAI,EAAO,KAAO,EAChD,EACG,MAAM,GACN,KAAA,CAAM,EAAO,IAAU,EAAgB,EAAO,EAAO,GAAQ,IAAU,IAElF,CACA,GAAkB,YAAd,EAAK,KAAoB,CAC3B,MAAM,EAAK,EAAK,EAAI,EAClB,EAAK,EAAK,EAAI,EAChB,IAAK,IAAO,EAAI,OAAO,EACvB,MAAM,EAAI,KAAK,OAAO,EAAI,GAAM,GAAK,EAAI,GAAM,GAC7C,EAAO,EAAS,KAAK,IAAI,EAAI,GAC/B,OAAO,EAAS,GAAK,EAAI,EAAO,KAAK,IAAI,EAAI,IAAM,CACrD,CACA,GAAkB,YAAd,EAAK,KAAoB,CAC3B,MAAM,EAAW,CACb,CAAE,EAAG,EAAK,EAAI,EAAG,EAAG,GACpB,CAAE,EAAG,EAAK,EAAG,EAAG,EAAK,EAAI,GACzB,CAAE,EAAG,EAAK,EAAI,EAAG,EAAG,EAAK,GACzB,CAAE,EAAG,EAAG,EAAG,EAAK,EAAI,IAEtB,EAAQ,CAAE,IAAG,KACf,OACG,GAAU,EAAe,EAAO,IACjC,EAAS,KAAA,CAAM,EAAG,IAAM,EAAgB,EAAO,EAAG,GAAU,EAAI,GAAK,KAAO,EAEhF,CAEA,OADc,IAAM,GAAU,GAAK,EAAK,EAAI,GAAU,IAAM,GAAU,GAAK,EAAK,EAAI,IAExE,GAAU,GAAK,GAAU,GAAK,EAAK,EAAI,GAAU,GAAK,GAAU,GAAK,EAAK,EAAI,EAE5F,CACA,IAAa,GAAb,MAMY,QALV,KAAe,IAAI,GACnB,sBAAiB,IAAI,IACrB,uBAAkB,IAAI,IACtB,WAAA,CACE,EAAgB,GAChB,GAAQ,KAAA,QAAA,EAER,KAAK,IAAI,EACX,CACA,GAAA,CAAI,EAAe,EAAuC,KAAK,SAC7D,KAAK,QAAU,EACf,KAAK,KAAK,QACV,KAAK,OAAS,IAAI,IAAI,EAAa,GAAO,IAAK,GAAM,CAAC,EAAE,GAAI,KAC5D,MAAM,EAAmB,GACzB,IAAI,EAAQ,EACZ,MAAM,EAAA,CAAQ,EAAc,KAC1B,IAAK,MAAM,KAAQ,EAAM,CACvB,MAAM,EAAI,EAAW,EAAM,KAAK,OAAQ,KAAK,SAC7C,EAAQ,KAAK,CACX,KAAM,EAAE,EACR,KAAM,EAAE,EACR,KAAM,EAAE,EAAI,EAAE,EACd,KAAM,EAAE,EAAI,EAAE,EACd,OACA,MAAO,IACP,YAEE,EAAK,UAAU,EAAK,EAAK,SAAU,IAAI,EAAS,GACtD,GAEF,EAAK,EAAO,IACZ,KAAK,QAAU,IAAI,IAAI,EAAQ,IAAK,GAAU,CAAC,EAAM,KAAK,GAAI,KAC9D,KAAK,KAAK,KAAK,EACjB,CACA,MAAA,CAAO,GACL,OAAO,KAAK,KACT,OAAO,CAAE,KAAM,EAAI,EAAG,KAAM,EAAI,EAAG,KAAM,EAAI,EAAI,EAAI,EAAG,KAAM,EAAI,EAAI,EAAI,IAC1E,OAAQ,IAAO,EAAE,KAAK,SAAW,EAAE,QAAQ,KAAM,GAAM,EAAE,SACzD,KAAA,CAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,OAC3B,IAAK,GAAM,EAAE,KAClB,CACA,QAAA,CACE,EACA,EAAuE,CAAC,GAExE,MAAM,iBAAW,IAAI,IACf,EAAa,KAAK,KAAK,OAAO,CAClC,KAAM,EAAI,EACV,KAAM,EAAI,EACV,KAAM,EAAI,EAAI,EAAI,EAClB,KAAM,EAAI,EAAI,EAAI,IAEd,EAAiB,IACrB,KACE,EAAM,KAAK,QACX,EAAM,KAAK,QACX,EAAQ,SAAS,EAAM,OACvB,EAAM,QAAQ,KAAM,GAAW,EAAO,QAAU,EAAO,QAAU,EAAQ,SAAS,KAGpF,MAAO,CACL,EAAG,EAAM,KACT,EAAG,EAAM,KACT,EAAG,EAAM,KAAO,EAAM,KACtB,EAAG,EAAM,KAAO,EAAM,OAG1B,IAAK,MAAM,KAAa,EAAY,CAClC,MAAM,EAAU,EAAc,GAC9B,IAAK,IAAY,EAAS,EAAK,GAAU,SACzC,MAAM,EAAS,EAAU,QAAQ,OAAQ,GAA2B,UAAhB,EAAO,MAErD,EAAQ,EADE,EAAO,UAAW,GAAW,EAAO,KAAO,EAAQ,cACpC,GACzB,EAAQ,EAAQ,KAAK,QAAQ,IAAI,EAAM,IAAO,EACpD,GAAI,EAAM,KAAK,KAAO,EAAQ,aAAc,SAC5C,MAAM,EAAS,IAAU,EAAY,EAAU,EAAc,GACzD,GAAU,EAAS,EAAK,IAAS,EAAS,IAAI,EAAM,KAAK,GAAI,EACnE,CACA,MAAO,IAAI,EAAS,UAAU,KAAA,CAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,OAAO,IAAK,GAAU,EAAM,KACvF,CACA,IAAA,CAAK,EAAc,EAAuB,CAAC,GACzC,MAAM,EAAY,EAAQ,WAAa,EACjC,EAAQ,KAAK,KAChB,OAAO,CACN,KAAM,EAAM,EAAI,EAChB,KAAM,EAAM,EAAI,EAChB,KAAM,EAAM,EAAI,EAChB,KAAM,EAAM,EAAI,IAEjB,KAAA,CAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,OAC9B,IAAK,MAAM,KAAK,EAAO,CACrB,GACE,EAAE,KAAK,QACP,EAAQ,SAAS,EAAE,QACjB,EAAQ,eAAiB,EAAE,KAAK,QAClC,EAAE,QAAQ,KACP,GAAM,EAAE,QAAU,EAAQ,SAAS,KAAQ,EAAQ,eAAiB,EAAE,QAGzE,SACF,IAAK,GAAQ,EAAE,KAAM,EAAO,EAAW,KAAK,OAAQ,EAAQ,SAAW,KAAK,SAC1E,SACF,MAAM,EAAS,EAAE,QAAQ,OAAQ,GAAiB,UAAX,EAAE,MAGzC,OADc,EADE,EAAO,UAAW,GAAM,EAAE,KAAO,EAAQ,cAC1B,IACf,EAAE,IACpB,CAEF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ui-Cay6AVqT.js","names":[],"sources":["../../node_modules/perfect-freehand/dist/esm/index.mjs","../../src/stage/paint.ts","../../src/porter/json.ts","../../src/ui/icons.ts","../../src/ui/version.ts","../../src/ui/index.ts"],"sourcesContent":["const{PI:e}=Math,t=e+1e-4,n=.5,r=[1,1];function i(e,t,n,r=e=>e){return e*r(.5-t*(.5-n))}const{min:a}=Math;function o(e,t,n){let r=a(1,t/n);return a(1,e+(a(1,1-r)-e)*(r*.275))}function s(e){return[-e[0],-e[1]]}function c(e,t){return[e[0]+t[0],e[1]+t[1]]}function l(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function u(e,t){return[e[0]-t[0],e[1]-t[1]]}function d(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function f(e,t){return[e[0]*t,e[1]*t]}function p(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function m(e,t){return[e[0]/t,e[1]/t]}function h(e){return[e[1],-e[0]]}function g(e,t){let n=t[0];return e[0]=t[1],e[1]=-n,e}function ee(e,t){return e[0]*t[0]+e[1]*t[1]}function _(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return Math.hypot(e[0],e[1])}function y(e,t){let n=e[0]-t[0],r=e[1]-t[1];return n*n+r*r}function b(e){return m(e,v(e))}function x(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function S(e,t,n){let r=Math.sin(n),i=Math.cos(n),a=e[0]-t[0],o=e[1]-t[1],s=a*i-o*r,c=a*r+o*i;return[s+t[0],c+t[1]]}function C(e,t,n,r){let i=Math.sin(r),a=Math.cos(r),o=t[0]-n[0],s=t[1]-n[1],c=o*a-s*i,l=o*i+s*a;return e[0]=c+n[0],e[1]=l+n[1],e}function w(e,t,n){return c(e,f(u(t,e),n))}function te(e,t,n,r){let i=n[0]-t[0],a=n[1]-t[1];return e[0]=t[0]+i*r,e[1]=t[1]+a*r,e}function T(e,t,n){return c(e,f(t,n))}const E=[0,0],D=[0,0],O=[0,0];function k(e,n){let r=T(e,b(h(u(e,c(e,[1,1])))),-n),i=[],a=1/13;for(let n=a;n<=1;n+=a)i.push(S(r,e,t*2*n));return i}function A(e,n,r){let i=[],a=1/r;for(let r=a;r<=1;r+=a)i.push(S(n,e,t*r));return i}function j(e,t,n){let r=u(t,n),i=f(r,.5),a=f(r,.51);return[u(e,i),u(e,a),c(e,a),c(e,i)]}function M(e,n,r,i){let a=[],o=T(e,n,r),s=1/i;for(let n=s;n<1;n+=s)a.push(S(o,e,t*3*n));return a}function ne(e,t,n){return[c(e,f(t,n)),c(e,f(t,n*.99)),u(e,f(t,n*.99)),u(e,f(t,n))]}function N(e,t,n){return e===!1||e===void 0?0:e===!0?Math.max(t,n):e}function re(e,t,n){return e.slice(0,10).reduce((e,r)=>{let i=r.pressure;return t&&(i=o(e,r.distance,n)),(e+i)/2},e[0].pressure)}function P(e,n={}){let{size:r=16,smoothing:a=.5,thinning:f=.5,simulatePressure:m=!0,easing:_=e=>e,start:v={},end:b={},last:x=!1}=n,{cap:S=!0,easing:w=e=>e*(2-e)}=v,{cap:T=!0,easing:P=e=>--e*e*e+1}=b;if(e.length===0||r<=0)return[];let F=e[e.length-1].runningLength,I=N(v.taper,r,F),L=N(b.taper,r,F),R=(r*a)**2,z=[],B=[],V=re(e,m,r),H=i(r,f,e[e.length-1].pressure,_),U,W=e[0].vector,G=e[0].point,K=G,q=G,J=K,Y=!1;for(let n=0;n<e.length;n++){let{pressure:a}=e[n],{point:s,vector:h,distance:v,runningLength:b}=e[n],x=n===e.length-1;if(!x&&F-b<3)continue;f?(m&&(a=o(V,v,r)),H=i(r,f,a,_)):H=r/2,U===void 0&&(U=H);let S=b<I?w(b/I):1,T=F-b<L?P((F-b)/L):1;H=Math.max(.01,H*Math.min(S,T));let k=(x?e[n]:e[n+1]).vector,A=x?1:ee(h,k),j=ee(h,W)<0&&!Y,M=A!==null&&A<0;if(j||M){g(E,W),p(E,E,H);for(let e=0;e<=1;e+=.07692307692307693)d(D,s,E),C(D,D,s,t*e),q=[D[0],D[1]],z.push(q),l(O,s,E),C(O,O,s,t*-e),J=[O[0],O[1]],B.push(J);G=q,K=J,M&&(Y=!0);continue}if(Y=!1,x){g(E,h),p(E,E,H),z.push(u(s,E)),B.push(c(s,E));continue}te(E,k,h,A),g(E,E),p(E,E,H),d(D,s,E),q=[D[0],D[1]],(n<=1||y(G,q)>R)&&(z.push(q),G=q),l(O,s,E),J=[O[0],O[1]],(n<=1||y(K,J)>R)&&(B.push(J),K=J),V=a,W=h}let X=[e[0].point[0],e[0].point[1]],Z=e.length>1?[e[e.length-1].point[0],e[e.length-1].point[1]]:c(e[0].point,[1,1]),Q=[],$=[];if(e.length===1){if(!(I||L)||x)return k(X,U||H)}else{I||L&&e.length===1||(S?Q.push(...A(X,B[0],13)):Q.push(...j(X,z[0],B[0])));let t=h(s(e[e.length-1].vector));L||I&&e.length===1?$.push(Z):T?$.push(...M(Z,t,H,29)):$.push(...ne(Z,t,H))}return z.concat($,B.reverse(),Q)}const F=[0,0];function I(e){return e!=null&&e>=0}function L(e,t={}){let{streamline:i=.5,size:a=16,last:o=!1}=t;if(e.length===0)return[];let s=.15+(1-i)*.85,l=Array.isArray(e[0])?e:e.map(({x:e,y:t,pressure:r=n})=>[e,t,r]);if(l.length===2){let e=l[1];l=l.slice(0,-1);for(let t=1;t<5;t++)l.push(w(l[0],e,t/4))}l.length===1&&(l=[...l,[...c(l[0],r),...l[0].slice(2)]]);let u=[{point:[l[0][0],l[0][1]],pressure:I(l[0][2])?l[0][2]:.25,vector:[...r],distance:0,runningLength:0}],f=!1,p=0,m=u[0],h=l.length-1;for(let e=1;e<l.length;e++){let t=o&&e===h?[l[e][0],l[e][1]]:w(m.point,l[e],s);if(_(m.point,t))continue;let r=x(t,m.point);if(p+=r,e<h&&!f){if(p<a)continue;f=!0}d(F,m.point,t),m={point:t,pressure:I(l[e][2])?l[e][2]:n,vector:b(F),distance:r,runningLength:p},u.push(m)}return u[0].vector=u[1]?.vector||[0,0],u}function R(e,t={}){return P(L(e,t),t)}var z=R;export{z as default,R as getStroke,P as getStrokeOutlinePoints,L as getStrokePoints};\n//# sourceMappingURL=index.mjs.map","import { getStroke } from 'perfect-freehand';\nimport { CARD_CORNER } from '../core/defaults';\nimport type { Item, ItemText, Point, Style } from '../core/types';\n\nexport const SVG_NS = 'http://www.w3.org/2000/svg';\nexport const fonts = {\n sans: 'Nunito Variable, Nunito, ui-rounded, system-ui, sans-serif',\n serif: 'Georgia, serif',\n mono: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n hand: 'Comic Sans MS, Chalkboard SE, cursive',\n};\nexport const DEFAULT_FONT = 'hand' satisfies keyof typeof fonts;\nexport function fontFamily(font?: ItemText['font']): string {\n return fonts[font ?? DEFAULT_FONT];\n}\nconst light: Record<string, string> = {\n ink: '#103639',\n slate: '#606062',\n coral: '#FF9302',\n amber: '#FFC68A',\n moss: '#AAF1AC',\n teal: '#05D9AB',\n sky: '#92CAFF',\n violet: '#8F93F9',\n rose: '#F89B97',\n paper: '#FFFFFF',\n};\nconst dark: Record<string, string> = {\n ...light,\n ink: '#E9F7F3',\n slate: '#B6C5C1',\n paper: '#173D40',\n};\nexport function color(value = 'ink', theme: 'light' | 'dark' = 'light'): string {\n return (theme === 'dark' ? dark : light)[value] ?? value;\n}\nfunction rgb(value: string): number[] | undefined {\n const named: Record<string, string> = {\n black: '#000000',\n white: '#ffffff',\n red: '#ff0000',\n blue: '#0000ff',\n green: '#008000',\n yellow: '#ffff00',\n transparent: '#00000000',\n };\n value = named[value.toLowerCase()] ?? value;\n if (/^#[\\da-f]{3,4}$/i.test(value))\n value = `#${[...value.slice(1)].map((channel) => channel + channel).join('')}`;\n if (/^#[\\da-f]{6}([\\da-f]{2})?$/i.test(value))\n return [1, 3, 5]\n .map((index) => parseInt(value.slice(index, index + 2), 16))\n .concat(value.length === 9 ? parseInt(value.slice(7, 9), 16) / 255 : 1);\n if (!/^rgba?\\(/i.test(value)) return undefined;\n const channels = value.match(/[\\d.]+%?/g);\n if (!channels || channels.length < 3) return undefined;\n return channels\n .slice(0, 3)\n .map((channel) => parseFloat(channel) * (channel.endsWith('%') ? 2.55 : 1))\n .concat(\n channels[3] === undefined\n ? 1\n : parseFloat(channels[3]) / (channels[3].endsWith('%') ? 100 : 1),\n );\n}\nfunction luminance(channels: number[]): number {\n return channels\n .slice(0, 3)\n .map((channel) => {\n const value = channel / 255;\n return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;\n })\n .reduce((sum, channel, index) => sum + channel * [0.2126, 0.7152, 0.0722][index], 0);\n}\n/** Preserve explicit text colors and keep labels legible on opaque shape fills. */\nexport function labelColor(item: Item, theme: 'light' | 'dark'): string {\n if (item.kind === 'text') return color(item.style?.stroke ?? 'ink', theme);\n const ink = color('ink', theme),\n style = styleFor(item, theme);\n if (['connector', 'line'].includes(item.kind) || style.fillMode !== 'solid') return ink;\n const fill = rgb(style.fill);\n if (!fill) return ink;\n const paper = rgb(color('paper', theme))!;\n const background = luminance(\n fill.slice(0, 3).map((channel, index) => channel * fill[3] + paper[index] * (1 - fill[3])),\n );\n const contrast = (value: string) => {\n const foreground = luminance(rgb(value)!);\n return (Math.max(background, foreground) + 0.05) / (Math.min(background, foreground) + 0.05);\n };\n for (const candidate of [ink, color('ink', theme === 'dark' ? 'light' : 'dark')])\n if (contrast(candidate) >= 4.5) return candidate;\n return contrast('#0F0B0A') >= contrast('#FFFFFF') ? '#0F0B0A' : '#FFFFFF';\n}\nexport function fontSize(text?: ItemText): number {\n return typeof text?.size === 'number'\n ? text.size\n : { s: 14, m: 18, l: 26, xl: 36 }[text?.size ?? 'm'];\n}\nexport function esc(value: unknown): string {\n return String(value ?? '').replace(\n /[&<>\"']/g,\n (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char]!,\n );\n}\nexport function round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\nexport function pathFromPoints(points: Point[], closed = false): string {\n return (\n points\n .map((point, index) => `${index ? 'L' : 'M'}${round(point.x)},${round(point.y)}`)\n .join(' ') + (closed ? ' Z' : '')\n );\n}\nexport function freehandPath(item: Item): string {\n const points = item.points ?? [];\n if (!points.length) return '';\n if (item.closed)\n return pathFromPoints(\n points.map(([x, y]) => ({ x, y })),\n true,\n );\n const stroke = getStroke(\n points.map(([x, y, pressure]) => ({ x, y, pressure })),\n {\n size: (item.style?.strokeWidth ?? 2) * 2.2,\n thinning: 0.45,\n smoothing: 0.6,\n streamline: 0.45,\n simulatePressure: points.every((point) => point[2] === undefined),\n last: true,\n },\n );\n if (!stroke.length) return '';\n return `M${stroke.map((point) => `${round(point[0])},${round(point[1])}`).join(' L')} Z`;\n}\nexport function shapePath(item: Item): string {\n const w = item.w,\n h = item.h;\n if (item.kind === 'ellipse')\n return `M${w},${h / 2}a${w / 2},${h / 2} 0 1 0 ${-w},0a${w / 2},${h / 2} 0 1 0 ${w},0Z`;\n if (item.kind === 'diamond') return `M${w / 2},0L${w},${h / 2}L${w / 2},${h}L0,${h / 2}Z`;\n if (item.kind === 'line')\n return pathFromPoints(\n (\n item.points ?? [\n [0, 0],\n [w, h],\n ]\n ).map(([x, y]) => ({ x, y })),\n );\n if (item.kind === 'path') return freehandPath(item);\n const corner = Math.max(0, Math.min(item.style?.corner ?? CARD_CORNER, w / 2, h / 2));\n return `M${corner},0H${w - corner}Q${w},0 ${w},${corner}V${h - corner}Q${w},${h} ${w - corner},${h}H${corner}Q0,${h} 0,${h - corner}V${corner}Q0,0 ${corner},0Z`;\n}\nexport function styleFor(item: Item, theme: 'light' | 'dark'): Required<Style> {\n const fill = item.style?.fill ?? (item.kind === 'note' ? 'moss' : 'none');\n return {\n stroke: color(item.style?.stroke ?? 'ink', theme),\n strokeWidth: item.style?.strokeWidth ?? (item.kind === 'note' ? 0 : 2),\n dash: item.style?.dash ?? 'solid',\n fill: color(fill, theme),\n fillMode: item.style?.fillMode ?? 'solid',\n corner: item.style?.corner ?? CARD_CORNER,\n opacity: item.style?.opacity ?? 1,\n };\n}\nexport function shapeMarkup(\n item: Item,\n theme: 'light' | 'dark',\n uid: string,\n path = shapePath(item),\n): string {\n const style = styleFor(item, theme);\n const dash = style.dash === 'dashed' ? '8 6' : style.dash === 'dotted' ? '1 6' : '';\n const isPath = item.kind === 'path';\n const fill =\n item.kind === 'line' || item.kind === 'connector'\n ? 'none'\n : isPath\n ? item.closed && style.fill !== 'none'\n ? style.fill\n : style.stroke\n : style.fill;\n const hatchId = `ad_h_${uid.replace(/[^a-z0-9_-]/gi, '_')}`;\n const hatch = style.fillMode === 'hatch' && fill !== 'none' && !isPath;\n const defs = hatch\n ? `<defs><pattern id=\"${hatchId}\" width=\"8\" height=\"8\" patternUnits=\"userSpaceOnUse\"><path d=\"M-2 2L2-2M0 8L8 0M6 10L10 6\" fill=\"none\" stroke=\"${esc(fill)}\" stroke-opacity=\"0.5\" stroke-width=\"1.3\"/></pattern></defs>`\n : '';\n const fillAttr = hatch ? `url(#${hatchId})` : fill;\n const geometry = `<path d=\"${esc(path)}\" fill=\"${esc(fillAttr)}\"${style.fillMode === 'tint' && !isPath ? ' fill-opacity=\"0.22\"' : ''} stroke=\"${isPath && !item.closed ? 'none' : esc(style.stroke)}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/>`;\n return `${defs}${geometry}`;\n}\nexport function headMarkup(\n point: Point,\n previous: Point,\n kind: 'arrow' | 'dot' | 'none' | undefined,\n stroke: string,\n width: number,\n): string {\n if (!kind || kind === 'none') return '';\n if (kind === 'dot')\n return `<circle cx=\"${round(point.x)}\" cy=\"${round(point.y)}\" r=\"${Math.max(3, width * 2)}\" fill=\"${esc(stroke)}\"/>`;\n const angle = Math.atan2(point.y - previous.y, point.x - previous.x);\n const length = Math.max(10, width * 4.5);\n const spread = Math.PI / 6;\n const a = {\n x: point.x - Math.cos(angle - spread) * length,\n y: point.y - Math.sin(angle - spread) * length,\n };\n const b = {\n x: point.x - Math.cos(angle + spread) * length,\n y: point.y - Math.sin(angle + spread) * length,\n };\n return `<path d=\"${pathFromPoints([a, point, b])}\" fill=\"none\" stroke=\"${esc(stroke)}\" stroke-width=\"${width}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`;\n}\nexport function headsMarkup(points: Point[], item: Item, theme: 'light' | 'dark'): string {\n if (points.length < 2) return '';\n const style = styleFor(item, theme);\n return (\n headMarkup(points[0], points[1], item.heads?.start, style.stroke, style.strokeWidth) +\n headMarkup(\n points[points.length - 1],\n points[points.length - 2],\n item.heads?.end ?? (item.kind === 'connector' ? 'arrow' : 'none'),\n style.stroke,\n style.strokeWidth,\n )\n );\n}\n","import type { AnnieDoc } from '../core/types';\nexport const ANNIE_MIME = 'application/vnd.anniedrawing+json';\nexport function exportJSON(doc: AnnieDoc): string {\n return JSON.stringify(doc, null, 2);\n}\n","const paths: Record<string, string> = {\n select:\n '<path d=\"M5.8 3.8c-1-.4-1.7.4-1.4 1.4l4.9 14.4c.4 1.1 1.8 1.1 2.2 0l2.2-5.8 5.8-2.2c1.1-.4 1.1-1.8 0-2.2Z\"/>',\n hand: '<path d=\"M8 12V6a2 2 0 0 1 4 0v5-7a2 2 0 0 1 4 0v8-5a2 2 0 0 1 4 0v8c0 5-4 7-7 7-3 0-4-2-6-5l-3-4c-1-2 1-4 3-2l2 2\"/>',\n rect: '<rect x=\"3.75\" y=\"4.75\" width=\"16.5\" height=\"14.5\" rx=\"4\"/>',\n ellipse: '<ellipse cx=\"12\" cy=\"12\" rx=\"8.25\" ry=\"7.25\"/>',\n diamond:\n '<path d=\"m13.4 3.8 6.8 6.8a2 2 0 0 1 0 2.8l-6.8 6.8a2 2 0 0 1-2.8 0l-6.8-6.8a2 2 0 0 1 0-2.8l6.8-6.8a2 2 0 0 1 2.8 0Z\"/>',\n line: '<path d=\"m5.5 18.5 13-13\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"5\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/>',\n connector: '<path d=\"M4 18h5a3 3 0 0 0 3-3V9a3 3 0 0 1 3-3h5m-4-4 4 4-4 4\"/>',\n path: '<path d=\"M3.5 17.5c1.8-5 3.2-11 6-11 4 0-1 12 3 12 2.8 0 3.2-8 5.5-8 1.6 0 2.3 2 2.5 4\"/>',\n text: '<path d=\"M5 7V4.5h14V7M12 4.5v15M8.5 19.5h7\"/>',\n note: '<path d=\"M7 3.75h10a3.25 3.25 0 0 1 3.25 3.25v7.1a2 2 0 0 1-.6 1.4l-4.2 4.2a2 2 0 0 1-1.4.6H7A3.25 3.25 0 0 1 3.75 17V7A3.25 3.25 0 0 1 7 3.75Z\"/><path d=\"M20 14h-3.5a2.5 2.5 0 0 0-2.5 2.5V20\"/>',\n lock: '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 8 0v3M12 14v3\"/>',\n unlock:\n '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 7.5-2M12 14v3\"/>',\n opacity:\n '<circle cx=\"12\" cy=\"12\" r=\"8.5\"/><path d=\"M12 3.5a8.5 8.5 0 0 1 0 17Z\" fill=\"currentColor\" stroke=\"none\"/>',\n front:\n '<rect x=\"8\" y=\"3.5\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 16v1A3.5 3.5 0 0 1 12 20.5H7A3.5 3.5 0 0 1 3.5 17v-5A3.5 3.5 0 0 1 7 8.5h1\"/>',\n back: '<rect x=\"3.5\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M8.5 8V7A3.5 3.5 0 0 1 12 3.5h5A3.5 3.5 0 0 1 20.5 7v5A3.5 3.5 0 0 1 17 15.5h-1\"/>',\n eraser:\n '<path d=\"m13.2 4.3-9 9a2.4 2.4 0 0 0 0 3.4L7.5 20h4l8.2-8.2a2.4 2.4 0 0 0 0-3.4l-4.1-4.1a1.7 1.7 0 0 0-2.4 0ZM8 10.5l6 6M11.5 20H21\"/>',\n undo: '<path d=\"m8 5-4.5 4.5L8 14M4 9.5h9.5a5.5 5.5 0 0 1 0 11H11\"/>',\n redo: '<path d=\"m16 5 4.5 4.5L16 14m4-4.5h-9.5a5.5 5.5 0 0 0 0 11H13\"/>',\n plus: '<path d=\"M12 5.5v13M5.5 12h13\"/>',\n minus: '<path d=\"M5.5 12h13\"/>',\n fit: '<path d=\"M8.5 3.75h-3a1.75 1.75 0 0 0-1.75 1.75v3m11.75-4.75h3a1.75 1.75 0 0 1 1.75 1.75v3M3.75 15.5v3a1.75 1.75 0 0 0 1.75 1.75h3m11.75-4.75v3a1.75 1.75 0 0 1-1.75 1.75h-3\"/>',\n chevron: '<path d=\"m7 9.5 3.6 3.6a2 2 0 0 0 2.8 0L17 9.5\"/>',\n download: '<path d=\"M12 3.5v11m-4-4 4 4 4-4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n upload: '<path d=\"M12 15V4m-4 4 4-4 4 4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n code: '<path d=\"m7 7-4 4a1.4 1.4 0 0 0 0 2l4 4m10-10 4 4a1.4 1.4 0 0 1 0 2l-4 4M14 4l-4 16\"/>',\n close: '<path d=\"m6.5 6.5 11 11m-11 0 11-11\"/>',\n more: '<circle cx=\"5\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/>',\n image:\n '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"m4 17 3.6-3.6a1.3 1.3 0 0 1 1.8 0l2.1 2.1 3.4-5.1a1.3 1.3 0 0 1 2.2 0L20 15\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2.5v1M12 20.5v1M2.5 12h1m17 0h1M5.3 5.3l.7.7m12 12 .7.7M5.3 18.7l.7-.7M18 6l.7-.7\"/>',\n moon: '<path d=\"M20 14.5a8.2 8.2 0 0 1-10.5-10c-3.9.7-6.4 3.7-6.4 7.5a8.1 8.1 0 0 0 16.9 2.5Z\"/>',\n trash:\n '<path d=\"M4 6.5h16M9 6.5V5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5v1.5m-9 0 .7 11.2A3 3 0 0 0 9.7 20.5h4.6a3 3 0 0 0 3-2.8L18 6.5M10 10.5v6m4-6v6\"/>',\n copy: '<rect x=\"8\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 8V7A3.5 3.5 0 0 0 12 3.5H7A3.5 3.5 0 0 0 3.5 7v5A3.5 3.5 0 0 0 7 15.5h1\"/>',\n grid: '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><path d=\"M9 4v16m6-16v16M4 9h16M4 15h16\"/>',\n book: '<path d=\"M12 5.5c-2.6-2-5.2-2.5-8-2v15c2.8-.5 5.4 0 8 2 2.6-2 5.2-2.5 8-2v-15c-2.8-.5-5.4 0-8 2Zm0 0v15\"/>',\n github:\n '<path fill=\"currentColor\" stroke=\"none\" d=\"M12 1C5.922 1 1 5.922 1 12c0 4.867 3.149 8.979 7.521 10.437.55.096.75-.232.75-.546 0-.262-.013-1.13-.013-2.049-3.06.56-3.703-1.31-3.703-1.31-.498-1.316-1.216-1.667-1.216-1.667-.991-.68.075-.668.075-.668 1.109.075 1.688 1.264 1.688 1.264.982 1.686 2.573 1.2 3.201.907.096-.699.381-1.2.695-1.478-2.448-.282-5.022-1.226-5.022-5.451 0-1.2.426-2.187 1.12-2.953-.113-.275-.487-1.392.107-2.9 0 0 .917-.292 3.011 1.12.873-.24 1.809-.36 2.74-.36.93 0 1.867.12 2.74.36 2.077-1.413 3.01-1.12 3.01-1.12.596 1.508.221 2.625.108 2.9.697.766 1.12 1.748 1.12 2.953 0 4.237-2.578 5.163-5.034 5.437.39.338.746 1.016.746 2.056 0 1.478-.014 2.666-.014 3.025 0 .304.202.655.753.545C19.854 20.979 23 16.859 23 12c0-6.078-4.922-11-11-11Z\"/>',\n alignLeft: '<path d=\"M4 5h16M4 12h10M4 19h16\"/>',\n alignCenter: '<path d=\"M4 5h16M7 12h10M4 19h16\"/>',\n alignRight: '<path d=\"M4 5h16M10 12h10M4 19h16\"/>',\n align:\n '<path d=\"M4 3.5v17\"/><rect x=\"8\" y=\"5\" width=\"12.5\" height=\"5\" rx=\"1.75\"/><rect x=\"8\" y=\"14\" width=\"8.5\" height=\"5\" rx=\"1.75\"/>',\n shapes:\n '<rect x=\"3\" y=\"3\" width=\"8.5\" height=\"8.5\" rx=\"2.5\"/><circle cx=\"17.3\" cy=\"6.7\" r=\"3.7\"/><path d=\"m6 14-3.5 6h8L7 14a.6.6 0 0 0-1 0Z\"/><rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"2\" transform=\"rotate(45 17 17)\"/>',\n link: '<path d=\"M10 14.5 8.8 15.7a3.6 3.6 0 1 1-5.1-5.1l3.2-3.2a3.6 3.6 0 0 1 5.1 0\"/><path d=\"m14 9.5 1.2-1.2a3.6 3.6 0 0 1 5.1 5.1l-3.2 3.2a3.6 3.6 0 0 1-5.1 0\"/>',\n};\nexport function icon(name: string) {\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths[name] ?? paths.select}</svg>`;\n}\nexport function button(\n label: string,\n name: string,\n handler: () => void,\n className = 'ad-icon-button',\n) {\n const el = document.createElement('button');\n el.type = 'button';\n el.className = className;\n el.title = label;\n el.setAttribute('aria-label', label);\n el.innerHTML = icon(name);\n el.addEventListener('click', () => {\n el.focus();\n handler();\n });\n return el;\n}\n","/** npm package version shown in the AnnieDrawing menu. Keep in sync with package.json. */\nexport const PACKAGE_VERSION = '0.3.1';\nexport const GITHUB_REPO_URL = 'https://github.com/Frontierz-AI/anniedrawing';\n","import type { Board } from '../board';\nimport type { Item, Point } from '../core/types';\nimport { button, icon } from './icons';\nimport { GITHUB_REPO_URL, PACKAGE_VERSION } from './version';\nimport { color as resolveColor, DEFAULT_FONT, fonts, fontSize, styleFor } from '../stage/paint';\nimport { pageId } from '../core/ids';\nimport { ANNIE_MIME } from '../porter/json';\n/** PNG, SVG, or AnnieDoc (`json`, saved as `.annie`). */\nexport type UiExportFormat = 'png' | 'svg' | 'json';\n/** Header controls. Pass `ui: false` to `createBoard` to omit all editor chrome. */\nexport interface UiOptions {\n /** AnnieDrawing control. Default `true`. */\n menu?: boolean;\n /**\n * Export control. Default `['png', 'svg']`. `false` hides it. Include `'json'` for AnnieDoc.\n * One format downloads on click; two or more open a menu.\n */\n export?: boolean | UiExportFormat[];\n /** Page chips, add-page, and All pages. Default true. */\n pages?: boolean;\n}\nconst defaultExportFormats: UiExportFormat[] = ['png', 'svg'];\nfunction exportFormats(value: UiOptions['export']): UiExportFormat[] {\n if (value === false) return [];\n if (!Array.isArray(value)) return [...defaultExportFormats];\n const seen = new Set<UiExportFormat>();\n const formats: UiExportFormat[] = [];\n for (const format of value) {\n if (format !== 'png' && format !== 'svg' && format !== 'json') continue;\n if (seen.has(format)) continue;\n seen.add(format);\n formats.push(format);\n }\n return formats;\n}\nconst tools = [\n ['select', 'Select', 'V'],\n ['hand', 'Hand', 'H'],\n ['rect', 'Rectangle', 'R'],\n ['ellipse', 'Ellipse', 'O'],\n ['diamond', 'Diamond', 'D'],\n ['connector', 'Arrow', 'A'],\n ['line', 'Line', 'L'],\n ['path', 'Draw', 'P'],\n ['text', 'Text', 'T'],\n ['note', 'Sticky note', 'N'],\n ['eraser', 'Eraser', 'E'],\n];\nconst palette = [\n ['ink', 'Ink'],\n ['paper', 'Paper'],\n ['teal', 'Frontierz green'],\n ['moss', 'Soft green'],\n ['coral', 'Orange'],\n ['violet', 'Lavender'],\n ['slate', 'Slate'],\n ['amber', 'Peach'],\n ['sky', 'Sky blue'],\n ['rose', 'Rose'],\n ['none', 'No fill'],\n];\n/** Narrow hosts, or a short tablet / phone-landscape host. */\nfunction phoneChrome(width: number, height: number) {\n return width <= 700 || (width <= 1023 && height <= 640);\n}\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className = '', text?: string) {\n const node = document.createElement(tag);\n node.className = className;\n if (text) node.textContent = text;\n return node;\n}\nfunction textButton(label: string, action: () => void, kind = 'ad-button') {\n const b = el('button', kind, label);\n b.type = 'button';\n b.addEventListener('click', () => {\n b.focus();\n action();\n });\n return b;\n}\nfunction field(label: string, input: HTMLElement) {\n const wrapper = el('label', 'ad-field');\n wrapper.append(el('span', 'ad-field-label', label), input);\n return wrapper;\n}\nfunction select(values: [string, string][], value: string, change: (value: string) => void) {\n const input = el('select');\n values.forEach(([v, text]) => {\n const o = el('option', '', text);\n o.value = v;\n input.append(o);\n });\n if (!values.some(([v]) => v === value)) {\n const custom = el('option', '', value);\n custom.value = value;\n input.append(custom);\n }\n input.value = value;\n input.onchange = () => change(input.value);\n return input;\n}\nfunction download(content: string | Blob, name: string, type: string) {\n const url = URL.createObjectURL(\n typeof content === 'string' ? new Blob([content], { type }) : content,\n );\n const link = el('a');\n link.href = url;\n link.download = name;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\nexport function mountUI(board: Board, options: UiOptions = {}): () => void {\n const ui = el('div', 'ad-ui');\n board.stage.root.append(ui);\n const unsubs: (() => void)[] = [];\n let activeDialog: HTMLDialogElement | undefined;\n function dialog(title: string) {\n closePopover();\n activeDialog?.close();\n const previous = document.activeElement as HTMLElement;\n const d = el('dialog', 'ad-dialog');\n const head = el('div', 'ad-dialog-head');\n const copy = el('div');\n copy.append(el('h2', '', title));\n head.append(\n copy,\n button('Close', 'close', () => d.close()),\n );\n d.append(head);\n d.addEventListener('click', (e) => {\n if (e.target === d) {\n const r = d.getBoundingClientRect();\n if (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom)\n d.close();\n }\n });\n d.addEventListener('close', () => {\n d.remove();\n if (activeDialog === d) activeDialog = undefined;\n if (!activeDialog) {\n refresh();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n }\n });\n ui.append(d);\n activeDialog = d;\n d.showModal();\n return d;\n }\n let activePopover: HTMLElement | undefined;\n let popoverTrigger: HTMLButtonElement | undefined;\n let pagePressTimer: ReturnType<typeof setTimeout> | undefined;\n function closePopover() {\n activePopover?.hidePopover();\n activePopover?.remove();\n activePopover = undefined;\n popoverTrigger?.setAttribute('aria-expanded', 'false');\n if (popoverTrigger) popoverTrigger.popoverTargetElement = null;\n popoverTrigger = undefined;\n }\n function popover(trigger: HTMLButtonElement | undefined, label: string) {\n if (trigger && popoverTrigger === trigger && activePopover?.matches(':popover-open')) {\n closePopover();\n return;\n }\n closePopover();\n const panel = el('div', 'ad-popover');\n panel.popover = 'auto';\n panel.setAttribute('role', 'group');\n panel.setAttribute('aria-label', label);\n const previous = document.activeElement as HTMLElement;\n if (trigger) {\n trigger.setAttribute('aria-expanded', 'true');\n trigger.popoverTargetElement = panel;\n trigger.popoverTargetAction = 'show';\n }\n activePopover = panel;\n popoverTrigger = trigger;\n panel.addEventListener('toggle', () => {\n if (activePopover === panel && !panel.matches(':popover-open'))\n trigger?.setAttribute('aria-expanded', 'false');\n });\n panel.addEventListener('keydown', (event) => {\n event.stopPropagation();\n if (event.key === 'Escape' || (event.key === 'Tab' && panel.popover === 'manual')) {\n if (event.key === 'Escape') event.preventDefault();\n closePopover();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n } else if (\n !(event.target instanceof HTMLInputElement) &&\n ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)\n ) {\n const items = popoverItems(panel);\n const current = items.indexOf(document.activeElement as HTMLElement);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? items.length - 1\n : (current +\n (event.key === 'ArrowDown' || event.key === 'ArrowRight' ? 1 : -1) +\n items.length) %\n items.length;\n event.preventDefault();\n items[next]?.focus();\n }\n });\n ui.append(panel);\n return panel;\n }\n function showPopover(\n panel: HTMLElement,\n trigger: HTMLButtonElement,\n alignTo: HTMLElement = trigger,\n ) {\n panel.showPopover();\n const anchor = alignTo.getBoundingClientRect(),\n bounds = board.stage.root.getBoundingClientRect();\n const mobile = phoneChrome(bounds.width, bounds.height),\n width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n const besideToolbar = trigger.closest('.ad-toolbar') && !mobile;\n const left = besideToolbar\n ? anchor.right + 12\n : trigger.closest('.ad-header') && anchor.left < bounds.left + bounds.width / 2\n ? anchor.left\n : anchor.right - width;\n const top = besideToolbar\n ? anchor.top\n : anchor.top > bounds.top + bounds.height / 2\n ? anchor.top - height - 10\n : anchor.bottom + 10;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(left, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(top, bounds.bottom - height - 12))}px`;\n popoverItems(panel)[0]?.focus();\n }\n function popoverItems(panel: HTMLElement) {\n return [...panel.querySelectorAll<HTMLElement>('button:not(:disabled), a[href]')];\n }\n function contextMenu(label: string, point: Point) {\n const panel = popover(undefined, label)!;\n // A native auto popover dismisses on the right-button release that opened it.\n panel.popover = 'manual';\n panel.classList.add('ad-context-menu');\n panel.setAttribute('role', 'menu');\n panel.tabIndex = -1;\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = textButton(\n label,\n () => {\n closePopover();\n board.focus();\n action();\n },\n 'ad-tool-option',\n );\n option.insertAdjacentHTML('afterbegin', icon(glyph));\n option.setAttribute('role', 'menuitem');\n option.disabled = board.readonly || disabled;\n if (glyph === 'trash') option.classList.add('ad-danger');\n panel.append(option);\n };\n const show = () => {\n panel.showPopover();\n const bounds = board.stage.root.getBoundingClientRect();\n const width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(point.x, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(point.y, bounds.bottom - height - 12))}px`;\n (panel.querySelector<HTMLButtonElement>('button:not(:disabled)') ?? panel).focus();\n };\n return { panel, add, show };\n }\n const hideOnResize = () => closePopover();\n const dismissContext = (event: PointerEvent) => {\n if (activePopover?.popover === 'manual' && !activePopover.contains(event.target as Node))\n closePopover();\n };\n window.addEventListener('resize', hideOnResize);\n window.addEventListener('pointerdown', dismissContext, true);\n unsubs.push(() => {\n window.removeEventListener('resize', hideOnResize);\n window.removeEventListener('pointerdown', dismissContext, true);\n });\n const showMenu = options.menu !== false;\n const formats = exportFormats(options.export);\n const header = el('header', 'ad-header');\n let brand: HTMLButtonElement | undefined;\n let drawingInput: HTMLInputElement | undefined;\n let exportButton: HTMLButtonElement | undefined;\n if (showMenu) {\n brand = button('Board menu', 'chevron', openMenu, 'ad-brand');\n brand.innerHTML =\n '<span class=\"ad-brand-mark\" aria-hidden=\"true\"><svg viewBox=\"0 0 40 40\"><path d=\"M9 29 20 8l11 21M14 22h12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"32\" cy=\"9\" r=\"2.5\" fill=\"currentColor\"/></svg></span><span class=\"ad-brand-name\">AnnieDrawing</span>' +\n icon('chevron');\n brand.setAttribute('aria-haspopup', 'true');\n brand.setAttribute('aria-expanded', 'false');\n drawingInput = el('input');\n drawingInput.type = 'file';\n drawingInput.accept = '.annie,.json,application/json';\n drawingInput.hidden = true;\n drawingInput.onchange = () => {\n const file = drawingInput?.files?.[0];\n if (drawingInput) drawingInput.value = '';\n if (file)\n void file\n .text()\n .then((value) => board.load(JSON.parse(value)))\n .catch(() => undefined);\n };\n header.append(brand);\n }\n if (formats.length) {\n const actions = el('div', 'ad-header-actions');\n exportButton = textButton('Export', openExport, 'ad-button ad-primary');\n exportButton.insertAdjacentHTML('afterbegin', icon('download'));\n if (formats.length > 1) {\n exportButton.setAttribute('aria-haspopup', 'true');\n exportButton.setAttribute('aria-expanded', 'false');\n }\n actions.append(exportButton);\n header.append(actions);\n }\n if (!showMenu) header.classList.add('ad-header-end');\n if (showMenu || formats.length) ui.append(header);\n if (drawingInput) ui.append(drawingInput);\n const toolbar = el('nav', 'ad-toolbar');\n toolbar.setAttribute('aria-label', 'Drawing tools');\n function toolButton(id: string, expanded = false) {\n const [, label, key] = tools.find((tool) => tool[0] === id)!;\n const b = button(\n label,\n id,\n () => {\n closePopover();\n board.setTool(id);\n board.focus();\n },\n expanded ? 'ad-tool-option' : 'ad-icon-button',\n );\n b.dataset.tool = id;\n b.setAttribute('aria-keyshortcuts', key);\n b.setAttribute('aria-pressed', String(board.tool === id));\n b.innerHTML += expanded ? `<span>${label}</span>` : `<span class=\"ad-tooltip\">${label}</span>`;\n if (board.readonly && id !== 'hand' && id !== 'select') b.disabled = true;\n return b;\n }\n const shapeKinds = ['rect', 'ellipse', 'diamond', 'line', 'connector'];\n const shapeButton = button('Shapes', 'shapes', () => {\n const panel = popover(shapeButton, 'Shapes');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n panel.append(...shapeKinds.map((id) => toolButton(id, true)));\n showPopover(panel, shapeButton);\n });\n shapeButton.setAttribute('aria-haspopup', 'true');\n shapeButton.setAttribute('aria-expanded', 'false');\n shapeButton.innerHTML +=\n '<span class=\"ad-tool-corner\"></span><span class=\"ad-tooltip\">Shapes</span>';\n const imageInput = el('input');\n imageInput.type = 'file';\n imageInput.accept = 'image/png,image/jpeg,image/webp,image/gif,image/avif';\n imageInput.hidden = true;\n imageInput.onchange = () => {\n if (imageInput.files?.[0]) void board.addImage(imageInput.files[0]).catch(() => undefined);\n imageInput.value = '';\n };\n const imageButton = button('Add image', 'image', () => {\n closePopover();\n imageInput.click();\n });\n imageButton.innerHTML += '<span class=\"ad-tooltip\">Add image</span>';\n imageButton.disabled = board.readonly;\n const hand = toolButton('hand');\n if (showMenu) hand.classList.add('ad-desktop-tool');\n toolbar.append(\n toolButton('select'),\n hand,\n toolButton('eraser'),\n el('div', 'ad-toolbar-divider'),\n shapeButton,\n toolButton('path'),\n toolButton('text'),\n toolButton('note'),\n imageButton,\n imageInput,\n );\n ui.append(toolbar);\n const styleDock = el('aside', 'ad-style-dock');\n styleDock.setAttribute('aria-label', 'Selection style');\n styleDock.hidden = true;\n const stylePanel = el('div', 'ad-style-panel');\n const deselect = button('Deselect', 'chevron', () => board.select([]));\n deselect.classList.add('ad-style-dismiss');\n styleDock.append(deselect, stylePanel);\n ui.append(styleDock);\n const footer = el('footer', 'ad-footer');\n const undo = button('Undo', 'undo', () => board.undo()),\n redo = button('Redo', 'redo', () => board.redo());\n undo.setAttribute('aria-keyshortcuts', 'Meta+Z Control+Z');\n redo.setAttribute('aria-keyshortcuts', 'Meta+Shift+Z Control+Shift+Z');\n const pagesBar = el('nav', 'ad-pages');\n pagesBar.setAttribute('aria-label', 'Pages');\n const pageTabs = el('div', 'ad-page-tabs');\n pageTabs.setAttribute('role', 'tablist');\n pageTabs.setAttribute('aria-label', 'Pages');\n const overflow = button('All pages', 'more', openPages);\n overflow.setAttribute('aria-haspopup', 'true');\n overflow.setAttribute('aria-expanded', 'false');\n overflow.hidden = true;\n const newPage = button('Add page', 'plus', addPage);\n newPage.disabled = board.readonly;\n pagesBar.append(pageTabs, overflow, newPage);\n let pageState = '';\n function pageContext(id: string, name: string, point: Point) {\n const menu = contextMenu('Page actions', point);\n menu.add('Rename page', 'text', () => renamePage(id, name));\n menu.add(\n 'Delete page',\n 'trash',\n () => {\n board.apply([{ op: 'page.remove', id }], { origin: 'user', label: 'Delete page' });\n },\n board.read().pages.length === 1,\n );\n menu.show();\n }\n function pageButton(id: string, name: string, tab = false) {\n const pick = textButton(\n name,\n () => {\n closePopover();\n board.setPage(id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n },\n tab ? 'ad-page-tab' : 'ad-tool-option',\n );\n pick.title = name;\n pick.dataset.pageId = id;\n let held = false;\n let start: Point;\n pick.addEventListener('pointerdown', (event) => {\n held = false;\n if (event.pointerType !== 'touch') return;\n start = { x: event.clientX, y: event.clientY };\n clearTimeout(pagePressTimer);\n pagePressTimer = setTimeout(() => {\n held = true;\n pageContext(id, name, start);\n }, 500);\n });\n pick.addEventListener('pointermove', (event) => {\n if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > 10)\n clearTimeout(pagePressTimer);\n });\n for (const type of ['pointerup', 'pointercancel'])\n pick.addEventListener(type, () => clearTimeout(pagePressTimer));\n pick.addEventListener(\n 'click',\n (event) => {\n if (held) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n },\n true,\n );\n if (tab) {\n pick.setAttribute('role', 'tab');\n pick.setAttribute('aria-selected', String(board.pageId === id));\n pick.tabIndex = board.pageId === id ? 0 : -1;\n } else pick.setAttribute('aria-current', String(board.pageId === id));\n pick.addEventListener('contextmenu', (event) => {\n event.preventDefault();\n pageContext(id, name, { x: event.clientX, y: event.clientY });\n });\n pick.addEventListener('keydown', (event) => {\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n event.preventDefault();\n const bounds = pick.getBoundingClientRect();\n pageContext(id, name, { x: bounds.left, y: bounds.top });\n } else if (tab && ['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n const pages = board.read().pages;\n const index = pages.findIndex((page) => page.id === id);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? pages.length - 1\n : (index + (event.key === 'ArrowRight' ? 1 : -1) + pages.length) % pages.length;\n closePopover();\n board.setPage(pages[next].id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n }\n });\n return pick;\n }\n let fittingPages = false;\n function fitPageTabs() {\n if (fittingPages) return;\n fittingPages = true;\n const probe = el('div', 'ad-page-tabs');\n try {\n const tabs = [...pageTabs.querySelectorAll<HTMLButtonElement>('button')];\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;width:max-content';\n const samples = tabs.map((tab) => {\n const sample = tab.cloneNode(true) as HTMLButtonElement;\n sample.hidden = false;\n sample.style.maxWidth = '';\n return sample;\n });\n const overflowSample = overflow.cloneNode(true) as HTMLButtonElement;\n overflowSample.hidden = false;\n probe.append(...samples, overflowSample);\n ui.append(probe);\n const widths = samples.map((sample) => sample.getBoundingClientRect().width);\n const overflowWidth = overflowSample.offsetWidth;\n probe.remove();\n const needed = widths.reduce((sum, width) => sum + width + 4, 0) + newPage.offsetWidth + 14;\n const room =\n pagesBar.offsetTop === footerRight.offsetTop\n ? footer.clientWidth - footerRight.offsetWidth - 16\n : pagesBar.clientWidth;\n const cap = Math.min(room, 520);\n const hideOverflow = needed <= cap;\n const nextHidden = tabs.map(() => false);\n const nextMax = tabs.map(() => '');\n if (!hideOverflow) {\n let remaining = Math.max(40, cap - newPage.offsetWidth - 14 - overflowWidth - 4);\n const selected = tabs.findIndex((tab) => tab.getAttribute('aria-selected') === 'true');\n for (const index of [\n selected,\n ...tabs.map((_, index) => index).filter((index) => index !== selected),\n ]) {\n if (index < 0) continue;\n if (index === selected) {\n nextMax[index] = `${remaining}px`;\n remaining -= Math.min(remaining, widths[index]) + 4;\n } else {\n nextHidden[index] = widths[index] > remaining;\n if (!nextHidden[index]) remaining -= widths[index] + 4;\n }\n }\n }\n overflow.hidden = hideOverflow;\n tabs.forEach((tab, index) => {\n tab.hidden = nextHidden[index];\n tab.style.maxWidth = nextMax[index];\n });\n } finally {\n probe.remove();\n fittingPages = false;\n }\n }\n function renderPages() {\n if (options.pages === false) return;\n const pages = board.read().pages;\n const state = JSON.stringify([board.pageId, pages.map(({ id, name }) => [id, name])]);\n if (state === pageState) return;\n pageState = state;\n pageTabs.replaceChildren(...pages.map((page) => pageButton(page.id, page.name, true)));\n fitPageTabs();\n }\n const pagesObserver = new ResizeObserver(fitPageTabs);\n if (options.pages !== false) {\n pagesObserver.observe(ui);\n unsubs.push(() => pagesObserver.disconnect());\n }\n function addPage() {\n closePopover();\n const id = pageId();\n const pages = board.read().pages;\n let number = pages.length + 1;\n while (pages.some((page) => page.name === `Page ${number}`)) number++;\n const result = board.apply(\n [{ op: 'page.add', page: { id, name: `Page ${number}`, items: [] } }],\n { origin: 'user', label: 'Add page' },\n );\n if (result.ok) board.setPage(id);\n }\n function openPages() {\n const panel = popover(overflow, 'All pages');\n if (!panel) return;\n panel.classList.add('ad-pages-popover');\n for (const page of board.read().pages) {\n const row = el('div', 'ad-page-row');\n row.append(pageButton(page.id, page.name));\n const actions = button(`Actions for ${page.name}`, 'more', () => {\n const bounds = actions.getBoundingClientRect();\n pageContext(page.id, page.name, { x: bounds.left, y: bounds.top });\n });\n row.append(actions);\n panel.append(row);\n }\n showPopover(panel, overflow);\n panel.querySelector<HTMLElement>('[aria-current=\"true\"]')?.scrollIntoView({ block: 'nearest' });\n }\n const footerRight = el('div', 'ad-footer-right');\n const zoom = el('div', 'ad-zoom');\n const percentage = textButton(\n '100%',\n () => {\n const panel = popover(percentage, 'Zoom controls');\n if (!panel) return;\n const row = el('div', 'ad-zoom-controls');\n row.append(\n button('Zoom out', 'minus', () => (board.view.zoom /= 1.2)),\n textButton('100%', () => (board.view.zoom = 1), 'ad-zoom-value'),\n button('Zoom in', 'plus', () => (board.view.zoom *= 1.2)),\n );\n panel.append(row);\n showPopover(panel, percentage, fitButton);\n },\n 'ad-zoom-value',\n );\n percentage.setAttribute('aria-label', 'Zoom controls');\n percentage.setAttribute('aria-haspopup', 'true');\n percentage.setAttribute('aria-expanded', 'false');\n const fitButton = button('Fit drawing', 'fit', () => board.view.fit());\n zoom.append(percentage, fitButton, undo, redo);\n footerRight.append(zoom);\n if (options.pages === false) footer.append(footerRight);\n else footer.append(pagesBar, footerRight);\n ui.append(footer);\n function renamePage(id: string, name: string) {\n if (board.readonly) return;\n const d = dialog('Name this page');\n const input = el('input');\n input.value = name;\n input.maxLength = 100;\n d.append(\n field('Page name', input),\n textButton(\n 'Save name',\n () => {\n if (input.value.trim())\n board.apply([{ op: 'page.set', id, patch: { name: input.value.trim() } }], {\n origin: 'user',\n label: 'Rename page',\n });\n d.close();\n },\n 'ad-button ad-primary',\n ),\n );\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n d.addEventListener(\n 'close',\n () => {\n const tab = pageTabs.querySelector<HTMLButtonElement>(`[data-page-id=\"${CSS.escape(id)}\"]`);\n if (tab && !tab.hidden) tab.focus();\n else if (!overflow.hidden) overflow.focus();\n },\n { once: true },\n );\n input.focus();\n input.select();\n }\n function hrefAction(kind: string) {\n return kind === 'video' ? 'Edit Video URL' : 'Edit URL';\n }\n function editHref(id: string) {\n if (board.readonly || board.isLocked(id)) return;\n const item = board.get(id);\n if (!item || (item.kind !== 'video' && item.kind !== 'link')) return;\n const video = item.kind === 'video';\n const d = dialog(video ? 'Edit video URL' : 'Edit URL');\n const input = el('input');\n input.type = 'text';\n input.inputMode = 'url';\n input.setAttribute('autocomplete', 'url');\n input.spellcheck = false;\n input.maxLength = 2000;\n input.value = item.href ?? '';\n input.setAttribute('aria-label', video ? 'Video URL' : 'URL');\n const error = el('p', 'ad-dialog-error');\n error.setAttribute('role', 'alert');\n error.hidden = true;\n const save = textButton(\n video ? 'Save video URL' : 'Save URL',\n () => {\n void (async () => {\n save.disabled = true;\n const result = await board.setHref(id, input.value);\n save.disabled = false;\n if (!result.ok) {\n const code = result.errors[0]?.code;\n error.textContent =\n code === 'LOCKED' || code === 'READONLY'\n ? (result.errors[0]?.message ?? 'This cannot be edited.')\n : video\n ? 'Use a YouTube or Vimeo URL.'\n : 'Use an http(s) URL.';\n error.hidden = false;\n input.setAttribute('aria-invalid', 'true');\n input.focus();\n return;\n }\n d.close();\n })();\n },\n 'ad-button ad-primary',\n );\n d.append(field(video ? 'Video URL' : 'URL', input), error, save);\n input.addEventListener('input', () => {\n error.hidden = true;\n input.removeAttribute('aria-invalid');\n });\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n input.focus();\n input.select();\n }\n let styleSelection = '';\n function renderStyle() {\n const locked = board.selection.some((id) => board.isLocked(id));\n if (board.tool !== 'select') {\n if (popoverTrigger && styleDock.contains(popoverTrigger)) closePopover();\n styleDock.hidden = true;\n return;\n }\n if (\n activeDialog ||\n (!locked &&\n document.activeElement instanceof HTMLInputElement &&\n document.activeElement.type === 'range' &&\n (styleDock.contains(document.activeElement) ||\n activePopover?.contains(document.activeElement)))\n )\n return;\n const focused = styleDock.contains(document.activeElement)\n ? (document.activeElement as HTMLElement)\n : undefined;\n const stylePopup =\n popoverTrigger && styleDock.contains(popoverTrigger)\n ? {\n label: popoverTrigger.getAttribute('aria-label'),\n focused: activePopover?.contains(document.activeElement),\n }\n : undefined;\n const focusLabel =\n focused?.getAttribute('aria-label') ?? (stylePopup?.focused ? stylePopup.label : undefined);\n const focusField = focused?.closest('label')?.querySelector('.ad-field-label')?.textContent;\n if (stylePopup) closePopover();\n const items = board.selection.map((id) => board.get(id)!).filter(Boolean);\n const selectedKey = items.map((item) => item.id).join(',');\n if (styleSelection !== selectedKey) {\n closePopover();\n }\n styleSelection = selectedKey;\n stylePanel.replaceChildren();\n styleDock.hidden = items.length === 0;\n if (!items.length) {\n if (stylePopup?.focused) board.focus();\n return;\n }\n const item = items[0],\n single = items.length === 1;\n const fillable = items.every((i) => ['rect', 'ellipse', 'diamond', 'note'].includes(i.kind));\n const stroked = items.every(\n (i) => !['image', 'html', 'video', 'link', 'group', 'text', 'note'].includes(i.kind),\n );\n const textOnly = items.every((i) => i.kind === 'text');\n const hasText = items.every(\n (i) => !['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(i.kind),\n );\n const colorControls = el('div', 'ad-color-controls');\n function colorControl(label: string, key: 'fill' | 'stroke') {\n const current =\n item.style?.[key] ?? (key === 'fill' ? (item.kind === 'note' ? 'moss' : 'none') : 'ink');\n const trigger = textButton(\n label,\n () => {\n const panel = popover(trigger, `${label} color`);\n if (!panel) return;\n panel.classList.add('ad-color-popover');\n for (const [token, name] of palette) {\n const b = el('button', `ad-swatch ${token === 'none' ? 'ad-swatch-none' : ''}`);\n b.type = 'button';\n b.style.setProperty('--swatch', resolveColor(token, board.stage.resolvedTheme));\n b.setAttribute('aria-label', `${label}: ${name}`);\n b.title = name;\n b.setAttribute('aria-pressed', String(current === token));\n b.onclick = () => {\n closePopover();\n board.defaultStyle[key] = token;\n board.updateSelection({ style: { [key]: token } });\n stylePanel.querySelector<HTMLButtonElement>(`[aria-label=\"${label}\"]`)?.focus();\n };\n panel.append(b);\n }\n showPopover(panel, trigger);\n },\n 'ad-color-control',\n );\n trigger.setAttribute('aria-label', label);\n trigger.setAttribute('aria-haspopup', 'true');\n trigger.setAttribute('aria-expanded', 'false');\n const swatch = el('span', `ad-color-preview ${current === 'none' ? 'ad-swatch-none' : ''}`);\n swatch.style.setProperty('--swatch', resolveColor(current, board.stage.resolvedTheme));\n trigger.prepend(swatch);\n colorControls.append(trigger);\n }\n if (fillable) colorControl('Fill', 'fill');\n if (stroked) colorControl('Line', 'stroke');\n if (textOnly) colorControl('Color', 'stroke');\n const opacityButton = textButton(\n 'Opacity',\n () => {\n const panel = popover(opacityButton, 'Opacity controls');\n if (!panel) return;\n panel.classList.add('ad-opacity-popover');\n const input = el('input');\n input.type = 'range';\n input.setAttribute('aria-label', 'Opacity');\n input.min = '0';\n input.max = '100';\n input.value = String(Math.round((board.get(item.id)?.style?.opacity ?? 1) * 100));\n const value = el('output', '', `${input.value}%`);\n const label = field('Opacity', input);\n label.querySelector('.ad-field-label')!.append(value);\n let first = true;\n input.oninput = () => {\n value.textContent = `${input.value}%`;\n board.apply(\n items.map(({ id }) => ({\n op: 'set',\n id,\n patch: { style: { opacity: Number(input.value) / 100 } },\n })),\n { origin: 'user', label: 'Change opacity', merge: !first },\n );\n first = false;\n };\n input.onchange = () => {\n first = true;\n };\n panel.append(label);\n showPopover(panel, opacityButton);\n input.focus();\n },\n 'ad-color-control',\n );\n opacityButton.insertAdjacentHTML('afterbegin', icon('opacity'));\n opacityButton.setAttribute('aria-label', 'Opacity');\n opacityButton.setAttribute('aria-haspopup', 'true');\n opacityButton.setAttribute('aria-expanded', 'false');\n if (items.every((item) => item.kind !== 'group')) colorControls.append(opacityButton);\n if (colorControls.childElementCount) stylePanel.append(colorControls);\n const updateText = (patch: Partial<NonNullable<Item['text']>>) =>\n board.apply(\n items.map((item) => ({\n op: 'set',\n id: item.id,\n patch: { text: { value: item.text?.value ?? '', ...patch } },\n })),\n { origin: 'user', label: 'Text style' },\n );\n function styleRow(label: string) {\n const row = el('div', 'ad-style-row');\n const group = el('div', 'ad-segments');\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', label);\n row.append(el('span', 'ad-style-label', label), group);\n stylePanel.append(row);\n return group;\n }\n function choices(\n group: HTMLElement,\n values: [string, string, string][],\n current: (item: Item) => string,\n change: (value: string) => void,\n ) {\n return values.map(([value, label, content]) => {\n const b = textButton(label, () => change(value), 'ad-segment');\n b.setAttribute('aria-label', label);\n b.title = label;\n b.setAttribute('aria-pressed', String(items.every((item) => current(item) === value)));\n b.innerHTML = content;\n group.append(b);\n return b;\n });\n }\n function lineIcon(width: number, dash = '') {\n return `<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3 12h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"${width}\" stroke-linecap=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/></svg>`;\n }\n if (hasText) {\n choices(\n styleRow('Text'),\n [\n ['s', 'Text size: Small', 'S'],\n ['m', 'Text size: Medium', 'M'],\n ['l', 'Text size: Large', 'L'],\n ['xl', 'Text size: Extra large', 'XL'],\n ],\n (item) => ({ 14: 's', 18: 'm', 26: 'l', 36: 'xl' })[fontSize(item.text)] ?? '',\n (value) => updateText({ size: value as 'm' }),\n );\n choices(\n styleRow('Align'),\n [\n ['start', 'Align text left', icon('alignLeft')],\n ['center', 'Align text center', icon('alignCenter')],\n ['end', 'Align text right', icon('alignRight')],\n ],\n (item) => item.text?.align ?? (item.kind === 'text' ? 'start' : 'center'),\n (value) => updateText({ align: value as 'start' }),\n );\n const fontChoices: [keyof typeof fonts, string, string][] = [\n ['sans', 'Font: Friendly', 'Aa'],\n ['serif', 'Font: Serif', 'Aa'],\n ['mono', 'Font: Mono', 'Aa'],\n ['hand', 'Font: Handwritten', 'Aa'],\n ];\n choices(\n styleRow('Font'),\n fontChoices,\n (item) => item.text?.font ?? DEFAULT_FONT,\n (value) => updateText({ font: value as 'sans' }),\n ).forEach((button, index) => {\n button.style.fontFamily = fonts[fontChoices[index][0]];\n });\n }\n if (stroked) {\n choices(\n styleRow('Line'),\n [\n ['1', 'Line: Fine', lineIcon(1)],\n ['2', 'Line: Regular', lineIcon(2)],\n ['4', 'Line: Bold', lineIcon(4)],\n ['8', 'Line: Extra bold', lineIcon(6)],\n ],\n (item) => String(styleFor(item, board.stage.resolvedTheme).strokeWidth),\n (value) => board.updateSelection({ style: { strokeWidth: Number(value) } }),\n );\n if (items.every((item) => item.kind !== 'path' || item.closed)) {\n choices(\n styleRow('Pattern'),\n [\n ['solid', 'Pattern: Solid', lineIcon(2)],\n ['dashed', 'Pattern: Dashed', lineIcon(2, '5 4')],\n ['dotted', 'Pattern: Dotted', lineIcon(2, '1 5')],\n ],\n (item) => item.style?.dash ?? 'solid',\n (value) => board.updateSelection({ style: { dash: value as 'solid' } }),\n );\n }\n }\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Route',\n select(\n [\n ['straight', 'Straight'],\n ['elbow', 'Elbow'],\n ['curve', 'Curve'],\n ],\n item.route ?? 'elbow',\n (v) => board.updateSelection({ route: v as 'elbow' }),\n ),\n ),\n );\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Arrowhead',\n select(\n [\n ['arrow', 'Arrow'],\n ['dot', 'Dot'],\n ['none', 'None'],\n ],\n item.heads?.end ?? 'arrow',\n (value) => board.updateSelection({ heads: { ...item.heads, end: value as 'arrow' } }),\n ),\n ),\n );\n if (single && (item.kind === 'video' || item.kind === 'link')) {\n const label = hrefAction(item.kind);\n const edit = textButton(label, () => editHref(item.id), 'ad-button ad-href-edit');\n edit.setAttribute('aria-label', label);\n stylePanel.append(edit);\n }\n const lock = button(\n locked ? 'Unlock selection' : 'Lock selection',\n locked ? 'lock' : 'unlock',\n () => board.updateSelection({ locked: !locked }),\n );\n lock.setAttribute('aria-pressed', String(locked));\n const row = el('div', 'ad-selection-actions');\n row.append(\n button('Duplicate selection', 'copy', () => board.duplicate()),\n button('More arrangement options', 'align', openArrange),\n lock,\n button('Delete selection', 'trash', () => board.deleteSelection()),\n );\n stylePanel.append(row);\n if (board.readonly || locked)\n stylePanel\n .querySelectorAll('button,input,select')\n .forEach(\n (e) =>\n ((e as HTMLButtonElement).disabled = e !== deselect && (e !== lock || board.readonly)),\n );\n if (focusLabel === 'Unlock selection' || focusLabel === 'Lock selection') lock.focus();\n else if (focusLabel === 'Deselect') deselect.focus();\n else if (focusLabel)\n stylePanel.querySelector<HTMLElement>(`[aria-label=\"${CSS.escape(focusLabel)}\"]`)?.focus();\n else if (focusField)\n [...stylePanel.querySelectorAll('label')]\n .find((label) => label.querySelector('.ad-field-label')?.textContent === focusField)\n ?.querySelector<HTMLElement>('input,select')\n ?.focus();\n if (focused || stylePopup?.focused)\n if (locked && !board.readonly && !styleDock.contains(document.activeElement)) lock.focus();\n }\n function openArrange() {\n const d = dialog('Give it a little order');\n const actions = el('div', 'ad-action-grid');\n const item = board.selection.length === 1 ? board.get(board.selection[0]) : undefined;\n if (item) {\n actions.append(\n textButton('Duplicate', () => {\n board.duplicate();\n d.close();\n }),\n textButton('Delete', () => {\n board.deleteSelection();\n d.close();\n }),\n );\n }\n if (board.selection.length > 1)\n for (const mode of [\n 'left',\n 'center',\n 'right',\n 'top',\n 'middle',\n 'bottom',\n 'horizontal',\n 'vertical',\n ] as const)\n actions.append(\n textButton(\n mode === 'horizontal' || mode === 'vertical' ? `Distribute ${mode}` : `Align ${mode}`,\n () => {\n board.align(mode);\n d.close();\n },\n ),\n );\n if (board.selection.length > 1)\n actions.append(\n textButton('Group', () => {\n board.group();\n d.close();\n }),\n );\n if (board.selection.some((id) => board.get(id)?.kind === 'group'))\n actions.append(\n textButton('Ungroup', () => {\n board.ungroup();\n d.close();\n }),\n );\n actions.append(\n textButton('Bring to front', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'front' })),\n { origin: 'user', label: 'Bring to front' },\n );\n d.close();\n }),\n textButton('Send to back', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'back' })),\n { origin: 'user', label: 'Send to back' },\n );\n d.close();\n }),\n );\n if (board.readonly)\n actions.querySelectorAll('button').forEach((action) => (action.disabled = true));\n d.append(actions);\n }\n function saveExport(format: UiExportFormat) {\n void board\n .export(format, {\n scope: 'page',\n padding: 40,\n background: true,\n ...(format === 'png' ? { scale: 2 } : {}),\n })\n .then((content) => {\n const name =\n board\n .read()\n .meta.title.replace(/[^a-z0-9 _-]/gi, '')\n .trim() || 'drawing';\n download(\n content,\n `${name}.${format === 'json' ? 'annie' : format}`,\n format === 'json' ? ANNIE_MIME : format === 'svg' ? 'image/svg+xml' : 'image/png',\n );\n })\n .catch(() => undefined);\n }\n function openExport() {\n if (formats.length === 1) {\n saveExport(formats[0]);\n return;\n }\n if (!exportButton) return;\n const panel = popover(exportButton, 'Export');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const choices: Record<UiExportFormat, [string, string]> = {\n png: ['PNG Image', 'image'],\n svg: ['SVG Image', 'image'],\n json: ['AnnieDoc format', 'code'],\n };\n for (const format of formats) {\n const [label, glyph] = choices[format];\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n saveExport(format);\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n panel.append(option);\n }\n showPopover(panel, exportButton);\n }\n function openMenu() {\n if (!brand) return;\n const panel = popover(brand, 'Board menu');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n action();\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n option.disabled = disabled;\n panel.append(option);\n };\n add('Open a drawing', 'upload', () => drawingInput?.click(), board.readonly);\n if (phoneChrome(board.stage.root.clientWidth, board.stage.root.clientHeight)) {\n add('Hand', 'hand', () => {\n board.setTool('hand');\n board.focus();\n });\n }\n add(board.grid ? 'Hide grid' : 'Show grid', 'grid', () => board.setGrid(!board.grid));\n const dark = board.stage.resolvedTheme === 'dark';\n add(dark ? 'Light appearance' : 'Dark appearance', dark ? 'sun' : 'moon', () =>\n board.setTheme(dark ? 'light' : 'dark'),\n );\n add('Documentation', 'book', () => {\n window.open('./docs/index.html', '_blank', 'noopener');\n });\n const github = el('a', 'ad-tool-option');\n github.href = GITHUB_REPO_URL;\n github.target = '_blank';\n github.rel = 'noopener noreferrer';\n github.title = 'GitHub';\n github.innerHTML = `${icon('github')}<span>GitHub</span>`;\n github.addEventListener('click', () => closePopover());\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n panel.append(github, separator, el('p', 'ad-menu-version', `v${PACKAGE_VERSION}`));\n showPopover(panel, brand);\n }\n function refresh() {\n undo.disabled = !board.canUndo;\n redo.disabled = !board.canRedo;\n renderPages();\n renderStyle();\n }\n const context = (event: Event) => {\n const { x, y, id } = (event as CustomEvent<Point & { id?: string }>).detail;\n const item = id ? board.get(id) : undefined;\n if (!item) {\n closePopover();\n return;\n }\n const bounds = board.stage.root.getBoundingClientRect();\n const menu = contextMenu('Element actions', { x: bounds.left + x, y: bounds.top + y });\n const locked = board.isLocked(item.id);\n if (item.kind === 'video' || item.kind === 'link')\n menu.add(hrefAction(item.kind), 'link', () => editHref(item.id), locked);\n if (!['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(item.kind))\n menu.add('Edit text', 'text', () => board.editText(item.id), locked);\n const order = (to: 'front' | 'back') =>\n board.apply([{ op: 'order', id: item.id, to }], {\n origin: 'user',\n label: to === 'front' ? 'Bring to front' : 'Send to back',\n });\n menu.add('Bring to front', 'front', () => order('front'), locked);\n menu.add('Send to back', 'back', () => order('back'), locked);\n menu.add(\n 'Duplicate',\n 'copy',\n () => {\n board.select([item.id]);\n board.duplicate();\n },\n locked,\n );\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n menu.panel.append(separator);\n menu.add(\n 'Delete',\n 'trash',\n () => {\n board.select([item.id]);\n board.deleteSelection();\n },\n locked,\n );\n menu.show();\n };\n board.host.addEventListener('ad-context', context);\n unsubs.push(\n board.on('change', refresh),\n board.on('select', () => {\n renderStyle();\n }),\n board.on('page', refresh),\n board.on('view', (state) => {\n if (activePopover?.popover === 'manual') closePopover();\n percentage.textContent = `${Math.round(state.zoom * 100)}%`;\n }),\n board.on('tool', (id) => {\n for (const b of ui.querySelectorAll<HTMLElement>('[data-tool]'))\n b.setAttribute('aria-pressed', String(id === b.dataset.tool));\n shapeButton.setAttribute('aria-pressed', String(shapeKinds.includes(id)));\n board.stage.root.dataset.adTool = id;\n renderStyle();\n }),\n );\n refresh();\n return () => {\n clearTimeout(pagePressTimer);\n closePopover();\n unsubs.forEach((fn) => fn());\n activeDialog?.close();\n board.host.removeEventListener('ad-context', context);\n ui.remove();\n };\n}\n"],"x_google_ignoreList":[0],"mappings":"6CAAA,IAAM,GAAG,GAAG,KAAK,EAAE,EAAE,KAAU,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC,IAAM,IAAI,GAAG,KAAK,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAM,KAAF,GAAQ,CAAmC,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAuC,SAAS,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAA4C,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,OAA7U,SAAW,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,CAA+S,CAAE,EAA7H,SAAW,GAAG,OAAO,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,CAAqF,CAAE,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAa,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,CAAxB,EAAE,EAAE,EAAE,EAAqB,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,SAAS,EAAG,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,IAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAI,EAAF,EAAI,IAAI,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,EAAI,EAAF,EAAI,IAAI,OAAO,CAAC,CAAC,SAAS,EAAG,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAI,IAAF,IAAQ,EAAE,EAAE,EAAE,EAAI,IAAF,IAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,OAAW,IAAJ,QAAiB,IAAT,EAAW,GAAM,IAAJ,EAAO,KAAK,IAAI,EAAE,GAAG,CAAC,CAAiI,SAAS,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,EAAE,GAAG,UAAU,EAAE,GAAG,SAAS,EAAE,GAAG,iBAAiB,GAAE,EAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,GAAE,GAAI,GAAG,IAAI,GAAE,EAAG,OAAO,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,IAAI,GAAE,EAAG,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,GAAc,IAAX,EAAE,QAAY,GAAG,EAAE,MAAM,GAAG,IAAuI,EAAnI,EAAE,EAAE,EAAE,OAAO,GAAG,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAA/b,SAAY,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,IAAI,OAAA,CAAQ,EAAE,KAAK,IAAI,EAAE,EAAE,SAAS,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,SAAS,CAAkU,CAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,GAAG,SAAS,GAAK,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAE,EAAG,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,IAAI,CAAC,IAAI,SAAS,GAAG,EAAE,IAAI,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,OAAW,IAAT,IAAa,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,EAAG,EAAE,GAAmB,EAAM,OAAJ,GAAU,EAAE,EAAE,GAA9B,EAAG,EAAE,GAAG,IAAI,GAAwB,EAAN,CAAS,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,mBAAmB,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,GAAE,EAAY,MAAI,GAAE,EAAG,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAa,EAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,EAAE,EAAE,OAAO,GAAG,MAAM,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,GAAE,GAAG,GAAE,GAAG,GAAc,IAAX,EAAE,QAAe,IAAE,IAAG,GAAI,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,GAAc,IAAX,EAAE,SAAa,EAAE,GAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,KAAK,GAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,IAAI,EAAE,EAAhrG,SAAW,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,GAAG,CAAipG,CAAE,EAAE,EAAE,OAAO,GAAG,SAAS,GAAG,GAAc,IAAX,EAAE,OAAW,GAAE,KAAK,GAAG,EAAE,GAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,GAAE,QAAQ,EAAG,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,GAAE,EAAE,UAAU,GAAE,CAAC,IAAM,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,GAAG,OAAU,MAAH,GAAS,GAAG,CAAC,CAAwvB,SAAS,EAAE,EAAE,EAAE,CAAC,GAAG,OAAO,EAAjxB,SAAW,EAAE,EAAE,CAAC,GAAG,IAAI,WAAW,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,GAAE,GAAI,EAAE,GAAc,IAAX,EAAE,OAAW,MAAM,GAAG,IAAI,EAAE,IAAU,KAAL,EAAE,GAAO,EAAE,MAAM,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAA,EAAM,EAAE,EAAE,EAAE,EAAE,SAAS,EAAvpH,MAA8pH,CAAC,EAAE,EAAE,IAAI,GAAc,IAAX,EAAE,OAAW,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,GAAE,GAAI,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,CAAY,IAAX,EAAE,SAAa,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,OAAO,IAAI,GAAG,SAAS,EAAE,cAAc,IAAI,GAAE,EAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,MAAM,GAAG,SAAS,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,GAAG,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,GAAE,CAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,GAAlpI,GAAupI,OAAO,EAAE,GAAG,SAAS,EAAE,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,IAAI,QAAQ,CAAC,EAAE,GAAG,CAAC,CAA6B,CAAE,EAAE,GAAG,EAAE,CCInzI,IAAa,EAAS,6BACT,EAAQ,CACnB,KAAM,6DACN,MAAO,iBACP,KAAM,iDACN,KAAM,yCAGR,SAAgB,EAAW,GACzB,OAAO,EAAM,GAAA,OACf,CACA,IAAM,EAAgC,CACpC,IAAK,UACL,MAAO,UACP,MAAO,UACP,MAAO,UACP,KAAM,UACN,KAAM,UACN,IAAK,UACL,OAAQ,UACR,KAAM,UACN,MAAO,WAEH,EAA+B,IAChC,EACH,IAAK,UACL,MAAO,UACP,MAAO,WAET,SAAgB,EAAM,EAAQ,MAAO,EAA0B,SAC7D,OAAkB,SAAV,EAAmB,EAAO,GAAO,IAAU,CACrD,CACA,SAAS,EAAI,GAaX,GAHA,EAAQ,CARN,MAAO,UACP,MAAO,UACP,IAAK,UACL,KAAM,UACN,MAAO,UACP,OAAQ,UACR,YAAa,aAED,EAAM,gBAAkB,EAClC,mBAAmB,KAAK,KAC1B,EAAQ,IAAI,IAAI,EAAM,MAAM,IAAI,IAAK,GAAY,EAAU,GAAS,KAAK,OACvE,8BAA8B,KAAK,GACrC,MAAO,CAAC,EAAG,EAAG,GACX,IAAK,GAAU,SAAS,EAAM,MAAM,EAAO,EAAQ,GAAI,KACvD,OAAwB,IAAjB,EAAM,OAAe,SAAS,EAAM,MAAM,EAAG,GAAI,IAAM,IAAM,GACzE,IAAK,YAAY,KAAK,GAAQ,OAC9B,MAAM,EAAW,EAAM,MAAM,aAC7B,OAAK,GAAY,EAAS,OAAS,OAAnC,EACO,EACJ,MAAM,EAAG,GACT,IAAK,GAAY,WAAW,IAAY,EAAQ,SAAS,KAAO,KAAO,IACvE,YACiB,IAAhB,EAAS,GACL,EACA,WAAW,EAAS,KAAO,EAAS,GAAG,SAAS,KAAO,IAAM,GAEvE,CACA,SAAS,EAAU,GACjB,OAAO,EACJ,MAAM,EAAG,GACT,IAAK,IACJ,MAAM,EAAQ,EAAU,IACxB,OAAO,GAAS,OAAU,EAAQ,QAAU,EAAQ,MAAS,QAAU,MAExE,OAAA,CAAQ,EAAK,EAAS,IAAU,EAAM,EAAU,CAAC,MAAQ,MAAQ,OAAQ,GAAQ,EACtF,CAEA,SAAgB,EAAW,EAAY,GACrC,GAAkB,SAAd,EAAK,KAAiB,OAAO,EAAM,EAAK,OAAO,QAAU,MAAO,GACpE,MAAM,EAAM,EAAM,MAAO,GACvB,EAAQ,EAAS,EAAM,GACzB,GAAI,CAAC,YAAa,QAAQ,SAAS,EAAK,OAA4B,UAAnB,EAAM,SAAsB,OAAO,EACpF,MAAM,EAAO,EAAI,EAAM,MACvB,IAAK,EAAM,OAAO,EAClB,MAAM,EAAQ,EAAI,EAAM,QAAS,IAC3B,EAAa,EACjB,EAAK,MAAM,EAAG,GAAG,IAAA,CAAK,EAAS,IAAU,EAAU,EAAK,GAAK,EAAM,IAAU,EAAI,EAAK,MAElF,EAAY,IAChB,MAAM,EAAa,EAAU,EAAI,IACjC,OAAQ,KAAK,IAAI,EAAY,GAAc,MAAS,KAAK,IAAI,EAAY,GAAc,MAEzF,IAAK,MAAM,IAAa,CAAC,EAAK,EAAM,MAAiB,SAAV,EAAmB,QAAU,SACtE,GAAI,EAAS,IAAc,IAAK,OAAO,EACzC,OAAO,EAAS,YAAc,EAAS,WAAa,UAAY,SAClE,CACA,SAAgB,EAAS,GACvB,MAA6B,iBAAf,GAAM,KAChB,EAAK,KACL,CAAE,EAAG,GAAI,EAAG,GAAI,EAAG,GAAI,GAAI,IAAK,GAAM,MAAQ,IACpD,CACA,SAAgB,EAAI,GAClB,OAAO,OAAO,GAAS,IAAI,QACzB,WACC,IAAA,CAAY,IAAK,QAAS,IAAK,OAAQ,IAAK,OAAQ,IAAK,SAAU,IAAK,SAAW,IAExF,CACA,SAAgB,EAAM,GACpB,OAAO,KAAK,MAAc,IAAR,GAAgB,GACpC,CACA,SAAgB,EAAe,EAAiB,GAAS,GACvD,OACE,EACG,IAAA,CAAK,EAAO,IAAU,GAAG,EAAQ,IAAM,MAAM,EAAM,EAAM,MAAM,EAAM,EAAM,MAC3E,KAAK,MAAQ,EAAS,KAAO,GAEpC,CAuBA,SAAgB,EAAU,GACxB,MAAM,EAAI,EAAK,EACb,EAAI,EAAK,EACX,GAAkB,YAAd,EAAK,KACP,MAAO,IAAI,KAAK,EAAI,KAAK,EAAI,KAAK,EAAI,YAAY,OAAO,EAAI,KAAK,EAAI,WAAW,OACnF,GAAkB,YAAd,EAAK,KAAoB,MAAO,IAAI,EAAI,OAAO,KAAK,EAAI,KAAK,EAAI,KAAK,OAAO,EAAI,KACrF,GAAkB,SAAd,EAAK,KACP,OAAO,GAEH,EAAK,QAAU,CACb,CAAC,EAAG,GACJ,CAAC,EAAG,KAEN,IAAA,EAAM,EAAG,MAAA,CAAU,IAAG,QAE5B,GAAkB,SAAd,EAAK,KAAiB,OArC5B,SAA6B,GAC3B,MAAM,EAAS,EAAK,QAAU,GAC9B,IAAK,EAAO,OAAQ,MAAO,GAC3B,GAAI,EAAK,OACP,OAAO,EACL,EAAO,IAAA,EAAM,EAAG,MAAA,CAAU,IAAG,QAC7B,GAEJ,MAAM,EAAS,EACb,EAAO,IAAA,EAAM,EAAG,EAAG,MAAA,CAAiB,IAAG,IAAG,cAC1C,CACE,KAAuC,KAAhC,EAAK,OAAO,aAAe,GAClC,SAAU,IACV,UAAW,GACX,WAAY,IACZ,iBAAkB,EAAO,MAAO,QAAuB,IAAb,EAAM,IAChD,MAAM,IAGV,OAAK,EAAO,OACL,IAAI,EAAO,IAAK,GAAU,GAAG,EAAM,EAAM,OAAO,EAAM,EAAM,OAAO,KAAK,UADpD,EAE7B,CAgBmC,CAAa,GAC9C,MAAM,EAAS,KAAK,IAAI,EAAG,KAAK,IAAI,EAAK,OAAO,QAAA,GAAuB,EAAI,EAAG,EAAI,IAClF,MAAO,IAAI,OAAY,EAAI,KAAU,OAAO,KAAK,KAAU,EAAI,KAAU,KAAK,KAAK,EAAI,KAAU,KAAK,OAAY,OAAO,EAAI,KAAU,SAAc,MACvJ,CACA,SAAgB,EAAS,EAAY,GACnC,MAAM,EAAO,EAAK,OAAO,OAAuB,SAAd,EAAK,KAAkB,OAAS,QAClE,MAAO,CACL,OAAQ,EAAM,EAAK,OAAO,QAAU,MAAO,GAC3C,YAAa,EAAK,OAAO,cAA8B,SAAd,EAAK,KAAkB,EAAI,GACpE,KAAM,EAAK,OAAO,MAAQ,QAC1B,KAAM,EAAM,EAAM,GAClB,SAAU,EAAK,OAAO,UAAY,QAClC,OAAQ,EAAK,OAAO,QAAA,GACpB,QAAS,EAAK,OAAO,SAAW,EAEpC,CACA,SAAgB,GACd,EACA,EACA,EACA,EAAO,EAAU,IAEjB,MAAM,EAAQ,EAAS,EAAM,GACvB,EAAsB,WAAf,EAAM,KAAoB,MAAuB,WAAf,EAAM,KAAoB,MAAQ,GAC3E,EAAuB,SAAd,EAAK,KACd,EACU,SAAd,EAAK,MAAiC,cAAd,EAAK,KACzB,OACA,EACE,EAAK,QAAyB,SAAf,EAAM,KACnB,EAAM,KACN,EAAM,OACR,EAAM,KACR,EAAU,QAAQ,EAAI,QAAQ,gBAAiB,OAC/C,EAA2B,UAAnB,EAAM,UAAiC,SAAT,IAAoB,EAI1D,EAAW,EAAQ,QAAQ,KAAa,EAE9C,MAAO,GALM,EACT,sBAAsB,mHAAyH,EAAI,iEACnJ,cAEyB,EAAI,aAAgB,EAAI,MAAgC,SAAnB,EAAM,UAAwB,EAAkC,GAAzB,kCAAuC,IAAW,EAAK,OAAS,OAAS,EAAI,EAAM,0BAA0B,EAAM,8DAA8D,EAAO,sBAAsB,KAAU,MAEnU,CACA,SAAgB,GACd,EACA,EACA,EACA,EACA,GAEA,IAAK,GAAiB,SAAT,EAAiB,MAAO,GACrC,GAAa,QAAT,EACF,MAAO,eAAe,EAAM,EAAM,WAAW,EAAM,EAAM,UAAU,KAAK,IAAI,EAAW,EAAR,aAAqB,EAAI,QAC1G,MAAM,EAAQ,KAAK,MAAM,EAAM,EAAI,EAAS,EAAG,EAAM,EAAI,EAAS,GAC5D,EAAS,KAAK,IAAI,GAAY,IAAR,GACtB,EAAS,KAAK,GAAK,EASzB,MAAO,YAAY,EAAe,CAAC,CAPjC,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,EACxC,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,GAMJ,EAAO,CAH3C,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,EACxC,EAAG,EAAM,EAAI,KAAK,IAAI,EAAQ,GAAU,6BAE+B,EAAI,qBAA0B,qDACzG,CACA,SAAgB,GAAY,EAAiB,EAAY,GACvD,GAAI,EAAO,OAAS,EAAG,MAAO,GAC9B,MAAM,EAAQ,EAAS,EAAM,GAC7B,OACE,GAAW,EAAO,GAAI,EAAO,GAAI,EAAK,OAAO,MAAO,EAAM,OAAQ,EAAM,aACxE,GACE,EAAO,EAAO,OAAS,GACvB,EAAO,EAAO,OAAS,GACvB,EAAK,OAAO,MAAsB,cAAd,EAAK,KAAuB,QAAU,QAC1D,EAAM,OACN,EAAM,YAGZ,CCrOA,IAAa,GAAa,oCAC1B,SAAgB,GAAW,GACzB,OAAO,KAAK,UAAU,EAAK,KAAM,EACnC,CCJA,IAAM,GAAgC,CACpC,OACE,+GACF,KAAM,wHACN,KAAM,8DACN,QAAS,iDACT,QACE,2HACF,KAAM,kKACN,UAAW,mEACX,KAAM,4FACN,KAAM,iDACN,KAAM,qMACN,KAAM,kGACN,OACE,kGACF,QACE,6GACF,MACE,wJACF,KAAM,uJACN,OACE,yIACF,KAAM,gEACN,KAAM,mEACN,KAAM,mCACN,MAAO,yBACP,IAAK,kLACL,QAAS,oDACT,SAAU,uFACV,OAAQ,qFACR,KAAM,yFACN,MAAO,yCACP,KAAM,2MACN,MACE,kLACF,IAAK,mIACL,KAAM,4FACN,MACE,0JACF,KAAM,mJACN,KAAM,kGACN,KAAM,6GACN,OACE,2vBACF,UAAW,sCACX,YAAa,sCACb,WAAY,uCACZ,MACE,kIACF,OACE,4NACF,KAAM,iKAER,SAAgB,GAAK,GACnB,MAAO,mJAAmJ,GAAM,IAAS,GAAM,cACjL,CACA,SAAgB,GACd,EACA,EACA,EACA,EAAY,kBAEZ,MAAM,EAAK,SAAS,cAAc,UAUlC,OATA,EAAG,KAAO,SACV,EAAG,UAAY,EACf,EAAG,MAAQ,EACX,EAAG,aAAa,aAAc,GAC9B,EAAG,UAAY,GAAK,GACpB,EAAG,iBAAiB,QAAA,KAClB,EAAG,QACH,MAEK,CACT,CCzEA,IAAa,GAAkB,QAClB,GAAkB,+CCmBzB,GAAyC,CAAC,MAAO,OAcvD,IAAM,GAAQ,CACZ,CAAC,SAAU,SAAU,KACrB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,YAAa,KACtB,CAAC,UAAW,UAAW,KACvB,CAAC,UAAW,UAAW,KACvB,CAAC,YAAa,QAAS,KACvB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,OAAQ,KACjB,CAAC,OAAQ,cAAe,KACxB,CAAC,SAAU,SAAU,MAEjB,GAAU,CACd,CAAC,MAAO,OACR,CAAC,QAAS,SACV,CAAC,OAAQ,mBACT,CAAC,OAAQ,cACT,CAAC,QAAS,UACV,CAAC,SAAU,YACX,CAAC,QAAS,SACV,CAAC,QAAS,SACV,CAAC,MAAO,YACR,CAAC,OAAQ,QACT,CAAC,OAAQ,YAGX,SAAS,GAAY,EAAe,GAClC,OAAO,GAAS,KAAQ,GAAS,MAAQ,GAAU,GACrD,CACA,SAAS,GAA0C,EAAQ,EAAY,GAAI,GACzE,MAAM,EAAO,SAAS,cAAc,GAGpC,OAFA,EAAK,UAAY,EACb,IAAM,EAAK,YAAc,GACtB,CACT,CACA,SAAS,GAAW,EAAe,EAAoB,EAAO,aAC5D,MAAM,EAAI,GAAG,SAAU,EAAM,GAM7B,OALA,EAAE,KAAO,SACT,EAAE,iBAAiB,QAAA,KACjB,EAAE,QACF,MAEK,CACT,CACA,SAAS,GAAM,EAAe,GAC5B,MAAM,EAAU,GAAG,QAAS,YAE5B,OADA,EAAQ,OAAO,GAAG,OAAQ,iBAAkB,GAAQ,GAC7C,CACT,CACA,SAAS,GAAO,EAA4B,EAAe,GACzD,MAAM,EAAQ,GAAG,UAMjB,GALA,EAAO,QAAA,EAAU,EAAG,MAClB,MAAM,EAAI,GAAG,SAAU,GAAI,GAC3B,EAAE,MAAQ,EACV,EAAM,OAAO,MAEV,EAAO,KAAA,EAAO,KAAO,IAAM,GAAQ,CACtC,MAAM,EAAS,GAAG,SAAU,GAAI,GAChC,EAAO,MAAQ,EACf,EAAM,OAAO,EACf,CAGA,OAFA,EAAM,MAAQ,EACd,EAAM,SAAA,IAAiB,EAAO,EAAM,OAC7B,CACT,CAWA,SAAgB,GAAQ,EAAc,EAAqB,CAAC,GAC1D,MAAM,EAAK,GAAG,MAAO,SACrB,EAAM,MAAM,KAAK,OAAO,GACxB,MAAM,EAAyB,GAC/B,IAAI,EAmCA,EACA,EACA,EApCJ,SAAS,EAAO,GACd,IACA,GAAc,QACd,MAAM,EAAW,SAAS,cACpB,EAAI,GAAG,SAAU,aACjB,EAAO,GAAG,MAAO,kBACjB,EAAO,GAAG,OA0BhB,OAzBA,EAAK,OAAO,GAAG,KAAM,GAAI,IACzB,EAAK,OACH,EACA,GAAO,QAAS,QAAA,IAAe,EAAE,UAEnC,EAAE,OAAO,GACT,EAAE,iBAAiB,QAAU,IAC3B,GAAI,EAAE,SAAW,EAAG,CAClB,MAAM,EAAI,EAAE,yBACR,EAAE,QAAU,EAAE,MAAQ,EAAE,QAAU,EAAE,OAAS,EAAE,QAAU,EAAE,KAAO,EAAE,QAAU,EAAE,SAClF,EAAE,OACN,IAEF,EAAE,iBAAiB,QAAA,KACjB,EAAE,SACE,IAAiB,IAAG,OAAe,GAClC,IACH,KACI,GAAU,YAAa,EAAS,QAC/B,EAAM,WAGf,EAAG,OAAO,GACV,EAAe,EACf,EAAE,YACK,CACT,CAIA,SAAS,IACP,GAAe,cACf,GAAe,SACf,OAAgB,EAChB,GAAgB,aAAa,gBAAiB,SAC1C,IAAgB,EAAe,qBAAuB,MAC1D,OAAiB,CACnB,CACA,SAAS,EAAQ,EAAwC,GACvD,GAAI,GAAW,IAAmB,GAAW,GAAe,QAAQ,iBAElE,YADA,IAGF,IACA,MAAM,EAAQ,GAAG,MAAO,cACxB,EAAM,QAAU,OAChB,EAAM,aAAa,OAAQ,SAC3B,EAAM,aAAa,aAAc,GACjC,MAAM,EAAW,SAAS,cAuC1B,OAtCI,IACF,EAAQ,aAAa,gBAAiB,QACtC,EAAQ,qBAAuB,EAC/B,EAAQ,oBAAsB,QAEhC,EAAgB,EAChB,EAAiB,EACjB,EAAM,iBAAiB,SAAA,KACjB,IAAkB,GAAU,EAAM,QAAQ,kBAC5C,GAAS,aAAa,gBAAiB,WAE3C,EAAM,iBAAiB,UAAY,IAEjC,GADA,EAAM,kBACY,WAAd,EAAM,KAAmC,QAAd,EAAM,KAAmC,WAAlB,EAAM,QACxC,WAAd,EAAM,KAAkB,EAAM,iBAClC,IACI,GAAU,YAAa,EAAS,QAC/B,EAAM,aACN,KACH,EAAM,kBAAkB,mBAC1B,CAAC,YAAa,UAAW,YAAa,aAAc,OAAQ,OAAO,SAAS,EAAM,KAClF,CACA,MAAM,EAAQ,EAAa,GACrB,EAAU,EAAM,QAAQ,SAAS,eACjC,EACU,SAAd,EAAM,IACF,EACc,QAAd,EAAM,IACJ,EAAM,OAAS,GACd,GACgB,cAAd,EAAM,KAAqC,eAAd,EAAM,IAAuB,GAAI,GAC/D,EAAM,QACR,EAAM,OACd,EAAM,iBACN,EAAM,IAAO,OACf,IAEF,EAAG,OAAO,GACH,CACT,CACA,SAAS,EACP,EACA,EACA,EAAuB,GAEvB,EAAM,cACN,MAAM,EAAS,EAAQ,wBACrB,EAAS,EAAM,MAAM,KAAK,wBACtB,EAAS,GAAY,EAAO,MAAO,EAAO,QAC9C,EAAQ,KAAK,IAAI,IAAK,EAAO,MAAQ,IACvC,EAAM,MAAM,MAAQ,GAAG,MACvB,MAAM,EAAS,EAAM,wBAAwB,OACvC,EAAgB,EAAQ,QAAQ,iBAAmB,EACnD,EAAO,EACT,EAAO,MAAQ,GACf,EAAQ,QAAQ,eAAiB,EAAO,KAAO,EAAO,KAAO,EAAO,MAAQ,EAC1E,EAAO,KACP,EAAO,MAAQ,EACf,EAAM,EACR,EAAO,IACP,EAAO,IAAM,EAAO,IAAM,EAAO,OAAS,EACxC,EAAO,IAAM,EAAS,GACtB,EAAO,OAAS,GACtB,EAAM,MAAM,KAAO,GAAG,KAAK,IAAI,EAAO,KAAO,GAAI,KAAK,IAAI,EAAM,EAAO,MAAQ,EAAQ,SACvF,EAAM,MAAM,IAAM,GAAG,KAAK,IAAI,EAAO,IAAM,GAAI,KAAK,IAAI,EAAK,EAAO,OAAS,EAAS,SACtF,EAAa,GAAO,IAAI,OAC1B,CACA,SAAS,EAAa,GACpB,MAAO,IAAI,EAAM,iBAA8B,kCACjD,CACA,SAAS,EAAY,EAAe,GAClC,MAAM,EAAQ,OAAQ,EAAW,GAEjC,EAAM,QAAU,SAChB,EAAM,UAAU,IAAI,mBACpB,EAAM,aAAa,OAAQ,QAC3B,EAAM,UAAW,EA2BjB,MAAO,CAAE,QAAO,IA1BV,CAAO,EAAe,EAAe,EAAoB,GAAW,KACxE,MAAM,EAAS,GACb,EAAA,KAEE,IACA,EAAM,QACN,KAEF,kBAEF,EAAO,mBAAmB,aAAc,GAAK,IAC7C,EAAO,aAAa,OAAQ,YAC5B,EAAO,SAAW,EAAM,UAAY,EACtB,UAAV,GAAmB,EAAO,UAAU,IAAI,aAC5C,EAAM,OAAO,IAYM,KAVf,KACJ,EAAM,cACN,MAAM,EAAS,EAAM,MAAM,KAAK,wBAC1B,EAAQ,KAAK,IAAI,IAAK,EAAO,MAAQ,IAC3C,EAAM,MAAM,MAAQ,GAAG,MACvB,MAAM,EAAS,EAAM,wBAAwB,OAC7C,EAAM,MAAM,KAAO,GAAG,KAAK,IAAI,EAAO,KAAO,GAAI,KAAK,IAAI,EAAM,EAAG,EAAO,MAAQ,EAAQ,SAC1F,EAAM,MAAM,IAAM,GAAG,KAAK,IAAI,EAAO,IAAM,GAAI,KAAK,IAAI,EAAM,EAAG,EAAO,OAAS,EAAS,UACzF,EAAM,cAAiC,0BAA4B,GAAO,SAG/E,CACA,MAAM,EAAA,IAAqB,IACrB,EAAkB,IACS,WAA3B,GAAe,SAAyB,EAAc,SAAS,EAAM,SACvE,KAEJ,OAAO,iBAAiB,SAAU,GAClC,OAAO,iBAAiB,cAAe,GAAgB,GACvD,EAAO,KAAA,KACL,OAAO,oBAAoB,SAAU,GACrC,OAAO,oBAAoB,cAAe,GAAgB,KAE5D,MAAM,GAA4B,IAAjB,EAAQ,KACnB,EA3QR,SAAuB,GACrB,IAAc,IAAV,EAAiB,MAAO,GAC5B,IAAK,MAAM,QAAQ,GAAQ,MAAO,IAAI,IACtC,MAAM,iBAAO,IAAI,IACX,EAA4B,GAClC,IAAK,MAAM,KAAU,EACJ,QAAX,GAA+B,QAAX,GAA+B,SAAX,GACxC,EAAK,IAAI,KACb,EAAK,IAAI,GACT,EAAQ,KAAK,IAEf,OAAO,CACT,CA+PkB,CAAc,EAAQ,QAChC,EAAS,GAAG,SAAU,aAC5B,IAAI,EACA,EACA,EAuBJ,GAtBI,IACF,EAAQ,GAAO,aAAc,UAq1B/B,WACE,IAAK,EAAO,OACZ,MAAM,EAAQ,EAAQ,EAAO,cAC7B,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,mBACpB,MAAM,EAAA,CAAO,EAAe,EAAe,EAAoB,GAAW,KACxE,MAAM,EAAS,GACb,EACA,EAAA,KAEE,IACA,KAEF,kBAEF,EAAO,WAAa,SAAS,WAC7B,EAAO,SAAW,EAClB,EAAM,OAAO,IAEf,EAAI,iBAAkB,SAAA,IAAgB,GAAc,QAAS,EAAM,UAC/D,GAAY,EAAM,MAAM,KAAK,YAAa,EAAM,MAAM,KAAK,eAC7D,EAAI,OAAQ,OAAA,KACV,EAAM,QAAQ,QACd,EAAM,UAGV,EAAI,EAAM,KAAO,YAAc,YAAa,OAAA,IAAc,EAAM,SAAS,EAAM,OAC/E,MAAM,EAAqC,SAA9B,EAAM,MAAM,cACzB,EAAI,EAAO,mBAAqB,kBAAmB,EAAO,MAAQ,OAAA,IAChE,EAAM,SAAS,EAAO,QAAU,SAElC,EAAI,gBAAiB,OAAA,KACnB,OAAO,KAAK,oBAAqB,SAAU,cAE7C,MAAM,EAAS,GAAG,IAAK,kBACvB,EAAO,KAAO,GACd,EAAO,OAAS,SAChB,EAAO,IAAM,sBACb,EAAO,MAAQ,SACf,EAAO,UAAY,GAAG,GAAK,+BAC3B,EAAO,iBAAiB,QAAA,IAAe,KACvC,MAAM,EAAY,GAAG,MAAO,qBAC5B,EAAU,aAAa,OAAQ,aAC/B,EAAM,OAAO,EAAQ,EAAW,GAAG,IAAK,kBAAmB,IAAI,OAC/D,EAAY,EAAO,EACrB,EAl4BoD,YAClD,EAAM,UACJ,oUACA,GAAK,WACP,EAAM,aAAa,gBAAiB,QACpC,EAAM,aAAa,gBAAiB,SACpC,EAAe,GAAG,SAClB,EAAa,KAAO,OACpB,EAAa,OAAS,gCACtB,EAAa,QAAS,EACtB,EAAa,SAAA,KACX,MAAM,EAAO,GAAc,QAAQ,GAC/B,IAAc,EAAa,MAAQ,IACnC,GACF,EACG,OACA,KAAM,GAAU,EAAM,KAAK,KAAK,MAAM,KACtC,MAAA,SAEP,EAAO,OAAO,IAEZ,EAAQ,OAAQ,CAClB,MAAM,EAAU,GAAG,MAAO,qBAC1B,EAAe,GAAW,SAgyB5B,WACE,GAAuB,IAAnB,EAAQ,OAEV,YADA,GAAW,EAAQ,IAGrB,IAAK,EAAc,OACnB,MAAM,EAAQ,EAAQ,EAAc,UACpC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,mBACpB,MAAM,EAAoD,CACxD,IAAK,CAAC,YAAa,SACnB,IAAK,CAAC,YAAa,SACnB,KAAM,CAAC,kBAAmB,SAE5B,IAAK,MAAM,KAAU,EAAS,CAC5B,MAAO,EAAO,GAAS,EAAQ,GACzB,EAAS,GACb,EACA,EAAA,KAEE,IACA,GAAW,IAEb,kBAEF,EAAO,WAAa,SAAS,WAC7B,EAAM,OAAO,EACf,CACA,EAAY,EAAO,EACrB,EA7zBkD,wBAChD,EAAa,mBAAmB,aAAc,GAAK,aAC/C,EAAQ,OAAS,IACnB,EAAa,aAAa,gBAAiB,QAC3C,EAAa,aAAa,gBAAiB,UAE7C,EAAQ,OAAO,GACf,EAAO,OAAO,EAChB,CACK,GAAU,EAAO,UAAU,IAAI,kBAChC,GAAY,EAAQ,SAAQ,EAAG,OAAO,GACtC,GAAc,EAAG,OAAO,GAC5B,MAAM,EAAU,GAAG,MAAO,cAE1B,SAAS,EAAW,EAAY,GAAW,GACzC,MAAM,CAAG,EAAO,GAAO,GAAM,KAAM,GAAS,EAAK,KAAO,GAClD,EAAI,GACR,EACA,EAAA,KAEE,IACA,EAAM,QAAQ,GACd,EAAM,SAER,EAAW,iBAAmB,kBAOhC,OALA,EAAE,QAAQ,KAAO,EACjB,EAAE,aAAa,oBAAqB,GACpC,EAAE,aAAa,eAAgB,OAAO,EAAM,OAAS,IACrD,EAAE,WAAa,EAAW,SAAS,WAAiB,4BAA4B,WAC5E,EAAM,UAAmB,SAAP,GAAwB,WAAP,IAAiB,EAAE,UAAW,GAC9D,CACT,CAnBA,EAAQ,aAAa,aAAc,iBAoBnC,MAAM,EAAa,CAAC,OAAQ,UAAW,UAAW,OAAQ,aACpD,EAAc,GAAO,SAAU,SAAA,KACnC,MAAM,EAAQ,EAAQ,EAAa,UAC9B,IACL,EAAM,UAAU,IAAI,mBACpB,EAAM,UAAU,EAAW,IAAK,GAAO,EAAW,GAAI,KACtD,EAAY,EAAO,MAErB,EAAY,aAAa,gBAAiB,QAC1C,EAAY,aAAa,gBAAiB,SAC1C,EAAY,WACV,6EACF,MAAM,EAAa,GAAG,SACtB,EAAW,KAAO,OAClB,EAAW,OAAS,uDACpB,EAAW,QAAS,EACpB,EAAW,SAAA,KACL,EAAW,QAAQ,IAAI,EAAW,SAAS,EAAW,MAAM,IAAI,MAAA,QACpE,EAAW,MAAQ,IAErB,MAAM,EAAc,GAAO,YAAa,QAAA,KACtC,IACA,EAAW,UAEb,EAAY,WAAa,4CACzB,EAAY,SAAW,EAAM,SAC7B,MAAM,EAAO,EAAW,QACpB,GAAU,EAAK,UAAU,IAAI,mBACjC,EAAQ,OACN,EAAW,UACX,EACA,EAAW,UACX,GAAG,MAAO,sBACV,EACA,EAAW,QACX,EAAW,QACX,EAAW,QACX,EACA,GAEF,EAAG,OAAO,GACV,MAAM,EAAY,GAAG,QAAS,iBAC9B,EAAU,aAAa,aAAc,mBACrC,EAAU,QAAS,EACnB,MAAM,EAAa,GAAG,MAAO,kBACvB,EAAW,GAAO,WAAY,UAAA,IAAiB,EAAM,OAAO,KAClE,EAAS,UAAU,IAAI,oBACvB,EAAU,OAAO,EAAU,GAC3B,EAAG,OAAO,GACV,MAAM,EAAS,GAAG,SAAU,aACtB,EAAO,GAAO,OAAQ,OAAA,IAAc,EAAM,QAC9C,EAAO,GAAO,OAAQ,OAAA,IAAc,EAAM,QAC5C,EAAK,aAAa,oBAAqB,oBACvC,EAAK,aAAa,oBAAqB,gCACvC,MAAM,EAAW,GAAG,MAAO,YAC3B,EAAS,aAAa,aAAc,SACpC,MAAM,EAAW,GAAG,MAAO,gBAC3B,EAAS,aAAa,OAAQ,WAC9B,EAAS,aAAa,aAAc,SACpC,MAAM,EAAW,GAAO,YAAa,OAgLrC,WACE,MAAM,EAAQ,EAAQ,EAAU,aAChC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,oBACpB,IAAK,MAAM,KAAQ,EAAM,OAAO,MAAO,CACrC,MAAM,EAAM,GAAG,MAAO,eACtB,EAAI,OAAO,EAAW,EAAK,GAAI,EAAK,OACpC,MAAM,EAAU,GAAO,eAAe,EAAK,OAAQ,OAAA,KACjD,MAAM,EAAS,EAAQ,wBACvB,EAAY,EAAK,GAAI,EAAK,KAAM,CAAE,EAAG,EAAO,KAAM,EAAG,EAAO,QAE9D,EAAI,OAAO,GACX,EAAM,OAAO,EACf,CACA,EAAY,EAAO,GACnB,EAAM,cAA2B,0BAA0B,eAAe,CAAE,MAAO,WACrF,GA/LA,EAAS,aAAa,gBAAiB,QACvC,EAAS,aAAa,gBAAiB,SACvC,EAAS,QAAS,EAClB,MAAM,EAAU,GAAO,WAAY,OAgKnC,WACE,IACA,MAAM,EAAK,IACL,EAAQ,EAAM,OAAO,MAC3B,IAAI,EAAS,EAAM,OAAS,EAC5B,KAAO,EAAM,KAAM,GAAS,EAAK,OAAS,QAAQ,MAAW,IAC9C,EAAM,MACnB,CAAC,CAAE,GAAI,WAAY,KAAM,CAAE,KAAI,KAAM,QAAQ,IAAU,MAAO,MAC9D,CAAE,OAAQ,OAAQ,MAAO,aAEhB,IAAI,EAAM,QAAQ,EAC/B,GA1KA,EAAQ,SAAW,EAAM,SACzB,EAAS,OAAO,EAAU,EAAU,GACpC,IAAI,EAAY,GAChB,SAAS,EAAY,EAAY,EAAc,GAC7C,MAAM,EAAO,EAAY,eAAgB,GACzC,EAAK,IAAI,cAAe,OAAA,IAkN1B,SAAoB,EAAY,GAC9B,GAAI,EAAM,SAAU,OACpB,MAAM,EAAI,EAAO,kBACX,EAAQ,GAAG,SACjB,EAAM,MAAQ,EACd,EAAM,UAAY,IAClB,EAAE,OACA,GAAM,YAAa,GACnB,GACE,YAAA,KAEM,EAAM,MAAM,QACd,EAAM,MAAM,CAAC,CAAE,GAAI,WAAY,KAAI,MAAO,CAAE,KAAM,EAAM,MAAM,UAAa,CACzE,OAAQ,OACR,MAAO,gBAEX,EAAE,SAEJ,yBAGJ,EAAM,iBAAiB,UAAY,IACf,UAAd,EAAM,KAAiB,EAAE,cAAiC,gBAAgB,UAEhF,EAAE,iBACA,QAAA,KAEE,MAAM,EAAM,EAAS,cAAiC,kBAAkB,IAAI,OAAO,QAC/E,IAAQ,EAAI,OAAQ,EAAI,QAClB,EAAS,QAAQ,EAAS,SAEtC,CAAE,MAAM,IAEV,EAAM,QACN,EAAM,QACR,CArPwC,CAAW,EAAI,IACrD,EAAK,IACH,cACA,QAAA,KAEE,EAAM,MAAM,CAAC,CAAE,GAAI,cAAe,OAAO,CAAE,OAAQ,OAAQ,MAAO,iBAEtC,IAA9B,EAAM,OAAO,MAAM,QAErB,EAAK,MACP,CACA,SAAS,EAAW,EAAY,EAAc,GAAM,GAClD,MAAM,EAAO,GACX,EAAA,KAEE,IACA,EAAM,QAAQ,GACd,EAAS,cAAiC,2BAA2B,SAEvE,EAAM,cAAgB,kBAExB,EAAK,MAAQ,EACb,EAAK,QAAQ,OAAS,EACtB,IACI,EADA,GAAO,EAEX,EAAK,iBAAiB,cAAgB,IACpC,GAAO,EACmB,UAAtB,EAAM,cACV,EAAQ,CAAE,EAAG,EAAM,QAAS,EAAG,EAAM,SACrC,aAAa,GACb,EAAiB,WAAA,KACf,GAAO,EACP,EAAY,EAAI,EAAM,IACrB,QAEL,EAAK,iBAAiB,cAAgB,IAChC,GAAS,KAAK,MAAM,EAAM,QAAU,EAAM,EAAG,EAAM,QAAU,EAAM,GAAK,IAC1E,aAAa,KAEjB,IAAK,MAAM,IAAQ,CAAC,YAAa,iBAC/B,EAAK,iBAAiB,EAAA,IAAY,aAAa,IAwCjD,OAvCA,EAAK,iBACH,QACC,IACK,IACF,EAAM,iBACN,EAAM,8BAGV,GAEE,GACF,EAAK,aAAa,OAAQ,OAC1B,EAAK,aAAa,gBAAiB,OAAO,EAAM,SAAW,IAC3D,EAAK,SAAW,EAAM,SAAW,EAAK,GAAI,GACrC,EAAK,aAAa,eAAgB,OAAO,EAAM,SAAW,IACjE,EAAK,iBAAiB,cAAgB,IACpC,EAAM,iBACN,EAAY,EAAI,EAAM,CAAE,EAAG,EAAM,QAAS,EAAG,EAAM,YAErD,EAAK,iBAAiB,UAAY,IAChC,GAAkB,gBAAd,EAAM,KAA0B,EAAM,UAA0B,QAAd,EAAM,IAAgB,CAC1E,EAAM,iBACN,MAAM,EAAS,EAAK,wBACpB,EAAY,EAAI,EAAM,CAAE,EAAG,EAAO,KAAM,EAAG,EAAO,KACpD,MAAO,GAAI,GAAO,CAAC,YAAa,aAAc,OAAQ,OAAO,SAAS,EAAM,KAAM,CAChF,EAAM,iBACN,MAAM,EAAQ,EAAM,OAAO,MACrB,EAAQ,EAAM,UAAW,GAAS,EAAK,KAAO,GAC9C,EACU,SAAd,EAAM,IACF,EACc,QAAd,EAAM,IACJ,EAAM,OAAS,GACd,GAAuB,eAAd,EAAM,IAAuB,GAAI,GAAM,EAAM,QAAU,EAAM,OAC/E,IACA,EAAM,QAAQ,EAAM,GAAM,IAC1B,EAAS,cAAiC,2BAA2B,OACvE,IAEK,CACT,CACA,IAAI,GAAe,EACnB,SAAS,IACP,GAAI,EAAc,OAClB,GAAe,EACf,MAAM,EAAQ,GAAG,MAAO,gBACxB,IACE,MAAM,EAAO,IAAI,EAAS,iBAAoC,WAC9D,EAAM,MAAM,QACV,4EACF,MAAM,EAAU,EAAK,IAAK,IACxB,MAAM,EAAS,EAAI,WAAU,GAG7B,OAFA,EAAO,QAAS,EAChB,EAAO,MAAM,SAAW,GACjB,IAEH,EAAiB,EAAS,WAAU,GAC1C,EAAe,QAAS,EACxB,EAAM,UAAU,EAAS,GACzB,EAAG,OAAO,GACV,MAAM,EAAS,EAAQ,IAAK,GAAW,EAAO,wBAAwB,OAChE,EAAgB,EAAe,YACrC,EAAM,SACN,MAAM,EAAS,EAAO,OAAA,CAAQ,EAAK,IAAU,EAAM,EAAQ,EAAG,GAAK,EAAQ,YAAc,GACnF,EACJ,EAAS,YAAc,EAAY,UAC/B,EAAO,YAAc,EAAY,YAAc,GAC/C,EAAS,YACT,EAAM,KAAK,IAAI,EAAM,KACrB,EAAe,GAAU,EACzB,EAAa,EAAK,IAAA,KAAU,GAC5B,EAAU,EAAK,IAAA,IAAU,IAC/B,IAAK,EAAc,CACjB,IAAI,EAAY,KAAK,IAAI,GAAI,EAAM,EAAQ,YAAc,GAAK,EAAgB,GAC9E,MAAM,EAAW,EAAK,UAAW,GAA8C,SAAtC,EAAI,aAAa,kBAC1D,IAAK,MAAM,IAAS,CAClB,KACG,EAAK,IAAA,CAAK,EAAG,IAAU,GAAO,OAAQ,GAAU,IAAU,IAEzD,EAAQ,IACR,IAAU,GACZ,EAAQ,GAAS,GAAG,MACpB,GAAa,KAAK,IAAI,EAAW,EAAO,IAAU,IAElD,EAAW,GAAS,EAAO,GAAS,EAC/B,EAAW,KAAQ,GAAa,EAAO,GAAS,IAG3D,CACA,EAAS,OAAS,EAClB,EAAK,QAAA,CAAS,EAAK,KACjB,EAAI,OAAS,EAAW,GACxB,EAAI,MAAM,SAAW,EAAQ,IAEjC,CAAA,QACE,EAAM,SACN,GAAe,CACjB,CACF,CAUA,MAAM,EAAgB,IAAI,eAAe,IACnB,IAAlB,EAAQ,QACV,EAAc,QAAQ,GACtB,EAAO,KAAA,IAAW,EAAc,eA+BlC,MAAM,EAAc,GAAG,MAAO,mBACxB,EAAO,GAAG,MAAO,WACjB,EAAa,GACjB,OAAA,KAEE,MAAM,EAAQ,EAAQ,EAAY,iBAClC,IAAK,EAAO,OACZ,MAAM,EAAM,GAAG,MAAO,oBACtB,EAAI,OACF,GAAO,WAAY,QAAA,IAAgB,EAAM,KAAK,MAAQ,KACtD,GAAW,OAAA,IAAe,EAAM,KAAK,KAAO,EAAI,iBAChD,GAAO,UAAW,OAAA,IAAe,EAAM,KAAK,MAAQ,MAEtD,EAAM,OAAO,GACb,EAAY,EAAO,EAAY,IAEjC,iBAEF,EAAW,aAAa,aAAc,iBACtC,EAAW,aAAa,gBAAiB,QACzC,EAAW,aAAa,gBAAiB,SACzC,MAAM,EAAY,GAAO,cAAe,MAAA,IAAa,EAAM,KAAK,OA0ChE,SAAS,GAAW,GAClB,MAAgB,UAAT,EAAmB,iBAAmB,UAC/C,CACA,SAAS,GAAS,GAChB,GAAI,EAAM,UAAY,EAAM,SAAS,GAAK,OAC1C,MAAM,EAAO,EAAM,IAAI,GACvB,IAAK,GAAuB,UAAd,EAAK,MAAkC,SAAd,EAAK,KAAkB,OAC9D,MAAM,EAAsB,UAAd,EAAK,KACb,EAAI,EAAO,EAAQ,iBAAmB,YACtC,EAAQ,GAAG,SACjB,EAAM,KAAO,OACb,EAAM,UAAY,MAClB,EAAM,aAAa,eAAgB,OACnC,EAAM,YAAa,EACnB,EAAM,UAAY,IAClB,EAAM,MAAQ,EAAK,MAAQ,GAC3B,EAAM,aAAa,aAAc,EAAQ,YAAc,OACvD,MAAM,EAAQ,GAAG,IAAK,mBACtB,EAAM,aAAa,OAAQ,SAC3B,EAAM,QAAS,EACf,MAAM,EAAO,GACX,EAAQ,iBAAmB,WAAA,KAEzB,WACE,EAAK,UAAW,EAChB,MAAM,QAAe,EAAM,QAAQ,EAAI,EAAM,OAE7C,GADA,EAAK,UAAW,GACX,EAAO,GAAI,CACd,MAAM,EAAO,EAAO,OAAO,IAAI,KAU/B,OATA,EAAM,YACK,WAAT,GAA8B,aAAT,EAChB,EAAO,OAAO,IAAI,SAAW,yBAC9B,EACE,8BACA,sBACR,EAAM,QAAS,EACf,EAAM,aAAa,eAAgB,aACnC,EAAM,OAER,CACA,EAAE,OACJ,EAlBA,IAoBF,wBAEF,EAAE,OAAO,GAAM,EAAQ,YAAc,MAAO,GAAQ,EAAO,GAC3D,EAAM,iBAAiB,QAAA,KACrB,EAAM,QAAS,EACf,EAAM,gBAAgB,kBAExB,EAAM,iBAAiB,UAAY,IACf,UAAd,EAAM,KAAiB,EAAE,cAAiC,gBAAgB,UAEhF,EAAM,QACN,EAAM,QACR,CAhGA,EAAK,OAAO,EAAY,EAAW,EAAM,GACzC,EAAY,OAAO,IACG,IAAlB,EAAQ,MAAiB,EAAO,OAAO,GACtC,EAAO,OAAO,EAAU,GAC7B,EAAG,OAAO,GA6FV,IAAI,GAAiB,GACrB,SAAS,KACP,MAAM,EAAS,EAAM,UAAU,KAAM,GAAO,EAAM,SAAS,IAC3D,GAAmB,WAAf,EAAM,KAGR,OAFI,GAAkB,EAAU,SAAS,IAAiB,SAC1D,EAAU,QAAS,GAGrB,GACE,IACE,GACA,SAAS,yBAAyB,kBACF,UAAhC,SAAS,cAAc,OACtB,EAAU,SAAS,SAAS,gBAC3B,GAAe,SAAS,SAAS,gBAErC,OACF,MAAM,EAAU,EAAU,SAAS,SAAS,eACvC,SAAS,mBACV,EACE,EACJ,GAAkB,EAAU,SAAS,GACjC,CACE,MAAO,EAAe,aAAa,cACnC,QAAS,GAAe,SAAS,SAAS,qBAE5C,EACA,EACJ,GAAS,aAAa,gBAAkB,GAAY,QAAU,EAAW,WAAQ,GAC7E,EAAa,GAAS,QAAQ,UAAU,cAAc,oBAAoB,YAC5E,GAAY,IAChB,MAAM,EAAQ,EAAM,UAAU,IAAK,GAAO,EAAM,IAAI,IAAM,OAAO,SAC3D,EAAc,EAAM,IAAK,GAAS,EAAK,IAAI,KAAK,KAOtD,GANI,KAAmB,GACrB,IAEF,GAAiB,EACjB,EAAW,kBACX,EAAU,OAA0B,IAAjB,EAAM,QACpB,EAAM,OAET,YADI,GAAY,SAAS,EAAM,SAGjC,MAAM,EAAO,EAAM,GACjB,EAA0B,IAAjB,EAAM,OACX,EAAW,EAAM,MAAO,GAAM,CAAC,OAAQ,UAAW,UAAW,QAAQ,SAAS,EAAE,OAChF,EAAU,EAAM,MACnB,IAAO,CAAC,QAAS,OAAQ,QAAS,OAAQ,QAAS,OAAQ,QAAQ,SAAS,EAAE,OAE3E,EAAW,EAAM,MAAO,GAAiB,SAAX,EAAE,MAChC,EAAU,EAAM,MACnB,IAAO,CAAC,QAAS,OAAQ,OAAQ,QAAS,OAAQ,QAAS,QAAQ,SAAS,EAAE,OAE3E,EAAgB,GAAG,MAAO,qBAChC,SAAS,EAAa,EAAe,GACnC,MAAM,EACJ,EAAK,QAAQ,KAAiB,SAAR,EAAgC,SAAd,EAAK,KAAkB,OAAS,OAAU,OAC9E,EAAU,GACd,EAAA,KAEE,MAAM,EAAQ,EAAQ,EAAS,GAAG,WAClC,GAAK,EAAL,CACA,EAAM,UAAU,IAAI,oBACpB,IAAK,MAAO,EAAO,KAAS,GAAS,CACnC,MAAM,EAAI,GAAG,SAAU,cAAuB,SAAV,EAAmB,iBAAmB,KAC1E,EAAE,KAAO,SACT,EAAE,MAAM,YAAY,WAAY,EAAa,EAAO,EAAM,MAAM,gBAChE,EAAE,aAAa,aAAc,GAAG,MAAU,KAC1C,EAAE,MAAQ,EACV,EAAE,aAAa,eAAgB,OAAO,IAAY,IAClD,EAAE,QAAA,KACA,IACA,EAAM,aAAa,GAAO,EAC1B,EAAM,gBAAgB,CAAE,MAAO,CAAA,CAAG,GAAM,KACxC,EAAW,cAAiC,gBAAgB,QAAY,SAE1E,EAAM,OAAO,EACf,CACA,EAAY,EAAO,EAjBP,GAmBd,oBAEF,EAAQ,aAAa,aAAc,GACnC,EAAQ,aAAa,gBAAiB,QACtC,EAAQ,aAAa,gBAAiB,SACtC,MAAM,EAAS,GAAG,OAAQ,qBAAgC,SAAZ,EAAqB,iBAAmB,KACtF,EAAO,MAAM,YAAY,WAAY,EAAa,EAAS,EAAM,MAAM,gBACvE,EAAQ,QAAQ,GAChB,EAAc,OAAO,EACvB,CACI,GAAU,EAAa,OAAQ,QAC/B,GAAS,EAAa,OAAQ,UAC9B,GAAU,EAAa,QAAS,UACpC,MAAM,EAAgB,GACpB,UAAA,KAEE,MAAM,EAAQ,EAAQ,EAAe,oBACrC,IAAK,EAAO,OACZ,EAAM,UAAU,IAAI,sBACpB,MAAM,EAAQ,GAAG,SACjB,EAAM,KAAO,QACb,EAAM,aAAa,aAAc,WACjC,EAAM,IAAM,IACZ,EAAM,IAAM,MACZ,EAAM,MAAQ,OAAO,KAAK,MAAkD,KAA3C,EAAM,IAAI,EAAK,KAAK,OAAO,SAAW,KACvE,MAAM,EAAQ,GAAG,SAAU,GAAI,GAAG,EAAM,UAClC,EAAQ,GAAM,UAAW,GAC/B,EAAM,cAAc,mBAAoB,OAAO,GAC/C,IAAI,GAAQ,EACZ,EAAM,QAAA,KACJ,EAAM,YAAc,GAAG,EAAM,SAC7B,EAAM,MACJ,EAAM,IAAA,EAAO,SAAA,CACX,GAAI,MACJ,KACA,MAAO,CAAE,MAAO,CAAE,QAAS,OAAO,EAAM,OAAS,SAEnD,CAAE,OAAQ,OAAQ,MAAO,iBAAkB,OAAQ,IAErD,GAAQ,GAEV,EAAM,SAAA,KACJ,GAAQ,GAEV,EAAM,OAAO,GACb,EAAY,EAAO,GACnB,EAAM,SAER,oBAEF,EAAc,mBAAmB,aAAc,GAAK,YACpD,EAAc,aAAa,aAAc,WACzC,EAAc,aAAa,gBAAiB,QAC5C,EAAc,aAAa,gBAAiB,SACxC,EAAM,MAAO,GAAuB,UAAd,EAAK,OAAmB,EAAc,OAAO,GACnE,EAAc,mBAAmB,EAAW,OAAO,GACvD,MAAM,EAAc,GAClB,EAAM,MACJ,EAAM,IAAK,IAAA,CACT,GAAI,MACJ,GAAI,EAAK,GACT,MAAO,CAAE,KAAM,CAAE,MAAO,EAAK,MAAM,OAAS,MAAO,OAErD,CAAE,OAAQ,OAAQ,MAAO,eAE7B,SAAS,EAAS,GAChB,MAAM,EAAM,GAAG,MAAO,gBAChB,EAAQ,GAAG,MAAO,eAKxB,OAJA,EAAM,aAAa,OAAQ,SAC3B,EAAM,aAAa,aAAc,GACjC,EAAI,OAAO,GAAG,OAAQ,iBAAkB,GAAQ,GAChD,EAAW,OAAO,GACX,CACT,CACA,SAAS,EACP,EACA,EACA,EACA,GAEA,OAAO,EAAO,IAAA,EAAM,EAAO,EAAO,MAChC,MAAM,EAAI,GAAW,EAAA,IAAa,EAAO,GAAQ,cAMjD,OALA,EAAE,aAAa,aAAc,GAC7B,EAAE,MAAQ,EACV,EAAE,aAAa,eAAgB,OAAO,EAAM,MAAO,GAAS,EAAQ,KAAU,KAC9E,EAAE,UAAY,EACd,EAAM,OAAO,GACN,GAEX,CACA,SAAS,EAAS,EAAe,EAAO,IACtC,MAAO,kHAAkH,4BAAgC,EAAO,sBAAsB,KAAU,YAClM,CACA,GAAI,EAAS,CACX,EACE,EAAS,QACT,CACE,CAAC,IAAK,mBAAoB,KAC1B,CAAC,IAAK,oBAAqB,KAC3B,CAAC,IAAK,mBAAoB,KAC1B,CAAC,KAAM,yBAA0B,OAElC,IAAA,CAAY,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,MAAQ,EAAS,EAAK,QAAU,IAC3E,GAAU,EAAW,CAAE,KAAM,KAEhC,EACE,EAAS,SACT,CACE,CAAC,QAAS,kBAAmB,GAAK,cAClC,CAAC,SAAU,oBAAqB,GAAK,gBACrC,CAAC,MAAO,mBAAoB,GAAK,gBAElC,GAAS,EAAK,MAAM,QAAwB,SAAd,EAAK,KAAkB,QAAU,UAC/D,GAAU,EAAW,CAAE,MAAO,KAEjC,MAAM,EAAsD,CAC1D,CAAC,OAAQ,iBAAkB,MAC3B,CAAC,QAAS,cAAe,MACzB,CAAC,OAAQ,aAAc,MACvB,CAAC,OAAQ,oBAAqB,OAEhC,EACE,EAAS,QACT,EACC,GAAS,EAAK,MAAM,MAAA,OACpB,GAAU,EAAW,CAAE,KAAM,KAC9B,QAAA,CAAS,EAAQ,KACjB,EAAO,MAAM,WAAa,EAAM,EAAY,GAAO,KAEvD,CAwDA,GAvDI,IACF,EACE,EAAS,QACT,CACE,CAAC,IAAK,aAAc,EAAS,IAC7B,CAAC,IAAK,gBAAiB,EAAS,IAChC,CAAC,IAAK,aAAc,EAAS,IAC7B,CAAC,IAAK,mBAAoB,EAAS,KAEpC,GAAS,OAAO,EAAS,EAAM,EAAM,MAAM,eAAe,aAC1D,GAAU,EAAM,gBAAgB,CAAE,MAAO,CAAE,YAAa,OAAO,OAE9D,EAAM,MAAO,GAAuB,SAAd,EAAK,MAAmB,EAAK,SACrD,EACE,EAAS,WACT,CACE,CAAC,QAAS,iBAAkB,EAAS,IACrC,CAAC,SAAU,kBAAmB,EAAS,EAAG,QAC1C,CAAC,SAAU,kBAAmB,EAAS,EAAG,SAE3C,GAAS,EAAK,OAAO,MAAQ,QAC7B,GAAU,EAAM,gBAAgB,CAAE,MAAO,CAAE,KAAM,OAIpD,GAAwB,cAAd,EAAK,MACjB,EAAW,OACT,GACE,QACA,GACE,CACE,CAAC,WAAY,YACb,CAAC,QAAS,SACV,CAAC,QAAS,UAEZ,EAAK,OAAS,QACb,GAAM,EAAM,gBAAgB,CAAE,MAAO,OAI1C,GAAwB,cAAd,EAAK,MACjB,EAAW,OACT,GACE,YACA,GACE,CACE,CAAC,QAAS,SACV,CAAC,MAAO,OACR,CAAC,OAAQ,SAEX,EAAK,OAAO,KAAO,QAClB,GAAU,EAAM,gBAAgB,CAAE,MAAO,IAAK,EAAK,MAAO,IAAK,QAIpE,IAAyB,UAAd,EAAK,MAAkC,SAAd,EAAK,MAAkB,CAC7D,MAAM,EAAQ,GAAW,EAAK,MACxB,EAAO,GAAW,EAAA,IAAa,GAAS,EAAK,IAAK,0BACxD,EAAK,aAAa,aAAc,GAChC,EAAW,OAAO,EACpB,CACA,MAAM,EAAO,GACX,EAAS,mBAAqB,iBAC9B,EAAS,OAAS,SAAA,IACZ,EAAM,gBAAgB,CAAE,QAAS,KAEzC,EAAK,aAAa,eAAgB,OAAO,IACzC,MAAM,EAAM,GAAG,MAAO,wBACtB,EAAI,OACF,GAAO,sBAAuB,OAAA,IAAc,EAAM,aAClD,GAAO,2BAA4B,QAAS,IAC5C,EACA,GAAO,mBAAoB,QAAA,IAAe,EAAM,oBAElD,EAAW,OAAO,IACd,EAAM,UAAY,IACpB,EACG,iBAAiB,uBACjB,QACE,GACE,EAAyB,SAAW,IAAM,IAAa,IAAM,GAAQ,EAAM,WAEjE,qBAAf,GAAoD,mBAAf,EAAiC,EAAK,QACvD,aAAf,EAA2B,EAAS,QACpC,EACP,EAAW,cAA2B,gBAAgB,IAAI,OAAO,SAAkB,QAC5E,GACP,IAAI,EAAW,iBAAiB,UAC7B,KAAM,GAAU,EAAM,cAAc,oBAAoB,cAAgB,IACvE,cAA2B,iBAC3B,SACF,GAAW,GAAY,YACrB,GAAW,EAAM,UAAa,EAAU,SAAS,SAAS,gBAAgB,EAAK,QACvF,CACA,SAAS,KACP,MAAM,EAAI,EAAO,0BACX,EAAU,GAAG,MAAO,kBAc1B,IAbwC,IAA3B,EAAM,UAAU,OAAe,EAAM,IAAI,EAAM,UAAU,SAAM,IAE1E,EAAQ,OACN,GAAW,YAAA,KACT,EAAM,YACN,EAAE,UAEJ,GAAW,SAAA,KACT,EAAM,kBACN,EAAE,WAIJ,EAAM,UAAU,OAAS,EAC3B,IAAK,MAAM,IAAQ,CACjB,OACA,SACA,QACA,MACA,SACA,SACA,aACA,YAEA,EAAQ,OACN,GACW,eAAT,GAAkC,aAAT,EAAsB,cAAc,IAAS,SAAS,IAAA,KAE7E,EAAM,MAAM,GACZ,EAAE,WAIR,EAAM,UAAU,OAAS,GAC3B,EAAQ,OACN,GAAW,QAAA,KACT,EAAM,QACN,EAAE,WAGJ,EAAM,UAAU,KAAM,GAA+B,UAAxB,EAAM,IAAI,IAAK,OAC9C,EAAQ,OACN,GAAW,UAAA,KACT,EAAM,UACN,EAAE,WAGR,EAAQ,OACN,GAAW,iBAAA,KACT,EAAM,MACJ,EAAM,UAAU,IAAK,IAAA,CAAU,GAAI,QAAS,KAAI,GAAI,WACpD,CAAE,OAAQ,OAAQ,MAAO,mBAE3B,EAAE,UAEJ,GAAW,eAAA,KACT,EAAM,MACJ,EAAM,UAAU,IAAK,IAAA,CAAU,GAAI,QAAS,KAAI,GAAI,UACpD,CAAE,OAAQ,OAAQ,MAAO,iBAE3B,EAAE,WAGF,EAAM,UACR,EAAQ,iBAAiB,UAAU,QAAS,GAAY,EAAO,UAAW,GAC5E,EAAE,OAAO,EACX,CACA,SAAS,GAAW,GAClB,EACG,OAAO,EAAQ,CACd,MAAO,OACP,QAAS,GACT,YAAY,KACG,QAAX,EAAmB,CAAE,MAAO,GAAM,CAAC,IAExC,KAAM,KA3+Bb,SAAkB,EAAwB,EAAc,GACtD,MAAM,EAAM,IAAI,gBACK,iBAAZ,EAAuB,IAAI,KAAK,CAAC,GAAU,CAAE,SAAU,GAE1D,EAAO,GAAG,KAChB,EAAK,KAAO,EACZ,EAAK,SAAW,EAChB,EAAK,QACL,WAAA,IAAiB,IAAI,gBAAgB,GAAM,IAC7C,CAw+BQ,CACE,EACA,GANA,EACG,OACA,KAAK,MAAM,QAAQ,iBAAkB,IACrC,QAAU,aAGS,SAAX,EAAoB,QAAU,IAC9B,SAAX,EAAoB,GAAwB,QAAX,EAAmB,gBAAkB,eAGzE,MAAA,OACL,CA6EA,SAAS,KACP,EAAK,UAAY,EAAM,QACvB,EAAK,UAAY,EAAM,QA5nBzB,WACE,IAAsB,IAAlB,EAAQ,MAAiB,OAC7B,MAAM,EAAQ,EAAM,OAAO,MACrB,EAAQ,KAAK,UAAU,CAAC,EAAM,OAAQ,EAAM,IAAA,EAAO,KAAI,UAAW,CAAC,EAAI,MACzE,IAAU,IACd,EAAY,EACZ,EAAS,mBAAmB,EAAM,IAAK,GAAS,EAAW,EAAK,GAAI,EAAK,MAAM,KAC/E,IACF,CAqnBE,GACA,IACF,CACA,MAAM,GAAW,IACf,MAAM,EAAE,EAAA,EAAG,EAAA,GAAG,GAAQ,EAA+C,OAC/D,EAAO,EAAK,EAAM,IAAI,QAAM,EAClC,IAAK,EAEH,YADA,IAGF,MAAM,EAAS,EAAM,MAAM,KAAK,wBAC1B,EAAO,EAAY,kBAAmB,CAAE,EAAG,EAAO,KAAO,EAAG,EAAG,EAAO,IAAM,IAC5E,EAAS,EAAM,SAAS,EAAK,IACjB,UAAd,EAAK,MAAkC,SAAd,EAAK,MAChC,EAAK,IAAI,GAAW,EAAK,MAAO,OAAA,IAAc,GAAS,EAAK,IAAK,GAC9D,CAAC,QAAS,OAAQ,OAAQ,QAAS,OAAQ,QAAS,QAAQ,SAAS,EAAK,OAC7E,EAAK,IAAI,YAAa,OAAA,IAAc,EAAM,SAAS,EAAK,IAAK,GAC/D,MAAM,EAAS,GACb,EAAM,MAAM,CAAC,CAAE,GAAI,QAAS,GAAI,EAAK,GAAI,OAAO,CAC9C,OAAQ,OACR,MAAc,UAAP,EAAiB,iBAAmB,iBAE/C,EAAK,IAAI,iBAAkB,QAAA,IAAe,EAAM,SAAU,GAC1D,EAAK,IAAI,eAAgB,OAAA,IAAc,EAAM,QAAS,GACtD,EAAK,IACH,YACA,OAAA,KAEE,EAAM,OAAO,CAAC,EAAK,KACnB,EAAM,aAER,GAEF,MAAM,EAAY,GAAG,MAAO,qBAC5B,EAAU,aAAa,OAAQ,aAC/B,EAAK,MAAM,OAAO,GAClB,EAAK,IACH,SACA,QAAA,KAEE,EAAM,OAAO,CAAC,EAAK,KACnB,EAAM,mBAER,GAEF,EAAK,QAsBP,OApBA,EAAM,KAAK,iBAAiB,aAAc,IAC1C,EAAO,KACL,EAAM,GAAG,SAAU,IACnB,EAAM,GAAG,SAAA,KACP,OAEF,EAAM,GAAG,OAAQ,IACjB,EAAM,GAAG,OAAS,IACe,WAA3B,GAAe,SAAsB,IACzC,EAAW,YAAc,GAAG,KAAK,MAAmB,IAAb,EAAM,WAE/C,EAAM,GAAG,OAAS,IAChB,IAAK,MAAM,KAAK,EAAG,iBAA8B,eAC/C,EAAE,aAAa,eAAgB,OAAO,IAAO,EAAE,QAAQ,OACzD,EAAY,aAAa,eAAgB,OAAO,EAAW,SAAS,KACpE,EAAM,MAAM,KAAK,QAAQ,OAAS,EAClC,QAGJ,KACA,KACE,aAAa,GACb,IACA,EAAO,QAAS,GAAO,KACvB,GAAc,QACd,EAAM,KAAK,oBAAoB,aAAc,IAC7C,EAAG,SAEP"}