@miragon/modeler-api 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/conformance.ts"],"sourcesContent":["/**\n * The conformance test kit — every law of the CollaborativeModeler contract\n * as an executable case. A modeler repo supplies a small HARNESS (how to\n * create an instance, canonical sample texts, scripted user mutations) and\n * binds the cases to its own test runner:\n *\n * import { conformanceCases, registerConformance } from \"@miragon/modeler-api/conformance\";\n * registerConformance(harness, test); // node:test, vitest, jest — any (name, fn) runner\n *\n * Cases throw plain Errors on violation, so the kit has no runner or\n * assertion-library dependency. A case that CANNOT (fully) run because the\n * harness left an optional field undefined resolves with `{ skipped }` and\n * registerConformance reports it (console.warn by default) — a law the kit\n * did not verify is never a silent green. A RECOMMENDATION the modeler does\n * not follow resolves with `{ advisories }`, reported the same way and never\n * a failure: a recommendation becomes a law only in a major release.\n */\nimport {\n apiVersionsCompatible,\n type CollaborativeModeler,\n type ElementBounds,\n type ElementsSurface,\n MODELER_API_VERSION,\n} from \"./index.js\";\n\nexport { apiVersionsCompatible };\n\nexport interface UserMutation {\n /** names the failing mutation in the kit's error message */\n name: string;\n run(modeler: CollaborativeModeler): Promise<void> | void;\n}\n\nexport interface ConformanceHarness {\n /**\n * a fresh EDITABLE modeler, attached to a host element that is IN the\n * document with a non-zero size (`attachedHost()` below) — diagram-js\n * engines compute viewboxes from the host's client size, so a detached\n * or 0×0 host yields NaN view state; they also need a real browser\n * (vitest browser mode / Playwright), jsdom has no getBBox. Keep\n * `fitOnImport` at its default: the L5 cases check the modeler's own fit\n */\n create(): Promise<CollaborativeModeler>;\n /** a fresh READ-ONLY instance (`meta.editable === false`) — the viewer\n * mount hosts use on read-only surfaces; absent = the package ships no\n * viewer and the viewer case is reported as skipped */\n createReadonly?(): Promise<CollaborativeModeler>;\n /**\n * CANONICAL sample documents of the notation (>= 2, distinct, at least one\n * rendering an element, ideally several covering config/axis content too)\n * — exactly what exportText emits. Obtain them by exporting a hand-authored\n * document and REVIEWING the bytes, not by pasting whatever the current\n * build prints: L2 only proves the serializer is a fixpoint of the texts\n * you vouch for\n */\n canonicalTexts: string[];\n /** importable but non-canonical inputs (hand-authored variants); the kit\n * verifies canonicalization is IDEMPOTENT on them, not byte-stable.\n * `undefined` = skipped; `[]` = the notation has no loose form */\n looseTexts?: string[];\n /**\n * NON-importable inputs (half-typed peer text, wrong notation) — the kit\n * verifies importText REJECTS, leaves no trace and stays usable (L7).\n * `undefined` = not provided (the L7 cases report a SKIP); `[]` = the\n * deliberate statement that this notation has no LISTED non-importable\n * text (the lenient line DSLs keep every line, so nothing rejects). The\n * probes below run either way, so a parser that does reject some input\n * is held to L7 on it\n */\n invalidTexts?: string[];\n /**\n * extra inputs for the L7 probe case, on top of the probes the kit derives\n * from every canonical text: its first half, its first third, the text\n * without its last character and the text followed by a NUL character.\n * Unlike `invalidTexts`, a probe need not reject: one that imports must\n * be silent (L1) with `exportText` total (L6), one that rejects must leave\n * no trace (L7). Add the damaged forms your parser is likely to meet (a\n * cut-off JSON object, an unclosed block). `undefined` and `[]` both mean\n * \"the derived probes only\" — the probe case never skips\n */\n probeTexts?: string[];\n /**\n * importable documents carrying content the modeler does NOT understand\n * (vendor extensions, unknown lines, unknown JSON keys), each with the\n * fragments that must come back from an import → export round-trip (L6).\n * `undefined` = skipped; `[]` = the notation has no foreign form\n */\n foreignTexts?: Array<{ text: string; mustSurvive: string[] }>;\n /**\n * a NON-default view state the modeler accepts — a panned/zoomed viewport\n * (e.g. a viewbox) that differs from what an import leaves; L5 cannot tell\n * a restore from a no-op without one. The kit never compares a readback\n * with this literal: it sets it, reads the modeler's own (possibly\n * normalised) state back, and requires THAT to survive a re-import and to\n * be settable itself. `undefined` = L5 is reported as skipped\n */\n viewState?: unknown;\n /** wait until deferred/debounced change events have been delivered —\n * MUST outlast the modeler's event debounce; defaults to one macrotask */\n settle?(): Promise<void>;\n /**\n * perform ONE user-visible atomic ELEMENT command through the modeler's\n * own commands: ADD an element — never rename or delete one (the elements\n * cases treat it as an edit unrelated to the existing elements and compare\n * the ids two instances allocate for it, and L4 builds undo history from\n * it, so it must be undoable). Let each call's element differ in content\n * from the previous one (a counter the harness shares across instances,\n * as the reference harness does): the collision case compares the ids two\n * fresh instances allocate for one new element each, and an id derived\n * from identical content (one that spells out the element's name)\n * collides by design. The kit also runs it once on a\n * fresh instance BEFORE the first import; a throw there is tolerated, and\n * so is a call that never settles (a mutate waiting for the change event\n * of a command the modeler ignores without a document): the kit stops\n * waiting after 2 s — what a command does without a document is the\n * modeler's choice\n */\n mutate(modeler: CollaborativeModeler): Promise<void> | void;\n /**\n * user-visible changes that do NOT run through an element command:\n * config/axis/title/style/size edits that live in the document. A notation\n * with such surfaces MUST list them — the kit cannot see what the canvas\n * offers, and a modeler that only forwards its command stack passes\n * `mutate` while a host loses exactly these edits. `undefined` = skipped;\n * `[]` = the notation has no such surface\n */\n configMutations?: UserMutation[];\n /** trigger the modeler's undo; `undefined` = the notation has no undo\n * (the undo cases are reported as skipped) */\n undo?(modeler: CollaborativeModeler): Promise<void> | void;\n /** trigger the modeler's redo; `undefined` with `undo` defined = the redo\n * half of the undo/redo case is reported as skipped */\n redo?(modeler: CollaborativeModeler): Promise<void> | void;\n /**\n * move ONE element read from `canonicalTexts[0]` (imported, then one\n * `mutate` added an element) through the modeler's own commands, the way\n * a user drags it, far enough that its box changes position after any\n * snapping, rounding or clamping — and return that element's id\n * (ElementInfo.id). The bounds case requires `elements.bounds` to report\n * the moved box. `undefined` = that half of the bounds case is reported as\n * skipped (only when the modeler has `bounds`)\n */\n moveElement?(modeler: CollaborativeModeler): Promise<string> | string;\n /**\n * open an INTERACTION on an element of `canonicalTexts[0]` (already\n * imported) the way a user does — its label editor, or a popup with an\n * input — and type input WITHOUT committing it (no Enter, no blur). The\n * kit then imports over it (L1) and changes the view over it (L5), and\n * neither may commit it. Type the same input on every call, one the\n * serializer writes verbatim: the L5 case looks for it in the export and\n * compares what a commit writes with and without a view change in\n * between. `undefined` = the L1 and L5 interaction cases are reported as\n * skipped\n */\n openInteraction?(modeler: CollaborativeModeler): Promise<void> | void;\n /**\n * the interaction open right now — the element it edits and its\n * uncommitted input — or `undefined` when none is open. The kit reads it\n * before and after a re-import of the same text to check the RECOMMENDED\n * keep-and-reopen (an advisory, never a failure). `undefined` = that half\n * of the L1 interaction case is reported as skipped\n */\n interactionState?(modeler: CollaborativeModeler): InteractionState | undefined;\n /**\n * commit the interaction `openInteraction` opened, the way a user does\n * (Enter, or a click on the canvas). The L5 interaction case commits once\n * without a view change, proving the typed input changes the document,\n * and once after a host's view change, checking the RECOMMENDED keep-open\n * (an advisory, never a failure). `undefined` = both halves are reported\n * as skipped\n */\n commitInteraction?(modeler: CollaborativeModeler): Promise<void> | void;\n}\n\n/** an interaction in progress, as `ConformanceHarness.interactionState` reports it */\nexport interface InteractionState {\n /** the stable id of the element the interaction edits (ElementInfo.id) */\n elementId: string;\n /** the uncommitted input, when the interaction has one */\n text?: string;\n}\n\nexport interface CaseOutcome {\n /** the case could not (fully) verify its law — the harness left the field\n * it needs undefined, or the modeler has no such optional surface; the\n * reason names which */\n skipped?: string;\n /**\n * RECOMMENDED behaviour the modeler does not show. The case passed — the\n * contract only recommends what is missing (a candidate for a law in the\n * next major) — and registerConformance reports each advice through\n * `onAdvisory`, never as a failure\n */\n advisories?: string[];\n}\n\nexport interface ConformanceCase {\n name: string;\n run(harness: ConformanceHarness): Promise<CaseOutcome | void>;\n}\n\n/**\n * a host element of the given size, attached to the document — what\n * `create()` should mount into (browser only). The returned element sits\n * INSIDE a sized wrapper: the Miragon renderers restyle the container they\n * are given to 100% × 100%, which then resolves against the wrapper\n */\nexport function attachedHost(width = 800, height = 600): HTMLElement {\n const wrapper = document.createElement(\"div\");\n wrapper.style.cssText = `width:${width}px;height:${height}px;position:absolute;left:0;top:0;overflow:hidden`;\n const host = document.createElement(\"div\");\n host.style.cssText = \"width:100%;height:100%\";\n wrapper.append(host);\n document.body.append(wrapper);\n return host;\n}\n\nfunction fail(message: string): never {\n throw new Error(`modeler-api conformance: ${message}`);\n}\n\nconst skip = (reason: string): CaseOutcome => ({ skipped: reason });\n\nfunction exportOrFail(modeler: CollaborativeModeler, when: string): string {\n try {\n return modeler.exportText();\n } catch (e) {\n fail(`exportText threw ${when}: ${String(e)}`);\n }\n}\n\nconst same = (a: unknown, b: unknown): boolean => JSON.stringify(a) === JSON.stringify(b);\n\ntype BoundedElements = ElementsSurface & { bounds(id: string): ElementBounds | undefined };\n\nconst hasBounds = (elements: ElementsSurface): elements is BoundedElements =>\n typeof elements.bounds === \"function\";\n\nconst isFiniteBox = (box: ElementBounds | undefined): box is ElementBounds =>\n box !== undefined &&\n [box.x, box.y, box.width, box.height].every((n) => typeof n === \"number\" && Number.isFinite(n)) &&\n box.width >= 0 &&\n box.height >= 0;\n\nconst describeBox = (box: ElementBounds | undefined): string =>\n box === undefined\n ? \"undefined\"\n : `{ x: ${box.x}, y: ${box.y}, width: ${box.width}, height: ${box.height} }`;\n\n/** every listed element's box, copied — a listed id without a finite box fails */\nfunction boxesOf(elements: BoundedElements, when: string): Map<string, ElementBounds> {\n const boxes = new Map<string, ElementBounds>();\n for (const { id } of elements.list()) {\n const box = elements.bounds(id);\n if (!isFiniteBox(box)) {\n fail(\n `elements.bounds('${id}') ${when} is ${describeBox(box)} — every listed id must give a finite box with a non-negative size`,\n );\n }\n boxes.set(id, { x: box.x, y: box.y, width: box.width, height: box.height });\n }\n return boxes;\n}\n\n/** a view state with NaN/Infinity is what a detached or 0×0 host produces */\nfunction assertFinite(state: unknown, when: string): void {\n const json = JSON.stringify(state, (_k, v: unknown) =>\n typeof v === \"number\" && !Number.isFinite(v) ? \"__non_finite__\" : v,\n );\n if (json?.includes(\"__non_finite__\")) {\n fail(\n `getViewState() ${when} contains a non-finite number — the host has no size (mount into attachedHost())`,\n );\n }\n}\n\nconst defaultSettle = (): Promise<void> => new Promise((resolve) => setTimeout(resolve, 0));\n\n/** how long the pre-import case waits for `mutate` on an instance without a document */\nconst PRE_IMPORT_CALL_BOUND_MS = 2000;\n\n/** run a harness call whose throw and whose hang are both tolerated: it gets\n * `ms` to settle, then the kit moves on (the call may keep running) */\nasync function toleratedCall(action: () => Promise<void> | void, ms: number): Promise<void> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const call = Promise.resolve()\n .then(action)\n .catch(() => undefined);\n const bound = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, ms);\n });\n try {\n await Promise.race([call, bound]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** count invocations of onContentChanged around an action — settle-aware, so\n * debounced engines neither hide an echo nor fail a legitimate event; the\n * export seen INSIDE the last delivery is returned too (L3's ordering rule) */\nasync function changeEvents(\n harness: ConformanceHarness,\n modeler: CollaborativeModeler,\n action: () => Promise<void> | void,\n): Promise<{ calls: number; exportAtEmit: string | undefined }> {\n const settle = harness.settle ?? defaultSettle;\n let calls = 0;\n let exportAtEmit: string | undefined;\n const off = modeler.onContentChanged(() => {\n calls += 1;\n exportAtEmit = modeler.exportText();\n });\n try {\n await action();\n await settle();\n } finally {\n off();\n }\n return { calls, exportAtEmit };\n}\n\n/** an id or a name reduced to its letters and digits, lower case — `component_new_component` and\n * `New Component` share `newcomponent` */\nconst lettersAndDigits = (value: string): string => value.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, \"\");\n\nconst secondText = (h: ConformanceHarness): string => h.canonicalTexts[1] ?? h.canonicalTexts[0] ?? \"\";\n\n/** the harness's user mutations: the element command first, then every config edit */\nconst mutationsOf = (h: ConformanceHarness): UserMutation[] => [\n { name: \"mutate (element command)\", run: (m) => h.mutate(m) },\n ...(h.configMutations ?? []),\n];\n\nconst sortedIds = (m: CollaborativeModeler): string[] | undefined =>\n m.elements ? [...m.elements.list().map((e) => e.id)].sort() : undefined;\n\n/** element id → name; `undefined` without an elements surface */\nconst namesById = (m: CollaborativeModeler): Map<string, string | undefined> | undefined =>\n m.elements ? new Map(m.elements.list().map((e) => [e.id, e.name])) : undefined;\n\nasync function importOrFail(m: CollaborativeModeler, text: string, failure: string): Promise<void> {\n await m.importText(text).catch((e: unknown) => fail(`${failure}: ${String(e)}`));\n}\n\ninterface Probe {\n /** where the probe comes from, for the failure message */\n label: string;\n text: string;\n}\n\nconst describeProbe = (probe: Probe): string => {\n const excerpt = probe.text.length > 40 ? `${probe.text.slice(0, 40)}…` : probe.text;\n return `${probe.label} (${JSON.stringify(excerpt)})`;\n};\n\n/**\n * damaged forms of every canonical text — what a host re-imports while a\n * peer is still typing (cut mid-way, the last character missing) or after a\n * transport glitch (a trailing NUL) — plus the harness's own probeTexts.\n * Cuts fall on code points, never inside a surrogate pair; duplicates are\n * dropped so each input runs once\n */\nfunction probesOf(h: ConformanceHarness): Probe[] {\n const probes: Probe[] = [];\n h.canonicalTexts.forEach((text, index) => {\n const source = `canonicalTexts[${index}]`;\n const codePoints = Array.from(text);\n const cut = (length: number): string => codePoints.slice(0, length).join(\"\");\n probes.push(\n { label: `the first half of ${source}`, text: cut(Math.floor(codePoints.length / 2)) },\n { label: `the first third of ${source}`, text: cut(Math.floor(codePoints.length / 3)) },\n { label: `${source} without its last character`, text: cut(codePoints.length - 1) },\n { label: `${source} followed by a NUL character`, text: `${text}\\u0000` },\n );\n });\n (h.probeTexts ?? []).forEach((text, index) => probes.push({ label: `probeTexts[${index}]`, text }));\n const seen = new Set<string>();\n return probes.filter((probe) => {\n if (seen.has(probe.text)) return false;\n seen.add(probe.text);\n return true;\n });\n}\n\n/**\n * import the first canonical text that renders at least one element (an\n * empty document has no fitted view — renderers leave the viewport alone),\n * and return it; without an elements surface the first text is used\n */\nasync function importContentText(h: ConformanceHarness, m: CollaborativeModeler): Promise<string> {\n for (const text of h.canonicalTexts) {\n await m.importText(text);\n if (!m.elements || m.elements.list().length > 0) return text;\n }\n fail(\"L5 needs a canonical text that renders at least one element — an empty document has no fitted view\");\n}\n\nexport function conformanceCases(): ConformanceCase[] {\n return [\n {\n name: \"meta declares the notation, editability and a compatible apiVersion\",\n async run(h) {\n const m = await h.create();\n try {\n if (!m.meta.notation) fail(\"meta.notation is empty\");\n if (m.meta.editable !== true)\n fail(\"create() must return an EDITABLE modeler (meta.editable === true)\");\n if (!apiVersionsCompatible(m.meta.apiVersion, MODELER_API_VERSION)) {\n fail(`apiVersion ${m.meta.apiVersion} is not compatible with ${MODELER_API_VERSION}`);\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"calls before the first import never wedge the instance\",\n async run(h) {\n const m = await h.create();\n let control: CollaborativeModeler | undefined;\n try {\n // what these return without a document is the modeler's choice —\n // only the instance has to survive them\n try {\n m.exportText();\n } catch {\n // a throw before the first import is allowed\n }\n await toleratedCall(() => h.mutate(m), PRE_IMPORT_CALL_BOUND_MS);\n await (h.settle ?? defaultSettle)();\n control = await h.create();\n const texts = h.canonicalTexts.length > 0 ? h.canonicalTexts.slice(0, 2) : [\"\"];\n let last = \"\";\n for (const [index, text] of texts.entries()) {\n const source = `canonicalTexts[${index}]`;\n // the oracle is a fresh instance's export of the same text: this\n // case isolates the pre-import calls — a non-canonical serializer\n // fails L2, not here\n await control.importText(text);\n const expected = exportOrFail(control, `after importing ${source} into a fresh instance`);\n await importOrFail(\n m,\n text,\n `importText(${source}) rejected on an instance that ran exportText() and a user command before its first import (wedged)`,\n );\n last = exportOrFail(m, `after importing ${source} into an instance used before its first import`);\n if (last !== expected) {\n fail(\n `importText(${source}) on an instance that ran exportText() and a user command before its first import did not render that document:\\n--- expected (a fresh instance's export)\\n${expected}\\n--- got\\n${last}`,\n );\n }\n }\n const { calls } = await changeEvents(h, m, () => h.mutate(m));\n if (calls === 0) {\n fail(\n \"a user mutation fired no onContentChanged on an instance used before its first import (wedged)\",\n );\n }\n if (exportOrFail(m, \"after a user mutation on an instance used before its first import\") === last) {\n fail(\"a user mutation did not apply on an instance used before its first import (wedged)\");\n }\n } finally {\n m.destroy();\n control?.destroy();\n }\n },\n },\n {\n name: \"L1: importText is silent (no change events, for canonical, loose and foreign inputs)\",\n async run(h) {\n const m = await h.create();\n try {\n const texts = [\n ...h.canonicalTexts,\n ...(h.looseTexts ?? []),\n ...(h.foreignTexts ?? []).map((f) => f.text),\n ];\n for (const text of texts) {\n const { calls } = await changeEvents(h, m, () => m.importText(text).then(() => undefined));\n if (calls > 0) fail(`importText fired onContentChanged ${calls}x`);\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L1: importText over EXISTING undo history is silent too\",\n async run(h) {\n // diagram-js' commandStack.clear() emits 'changed' whether or not the\n // stack is empty — but an engine that only emits when it has something\n // to clear would pass the fresh-instance case above\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const { calls } = await changeEvents(h, m, () => m.importText(secondText(h)).then(() => undefined));\n if (calls > 0) fail(`importText over a non-empty undo history fired onContentChanged ${calls}x`);\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L1: an interaction open during importText never commits\",\n async run(h) {\n if (!h.openInteraction) {\n return skip(\n \"openInteraction is undefined — an interaction open during an import (a label editor with typed input) was not verified\",\n );\n }\n const openInteraction = h.openInteraction;\n const first = h.canonicalTexts[0] ?? \"\";\n const second = h.canonicalTexts[1];\n const m = await h.create();\n try {\n // the oracles come from the modeler's OWN serializer: this case\n // isolates the interaction — a non-canonical serializer fails L2\n const legs: Array<{ text: string; expected: string; what: string }> = [];\n // a DIFFERENT document usually removes the edited element (a commit\n // would land on a removed element); the SAME document keeps it (a\n // commit would write the typed input into the re-imported document)\n if (second !== undefined) {\n await m.importText(second);\n const expected = exportOrFail(m, \"after importing canonicalTexts[1]\");\n legs.push({ text: second, expected, what: \"a different document (canonicalTexts[1])\" });\n }\n await m.importText(first);\n const firstExport = exportOrFail(m, \"after importing canonicalTexts[0]\");\n legs.push({\n text: first,\n expected: firstExport,\n what: \"the same document again (canonicalTexts[0])\",\n });\n let advice: string | undefined;\n for (const [index, leg] of legs.entries()) {\n await m.importText(first);\n await openInteraction(m);\n await (h.settle ?? defaultSettle)();\n const opened = h.interactionState?.(m);\n if (h.interactionState && opened === undefined) {\n fail(\"interactionState reports no interaction after openInteraction — the case proves nothing\");\n }\n const { calls } = await changeEvents(h, m, () => m.importText(leg.text).then(() => undefined));\n if (calls > 0) {\n fail(\n `importing ${leg.what} over an open interaction fired onContentChanged ${calls}x — the interaction committed during or because of the import (if every import emits, see the L1 cases first)`,\n );\n }\n const reopened = h.interactionState?.(m);\n if (exportOrFail(m, `after importing ${leg.what} over an open interaction`) !== leg.expected) {\n fail(\n `importing ${leg.what} over an open interaction did not leave that document — the interaction's input was applied to it`,\n );\n }\n if (h.undo) {\n await h.undo(m);\n await (h.settle ?? defaultSettle)();\n if (exportOrFail(m, `after an undo that followed importing ${leg.what}`) !== leg.expected) {\n fail(\n `undo after importing ${leg.what} over an open interaction changed the document — the interaction was committed onto the fresh undo history (L4)`,\n );\n }\n }\n const sameDocument = index === legs.length - 1;\n const kept = reopened?.elementId === opened?.elementId && reopened?.text === opened?.text;\n if (sameDocument && opened !== undefined && !kept) {\n const input = opened.text === undefined ? \"\" : ` with the input ${JSON.stringify(opened.text)}`;\n const after = reopened === undefined ? \"closed it\" : `left ${JSON.stringify(reopened)} open`;\n advice = `an interaction on '${opened.elementId}'${input} did not survive a re-import of the same document (the import ${after}) — RECOMMENDED: keep the typed input and reopen the interaction on the element with the same id, so a remote re-import does not cost the user what they were typing`;\n }\n }\n const unverified = [\n ...(second === undefined\n ? [\n \"canonicalTexts holds one text — importing a DIFFERENT document over an open interaction was not verified (add a second canonical text)\",\n ]\n : []),\n ...(h.interactionState\n ? []\n : [\n \"interactionState is undefined — the RECOMMENDED keep-and-reopen of an interaction across an import was not checked (pass interactionState to check it)\",\n ]),\n ];\n return {\n ...(unverified.length > 0 ? { skipped: unverified.join(\"; \") } : {}),\n ...(advice === undefined ? {} : { advisories: [advice] }),\n };\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L2: canonical texts are byte fixpoints of import → export\",\n async run(h) {\n if (h.canonicalTexts.length === 0) fail(\"harness provides no canonicalTexts\");\n const m = await h.create();\n try {\n for (const text of h.canonicalTexts) {\n await m.importText(text);\n const out = m.exportText();\n if (out !== text)\n fail(`export after import differs from the canonical input:\\n--- in\\n${text}\\n--- out\\n${out}`);\n if (m.exportText() !== out)\n fail(\"exportText is not deterministic — two exports of one document differ\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L2: canonicalization of loose input is idempotent\",\n async run(h) {\n if (h.looseTexts === undefined)\n return skip(\"looseTexts is undefined — pass [] if the notation has no loose form\");\n if (h.looseTexts.length === 0) return;\n const m = await h.create();\n try {\n for (const text of h.looseTexts) {\n await m.importText(text);\n const canonical = m.exportText();\n await m.importText(canonical);\n const again = m.exportText();\n if (again !== canonical) fail(\"canonicalization is not idempotent on loose input\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L3: a scripted user mutation fires onContentChanged, and the export already reflects it inside the listener\",\n async run(h) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const before = m.exportText();\n const { calls, exportAtEmit } = await changeEvents(h, m, () => h.mutate(m));\n if (calls === 0) fail(\"a user mutation fired no onContentChanged\");\n const after = m.exportText();\n if (after === before)\n fail(\"the harness mutation did not change the export — the case proves nothing\");\n if (exportAtEmit !== after) {\n fail(\n \"exportText() inside the onContentChanged listener did not return the post-change document (emit before apply)\",\n );\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L3: config/axis edits fire onContentChanged too, with the export already updated\",\n async run(h) {\n if (h.configMutations === undefined) {\n return skip(\n \"configMutations is undefined — pass [] if the notation has no config/axis/title surface\",\n );\n }\n for (const mutation of h.configMutations) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const before = m.exportText();\n const { calls, exportAtEmit } = await changeEvents(h, m, () => mutation.run(m));\n if (calls === 0) fail(`config mutation \"${mutation.name}\" fired no onContentChanged`);\n const after = m.exportText();\n if (after === before) {\n fail(`config mutation \"${mutation.name}\" did not change the export — the case proves nothing`);\n }\n if (exportAtEmit !== after) {\n fail(\n `exportText() inside the listener of config mutation \"${mutation.name}\" did not return the post-change document`,\n );\n }\n } finally {\n m.destroy();\n }\n }\n },\n },\n {\n name: \"L3: unsubscribe stops delivery\",\n async run(h) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n let calls = 0;\n const off = m.onContentChanged(() => {\n calls += 1;\n });\n off();\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n if (calls > 0) fail(\"onContentChanged delivered after unsubscribe\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L3: undo and redo fire onContentChanged and restore the export\",\n async run(h) {\n if (!h.undo) return skip(\"undo is undefined — the notation declares no undo\");\n const undo = h.undo;\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const before = m.exportText();\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const mutated = m.exportText();\n const undone = await changeEvents(h, m, () => undo(m));\n if (undone.calls === 0)\n fail(\"undo fired no onContentChanged — the host would never export the undone state\");\n if (m.exportText() !== before)\n fail(\"undo of a single mutation did not restore the pre-mutation export\");\n if (undone.exportAtEmit !== before)\n fail(\"exportText() inside the undo listener did not return the undone document\");\n if (!h.redo)\n return skip(\n \"redo is undefined — the redo half of this case was not verified (pass redo to verify it)\",\n );\n const redo = h.redo;\n const redone = await changeEvents(h, m, () => redo(m));\n if (redone.calls === 0) fail(\"redo fired no onContentChanged\");\n if (m.exportText() !== mutated) fail(\"redo did not restore the mutated export\");\n if (redone.exportAtEmit !== mutated)\n fail(\"exportText() inside the redo listener did not return the redone document\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L4: undo directly after an import is a no-op\",\n async run(h) {\n if (!h.undo) return skip(\"undo is undefined — the notation declares no undo\");\n const first = h.canonicalTexts[0];\n const second = h.canonicalTexts[1];\n if (first === undefined || second === undefined || first === second) {\n fail(\"the L4 case needs TWO DISTINCT canonicalTexts — with one, stale undo is undetectable\");\n }\n const m = await h.create();\n try {\n await m.importText(first);\n await h.mutate(m); // real history exists…\n await h.mutate(m); // …more than one entry deep…\n // leg 1 — GUARANTEED id coincidence: re-import the mutated document\n // itself. A stale diagram-js stack whose revert removes the created\n // shape by id is a silent no-op on any other document and deletes a\n // re-imported element on this one — the tt drift as it really bites\n const mutated = m.exportText();\n await m.importText(mutated);\n const baselineSame = m.exportText();\n const idsSame = sortedIds(m);\n const { calls } = await changeEvents(h, m, () => h.undo!(m));\n if (calls > 0)\n fail(\n \"undo directly after importText fired onContentChanged — history housekeeping is not a change\",\n );\n if (m.exportText() !== baselineSame || (idsSame && !same(idsSame, sortedIds(m)))) {\n fail(\n \"undo after importText removed a re-imported element by id coincidence (stale history applied)\",\n );\n }\n // leg 2 — a DIFFERENT document replaces the doc; a snapshot-restoring\n // stale stack would resurrect the previous one\n await h.mutate(m);\n await m.importText(second);\n // baseline via the modeler's OWN serializer: this case isolates the\n // undo law — a non-canonical serializer must fail L2, not here\n const baseline = m.exportText();\n await h.undo(m);\n await h.undo(m); // drain a stale multi-entry history too\n if (m.exportText() !== baseline) {\n fail(\"undo after importText mutated the freshly imported document (stale history applied)\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L5: getViewState never throws before the first import\",\n async run(h) {\n const m = await h.create();\n try {\n let state: unknown;\n try {\n state = m.getViewState();\n } catch (e) {\n fail(`getViewState threw before the first import: ${String(e)}`);\n }\n if (state !== undefined) assertFinite(state, \"before the first import\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L5: view state round-trips across a re-import, an import fits the view — and none of it is document content\",\n async run(h) {\n if (h.viewState === undefined) {\n return skip(\n \"viewState is undefined — supply a panned/zoomed state, a no-op setViewState is otherwise undetectable\",\n );\n }\n const alt = h.viewState;\n const m = await h.create();\n try {\n const text = await importContentText(h, m);\n const doc = m.exportText();\n const fitted = m.getViewState();\n assertFinite(fitted, \"after the first import\");\n // the modeler's OWN readback is the oracle from here on — a\n // diagram-js viewbox comes back rounded and enriched (scale, inner,\n // outer), never byte-equal to the harness literal\n m.setViewState(alt);\n const applied = m.getViewState();\n assertFinite(applied, \"after setViewState\");\n if (same(applied, fitted)) {\n fail(\"setViewState(viewState) had no effect — supply a state that differs from the fitted view\");\n }\n await m.importText(text);\n if (!same(m.getViewState(), fitted)) {\n fail(\n \"an import must leave the view FITTED to the content (the same state the first import produced)\",\n );\n }\n // the host restores with what IT read back before the re-import —\n // the readback must be settable and yield itself again\n const { calls } = await changeEvents(h, m, () => m.setViewState(applied));\n if (calls > 0) fail(\"setViewState fired onContentChanged — view state is not document content\");\n if (m.exportText() !== doc)\n fail(\"setViewState changed the export — view state leaked into the document\");\n if (!same(m.getViewState(), applied)) {\n fail(\n \"view state did not survive re-import + restore (setting the modeler's own readback must yield that readback)\",\n );\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L5: a host's view change never commits an open interaction\",\n async run(h) {\n if (!h.openInteraction) {\n return skip(\n \"openInteraction is undefined — a host's view change over an open interaction (a label editor with typed input) was not verified\",\n );\n }\n if (h.viewState === undefined) {\n return skip(\n \"viewState is undefined — a host's view change over an open interaction was not verified (supply a panned/zoomed state)\",\n );\n }\n const openInteraction = h.openInteraction;\n const commitInteraction = h.commitInteraction;\n const viewState = h.viewState;\n const settle = h.settle ?? defaultSettle;\n const first = h.canonicalTexts[0] ?? \"\";\n const m = await h.create();\n try {\n await m.importText(first);\n const doc = exportOrFail(m, \"after importing canonicalTexts[0]\");\n const open = async (): Promise<InteractionState | undefined> => {\n await openInteraction(m);\n await settle();\n const opened = h.interactionState?.(m);\n if (h.interactionState && opened === undefined) {\n fail(\"interactionState reports no interaction after openInteraction — the case proves nothing\");\n }\n return opened;\n };\n // the document a commit writes WITHOUT a view change: proof that the\n // typed input is real, and the oracle for the commit after one\n let committed: string | undefined;\n if (commitInteraction) {\n const typed = (await open())?.text;\n await commitInteraction(m);\n await settle();\n committed = exportOrFail(m, \"after committing the interaction\");\n if (committed === doc || (typed && !committed.includes(typed))) {\n fail(\n \"committing the interaction openInteraction opened did not write its typed input into the export — the case proves nothing (commitInteraction must commit the way a user does, openInteraction type input the serializer writes verbatim)\",\n );\n }\n await importOrFail(m, first, \"re-importing canonicalTexts[0] after the commit rejected\");\n }\n const opened = await open();\n const view = m.getViewState();\n const { calls } = await changeEvents(h, m, () => m.setViewState(viewState));\n if (calls > 0) {\n fail(\n `setViewState over an open interaction fired onContentChanged ${calls}x — the host's view change committed it (L5; if every setViewState emits, see the L5 round-trip case first)`,\n );\n }\n if (exportOrFail(m, \"after setViewState over an open interaction\") !== doc) {\n fail(\n \"setViewState over an open interaction changed the export — the host's view change committed it (L5)\",\n );\n }\n if (same(m.getViewState(), view)) {\n fail(\n \"setViewState(viewState) had no effect over an open interaction — the case proves nothing (supply a state that differs from the fitted view)\",\n );\n }\n const after = h.interactionState?.(m);\n let advice: string | undefined;\n if (\n opened !== undefined &&\n (after?.elementId !== opened.elementId || after?.text !== opened.text)\n ) {\n const input = opened.text === undefined ? \"\" : ` with the input ${JSON.stringify(opened.text)}`;\n const what = after === undefined ? \"closed it\" : `left ${JSON.stringify(after)} open`;\n advice = `an interaction on '${opened.elementId}'${input} did not survive a host's view change (setViewState ${what}) — RECOMMENDED: keep it open with its typed input, so the user's commit afterwards writes what it would have written without the view change`;\n } else if (commitInteraction && committed !== undefined) {\n await commitInteraction(m);\n await settle();\n const out = exportOrFail(m, \"after committing the interaction after a view change\");\n if (out !== committed) {\n advice = `committing an interaction after a host's view change wrote another document than committing it without one — RECOMMENDED: keep it open with its typed input across a view change (if openInteraction types different input per call, this advice is the harness's):\\n--- committed without a view change\\n${committed}\\n--- committed after setViewState\\n${out}`;\n }\n }\n return {\n ...(commitInteraction\n ? {}\n : {\n skipped:\n \"commitInteraction is undefined — that the typed input changes the document (without it the case may prove nothing) and that it still commits after the view change were not checked (pass commitInteraction to check both)\",\n }),\n ...(advice === undefined ? {} : { advisories: [advice] }),\n };\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"elements (when present): stable ids across re-imports and unrelated edits, reveal and selection semantics\",\n async run(h) {\n const m = await h.create();\n try {\n const text = h.canonicalTexts[0] ?? \"\";\n await m.importText(text);\n const elements = m.elements;\n if (!elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n const ids = elements.list().map((e) => e.id);\n if (new Set(ids).size !== ids.length) fail(\"element ids are not unique\");\n await m.importText(text);\n const again = elements.list().map((e) => e.id);\n if (!same([...ids].sort(), [...again].sort()))\n fail(\"element ids are not stable across re-imports of the same text\");\n if (elements.reveal(\"__modeler_api_no_such_id__\") !== false)\n fail(\"reveal(unknown id) must return false\");\n const firstId = ids[0];\n if (firstId !== undefined) {\n const deliveries: string[][] = [];\n const off = elements.onSelection((selected) => deliveries.push([...selected]));\n const { calls } = await changeEvents(h, m, () => {\n if (elements.reveal(firstId) !== true) fail(\"reveal(known id) must return true\");\n });\n if (calls > 0) fail(\"reveal fired onContentChanged — revealing is view behavior, not an edit\");\n if (!deliveries.some((d) => d.includes(firstId))) {\n fail(\n `reveal('${firstId}') delivered no selection containing the id — is it a selectable element (not a root or a label)?`,\n );\n }\n for (const d of deliveries) {\n for (const id of d) {\n if (!again.includes(id)) {\n fail(\n `onSelection reported an id that is not an element: '${id}' (label ids must resolve to their target)`,\n );\n }\n }\n }\n if (!elements.selection().includes(firstId)) fail(\"selection() does not contain the revealed id\");\n const seen = deliveries.length;\n off();\n // a DIFFERENT selection after the unsubscribe — re-revealing the\n // same id would be deduplicated by many engines and prove nothing\n const otherId = ids[1];\n if (otherId !== undefined) elements.reveal(otherId);\n else await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n if (deliveries.length !== seen) fail(\"onSelection delivered after unsubscribe\");\n }\n // an edit to ANOTHER element must not renumber existing ids: every id\n // still exists AND (where the notation has names) still names the\n // same element — a positional scheme keeps the id strings while\n // shifting what they point at\n const namesBefore = new Map(elements.list().map((e) => [e.id, e.name]));\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const afterEdit = new Map(elements.list().map((e) => [e.id, e.name]));\n if (afterEdit.size <= namesBefore.size) {\n fail(\n \"the harness mutate must ADD an element (the elements case verifies ids under an unrelated edit)\",\n );\n }\n for (const [id, name] of namesBefore) {\n if (!afterEdit.has(id)) {\n fail(\n `element id '${id}' vanished after an unrelated edit — ids must survive edits to other elements`,\n );\n }\n if (name !== undefined && afterEdit.get(id) !== name) {\n fail(\n `element id '${id}' names a different element after an unrelated edit ('${name}' → '${String(afterEdit.get(id))}')`,\n );\n }\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"elements (when present): ids and names survive export → import, in this and in a fresh instance\",\n async run(h) {\n const m = await h.create();\n const others: CollaborativeModeler[] = [];\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const elements = m.elements;\n if (!elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n // the element the session just created is the one an in-memory id\n // scheme gives away: its id was never read back from a text\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const session = new Map(elements.list().map((e) => [e.id, e.name]));\n const exported = exportOrFail(m, \"after a user mutation\");\n const expectSessionIds = (target: CollaborativeModeler, where: string): void => {\n const after = namesById(target);\n if (!after) fail(`${where} exposes no elements surface — the editor does`);\n for (const [id, name] of session) {\n if (!after.has(id)) {\n fail(\n `element id '${id}' is gone after export → import ${where} — the id a session reports must be the element's id in the document (write it back)`,\n );\n }\n // an empty name and an absent one are the same across the\n // serializer: the contract fixes ids, not how a parser reports\n // an element without a label\n if (name !== undefined && (after.get(id) ?? \"\") !== name) {\n fail(\n `element id '${id}' names a different element after export → import ${where} ('${name}' → '${String(after.get(id))}')`,\n );\n }\n }\n };\n await importOrFail(m, exported, \"importText rejected the modeler's own export\");\n expectSessionIds(m, \"into the same instance\");\n const fresh = await h.create();\n others.push(fresh);\n await importOrFail(fresh, exported, \"a fresh instance rejected the modeler's own export\");\n expectSessionIds(fresh, \"into a fresh instance\");\n if (h.createReadonly) {\n const viewer = await h.createReadonly();\n others.push(viewer);\n await importOrFail(viewer, exported, \"the viewer rejected the editor's export\");\n if (viewer.elements) expectSessionIds(viewer, \"into the viewer\");\n }\n } finally {\n m.destroy();\n for (const other of others) other.destroy();\n }\n },\n },\n {\n name: \"elements (when present, recommended): ids created on two peers at the same time do not collide\",\n async run(h) {\n const text = h.canonicalTexts[0] ?? \"\";\n const peers: CollaborativeModeler[] = [];\n try {\n // two peers start from the same document and each creates one\n // element — what happens when two users add an element at once\n const created: Array<Map<string, string | undefined>> = [];\n for (let count = 0; count < 2; count += 1) {\n const peer = await h.create();\n peers.push(peer);\n await peer.importText(text);\n if (!peer.elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n const before = new Set(peer.elements.list().map((e) => e.id));\n await h.mutate(peer);\n await (h.settle ?? defaultSettle)();\n const added = new Map(\n peer.elements\n .list()\n .filter((e) => !before.has(e.id))\n .map((e) => [e.id, e.name]),\n );\n if (added.size === 0) {\n fail(\n \"the harness mutate must ADD an element (the elements cases compare the ids two instances allocate)\",\n );\n }\n created.push(added);\n }\n const [\n onFirst = new Map<string, string | undefined>(),\n onSecond = new Map<string, string | undefined>(),\n ] = created;\n const shared = [...onFirst.keys()].filter((id) => onSecond.has(id));\n // an id derived from the content (OWM's component_<slug>) collides\n // when both peers create the same named element — by design, and the\n // merge reconciles identical content anyway; only an id allocated\n // regardless of the content is the recommendation's concern. An id\n // that spells out its element's name counts as derived from it\n const derivedFromContent = (id: string): boolean => {\n const name = onFirst.get(id) ?? \"\";\n if (name === \"\" || name !== (onSecond.get(id) ?? \"\")) return false;\n const spelled = lettersAndDigits(name);\n return spelled !== \"\" && lettersAndDigits(id).includes(spelled);\n };\n const allocated = shared.filter((id) => !derivedFromContent(id));\n const quoted = (ids: string[]): string => ids.map((id) => `'${id}'`).join(\", \");\n if (allocated.length > 0) {\n return {\n advisories: [\n `two instances that imported the same document and each created one element, not of the same name, allocated the same id (${quoted(allocated)}) — RECOMMENDED: allocate ids for new elements that do not collide across peers (random or peer-scoped, not a per-instance counter); once both edits merge, two elements share one id`,\n ],\n };\n }\n if (shared.length > 0) {\n return skip(\n `both instances created an element of the same name and allocated the same id, one derived from that name (${quoted(shared)}) — such ids collide for identical content by design, so the check is inconclusive: let mutate's elements differ in content (a counter the harness shares across instances)`,\n );\n }\n } finally {\n for (const peer of peers) peer.destroy();\n }\n },\n },\n {\n name: \"elements.bounds (when present): a finite box in diagram coordinates for every listed id, undefined for an unknown one, live after a new element and a move\",\n async run(h) {\n const text = h.canonicalTexts[0] ?? \"\";\n const settle = h.settle ?? defaultSettle;\n const m = await h.create();\n let viewer: CollaborativeModeler | undefined;\n try {\n await m.importText(text);\n const elements = m.elements;\n if (!elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n if (!hasBounds(elements))\n return skip(\"the modeler exposes no elements.bounds (optional) — nothing to verify\");\n boxesOf(elements, \"after an import\");\n if (elements.bounds(\"__modeler_api_no_such_id__\") !== undefined)\n fail(\"elements.bounds(unknown id) must return undefined\");\n // what a box cached at the last import gives away: an element the\n // session created has none, a moved one keeps its old position\n const imported = new Set(elements.list().map((e) => e.id));\n await h.mutate(m);\n await settle();\n for (const { id } of elements.list().filter((e) => !imported.has(e.id))) {\n const box = elements.bounds(id);\n if (!isFiniteBox(box)) {\n fail(\n `elements.bounds('${id}') of an element created in the session is ${describeBox(box)} — bounds must read the live canvas, not the last import`,\n );\n }\n }\n const unverified: string[] = [];\n if (h.moveElement) {\n const before = boxesOf(elements, \"before a move\");\n const movedId = await h.moveElement(m);\n await settle();\n const was = before.get(movedId);\n if (was === undefined)\n fail(`moveElement returned '${movedId}', an id elements.list() did not report before the move`);\n const box = boxesOf(elements, \"after a move\").get(movedId);\n if (box === undefined)\n fail(`'${movedId}' is gone from elements.list() after moveElement moved it`);\n if (box.x === was.x && box.y === was.y) {\n fail(\n `elements.bounds('${movedId}') did not follow a move made through the modeler's own commands (still ${describeBox(was)}) — bounds must read the live canvas, not the last import (or moveElement did not move the element)`,\n );\n }\n } else {\n unverified.push(\"moveElement is undefined — that a box follows a move was not verified\");\n }\n if (h.viewState !== undefined) {\n const atRest = boxesOf(elements, \"before a view change\");\n m.setViewState(h.viewState);\n for (const [id, box] of boxesOf(elements, \"after setViewState\")) {\n if (!same(box, atRest.get(id))) {\n fail(\n `elements.bounds('${id}') changed with the view (${describeBox(atRest.get(id))} → ${describeBox(box)}) — boxes are in diagram coordinates, which zoom and scroll leave alone`,\n );\n }\n }\n } else {\n unverified.push(\n \"viewState is undefined — that boxes are independent of the view was not verified\",\n );\n }\n if (h.createReadonly) {\n viewer = await h.createReadonly();\n await importOrFail(viewer, text, \"the viewer rejected canonicalTexts[0]\");\n if (viewer.elements && hasBounds(viewer.elements)) {\n boxesOf(viewer.elements, \"on the viewer after an import\");\n if (viewer.elements.bounds(\"__modeler_api_no_such_id__\") !== undefined)\n fail(\"the viewer's elements.bounds(unknown id) must return undefined\");\n }\n }\n if (unverified.length > 0) return skip(unverified.join(\"; \"));\n } finally {\n m.destroy();\n viewer?.destroy();\n }\n },\n },\n {\n name: \"L6: export is total after imports, user mutations and undo\",\n async run(h) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n for (const mutation of mutationsOf(h)) {\n await mutation.run(m);\n exportOrFail(m, `after ${mutation.name}`);\n }\n if (h.undo) {\n await h.undo(m);\n exportOrFail(m, \"after an undo\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L6: foreign content survives an import → export round-trip\",\n async run(h) {\n if (h.foreignTexts === undefined) {\n return skip(\"foreignTexts is undefined — pass [] if the notation has no foreign form\");\n }\n if (h.foreignTexts.length === 0) return;\n const m = await h.create();\n try {\n await foreignRoundTrips(h, m, \"\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L7: a rejected import leaves no trace\",\n async run(h) {\n if (h.invalidTexts === undefined) {\n return skip(\"invalidTexts is undefined — pass [] if the notation has no non-importable text\");\n }\n if (h.invalidTexts.length === 0) return;\n const m = await h.create();\n try {\n const text = h.canonicalTexts[0] ?? \"\";\n await m.importText(text);\n const beforeEdit = m.exportText();\n // with undo history on the stack: a rejected import must leave it\n // intact too (an engine that erases history BEFORE parsing does not)\n if (h.undo) {\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n }\n const doc = m.exportText();\n const ids = sortedIds(m);\n for (const bad of h.invalidTexts) {\n let rejected = false;\n const { calls } = await changeEvents(h, m, () =>\n m.importText(bad).then(\n () => undefined,\n () => {\n rejected = true;\n },\n ),\n );\n if (!rejected) fail(\"importText resolved for a non-importable input — it must REJECT\");\n if (calls > 0) fail(\"a rejected import fired onContentChanged\");\n if (m.exportText() !== doc)\n fail(\"a rejected import changed the document — the previous state must stay intact\");\n if (ids && !same(ids, sortedIds(m))) {\n fail(\n \"a rejected import changed the rendered elements — the canvas must keep the previous document\",\n );\n }\n }\n if (h.undo) {\n await h.undo(m);\n if (m.exportText() !== beforeEdit) {\n fail(\n \"a rejected import erased the undo history — the previous document's history must stay intact\",\n );\n }\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L7: the modeler stays usable after a rejected import\",\n async run(h) {\n if (h.invalidTexts === undefined) {\n return skip(\"invalidTexts is undefined — pass [] if the notation has no non-importable text\");\n }\n const bad = h.invalidTexts[0];\n if (bad === undefined) return;\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n await m.importText(bad).then(\n () => fail(\"importText resolved for a non-importable input — it must REJECT\"),\n () => undefined,\n );\n const next = secondText(h);\n await m\n .importText(next)\n .catch((e) => fail(`the next VALID import after a rejection did not render: ${String(e)}`));\n if (m.exportText() !== next)\n fail(\"the next valid import after a rejection did not replace the document\");\n const before = m.exportText();\n const { calls } = await changeEvents(h, m, () => h.mutate(m));\n if (calls === 0) fail(\"a user mutation after a rejected import fired no onContentChanged (wedged)\");\n if (exportOrFail(m, \"after a mutation that followed a rejected import\") === before) {\n fail(\"a user mutation after a rejected import did not apply (wedged)\");\n }\n if (h.undo) {\n await h.undo(m);\n exportOrFail(m, \"after an undo that followed a rejected import\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L7: every rejection of a derived probe leaves no trace\",\n async run(h) {\n const base = h.canonicalTexts[0] ?? \"\";\n const m = await h.create();\n try {\n await m.importText(base);\n // the baseline comes from the modeler's OWN serializer: this case\n // isolates the rejection path — a non-canonical serializer fails L2\n const baseline = exportOrFail(m, \"after importing canonicalTexts[0]\");\n const baseIds = sortedIds(m);\n let previous: Probe | undefined;\n const reimportBase = async (): Promise<void> => {\n if (previous === undefined) return;\n const after = `after importing ${describeProbe(previous)}`;\n await importOrFail(m, base, `the next valid import ${after} did not render`);\n const doc = exportOrFail(m, `on the next valid import ${after}`);\n if (doc !== baseline || (baseIds && !same(baseIds, sortedIds(m)))) {\n fail(`the next valid import ${after} did not replace the document (wedged)`);\n }\n };\n const mutateAndExpectApplied = async (): Promise<string> => {\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const doc = exportOrFail(m, \"after a user mutation\");\n if (doc === baseline) {\n fail(\n previous === undefined\n ? \"the harness mutation did not change the export — the case proves nothing\"\n : `a user mutation after importing ${describeProbe(previous)} did not apply (wedged)`,\n );\n }\n return doc;\n };\n for (const probe of probesOf(h)) {\n await reimportBase();\n // a document WITH undo history: a rejection must keep both\n const doc = await mutateAndExpectApplied();\n const ids = sortedIds(m);\n const what = `importText(${describeProbe(probe)})`;\n let rejected = false;\n const { calls } = await changeEvents(h, m, () =>\n m.importText(probe.text).then(\n () => undefined,\n () => {\n rejected = true;\n },\n ),\n );\n if (rejected) {\n if (calls > 0) fail(`a rejected ${what} fired onContentChanged ${calls}x (L7)`);\n if (exportOrFail(m, `after a rejected ${what}`) !== doc) {\n fail(`a rejected ${what} changed the document — the previous state must stay intact (L7)`);\n }\n if (ids && !same(ids, sortedIds(m))) {\n fail(\n `a rejected ${what} changed the rendered elements — the canvas must keep the previous document (L7)`,\n );\n }\n if (h.undo) {\n await h.undo(m);\n if (exportOrFail(m, `after an undo that followed a rejected ${what}`) !== baseline) {\n fail(\n `a rejected ${what} erased the undo history — the previous document's history must stay intact (L7)`,\n );\n }\n }\n } else {\n if (calls > 0)\n fail(`${what} resolved and fired onContentChanged ${calls}x — an import is silent (L1)`);\n exportOrFail(m, `after ${what} resolved (L6)`);\n }\n previous = probe;\n }\n await reimportBase();\n await mutateAndExpectApplied();\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"viewer (when shipped): read-only, silent, canonical, fits, reveals, keeps foreign content, unshaken by a rejected import\",\n async run(h) {\n if (!h.createReadonly) return skip(\"createReadonly is undefined — the package ships no viewer mount\");\n const v = await h.createReadonly();\n try {\n if (v.meta.editable !== false)\n fail(\"createReadonly() must return a viewer (meta.editable === false)\");\n try {\n const fresh = v.getViewState();\n if (fresh !== undefined) assertFinite(fresh, \"on the viewer before the first import\");\n } catch (e) {\n fail(`the viewer's getViewState threw before the first import: ${String(e)}`);\n }\n let calls = 0;\n const off = v.onContentChanged(() => {\n calls += 1;\n });\n try {\n for (const text of h.canonicalTexts) {\n await v\n .importText(text)\n .catch((e) => fail(`the viewer rejected a canonical text: ${String(e)}`));\n if (exportOrFail(v, \"on the viewer\") !== text)\n fail(\"the viewer's export is not the canonical text\");\n }\n const doc = v.exportText();\n const ids = sortedIds(v);\n if (v.elements) {\n const firstId = v.elements.list()[0]?.id;\n if (firstId !== undefined) {\n const deliveries: string[][] = [];\n const offSel = v.elements.onSelection((s) => deliveries.push([...s]));\n if (v.elements.reveal(firstId) !== true)\n fail(\"the viewer's reveal(known id) must return true\");\n await (h.settle ?? defaultSettle)();\n if (!deliveries.some((d) => d.includes(firstId)))\n fail(\"the viewer's reveal delivered no selection containing the id\");\n if (!v.elements.selection().includes(firstId))\n fail(\"the viewer's selection() does not contain the revealed id\");\n offSel();\n }\n if (v.elements.reveal(\"__modeler_api_no_such_id__\") !== false)\n fail(\"the viewer's reveal(unknown id) must return false\");\n }\n for (const bad of h.invalidTexts ?? []) {\n await v.importText(bad).then(\n () => fail(\"the viewer resolved a non-importable input — it must REJECT\"),\n () => undefined,\n );\n if (v.exportText() !== doc) fail(\"a rejected import changed the viewer's document\");\n if (ids && !same(ids, sortedIds(v)))\n fail(\"a rejected import changed the viewer's rendered elements\");\n }\n await foreignRoundTrips(h, v, \"the viewer's \");\n if (h.viewState !== undefined) {\n const text = await importContentText(h, v);\n const fitted = v.getViewState();\n assertFinite(fitted, \"on the viewer after import\");\n v.setViewState(h.viewState);\n const applied = v.getViewState();\n if (same(applied, fitted)) fail(\"the viewer's setViewState had no effect\");\n await v.importText(text);\n if (!same(v.getViewState(), fitted))\n fail(\"the viewer's import must leave the view fitted (L5)\");\n v.setViewState(applied);\n if (!same(v.getViewState(), applied))\n fail(\"setting the viewer's own readback did not yield that readback\");\n }\n await (h.settle ?? defaultSettle)();\n if (calls > 0)\n fail(`the viewer fired onContentChanged ${calls}x — a viewer never changes content`);\n } finally {\n off();\n }\n } finally {\n v.destroy();\n v.destroy(); // must not throw — same as the editor\n }\n },\n },\n {\n name: \"destroy is safe to call twice\",\n async run(h) {\n const m = await h.create();\n m.destroy();\n m.destroy(); // must not throw\n },\n },\n ];\n}\n\n/** the L6 foreign-content round-trips, on an editor or a viewer */\nasync function foreignRoundTrips(h: ConformanceHarness, m: CollaborativeModeler, who: string): Promise<void> {\n for (const { text, mustSurvive } of h.foreignTexts ?? []) {\n if (mustSurvive.length === 0) fail(\"a foreignTexts entry must name at least one fragment in mustSurvive\");\n await m.importText(text); // warnings allowed — a throw is the violation\n const first = exportOrFail(m, `${who}after importing a document with foreign content`);\n for (const fragment of mustSurvive) {\n if (!first.includes(fragment))\n fail(`${who}foreign content was dropped on import → export: '${fragment}' is missing`);\n }\n await m.importText(first);\n const second = exportOrFail(m, `${who}after re-importing its own export of foreign content`);\n if (second !== first) fail(`${who}foreign content did not survive a second import → export round-trip`);\n }\n}\n\nexport interface RegisterOptions {\n /** how a SKIPPED case is reported — a law the kit could not (fully) verify\n * because the harness left its field undefined. Default: console.warn */\n onSkip?: (caseName: string, reason: string) => void;\n /** how an ADVISORY is reported — a RECOMMENDED behaviour the modeler does\n * not show; the case still passes. Called once per advice. Default:\n * console.warn */\n onAdvisory?: (caseName: string, advice: string) => void;\n}\n\n/** bind every case to a (name, fn) test runner — node:test, vitest, jest */\nexport function registerConformance(\n harness: ConformanceHarness,\n test: (name: string, fn: () => Promise<void>) => unknown,\n options: RegisterOptions = {},\n): void {\n const onSkip =\n options.onSkip ??\n ((name: string, reason: string) => {\n console.warn(`modeler-api conformance: SKIPPED \"${name}\" — ${reason}`);\n });\n const onAdvisory =\n options.onAdvisory ??\n ((name: string, advice: string) => {\n console.warn(`modeler-api conformance: ADVISORY \"${name}\" — ${advice}`);\n });\n for (const conformanceCase of conformanceCases()) {\n test(`conformance: ${conformanceCase.name}`, async () => {\n const outcome = await conformanceCase.run(harness);\n if (outcome?.skipped) onSkip(conformanceCase.name, outcome.skipped);\n for (const advice of outcome?.advisories ?? []) onAdvisory(conformanceCase.name, advice);\n });\n }\n}\n"],"mappings":"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","names":["opened"]}
1
+ {"version":3,"sources":["../src/conformance.ts"],"sourcesContent":["/**\n * The conformance test kit — every law of the CollaborativeModeler contract\n * as an executable case. A modeler repo supplies a small HARNESS (how to\n * create an instance, canonical sample texts, scripted user mutations) and\n * binds the cases to its own test runner:\n *\n * import { conformanceCases, registerConformance } from \"@miragon/modeler-api/conformance\";\n * registerConformance(harness, test); // node:test, vitest, jest — any (name, fn) runner\n *\n * Cases throw plain Errors on violation, so the kit has no runner or\n * assertion-library dependency. A case that CANNOT (fully) run because the\n * harness left an optional field undefined resolves with `{ skipped }` and\n * registerConformance reports it (console.warn by default) — a law the kit\n * did not verify is never a silent green. A RECOMMENDATION the modeler does\n * not follow resolves with `{ advisories }`, reported the same way and never\n * a failure: a recommendation becomes a law only in a major release.\n */\nimport {\n apiVersionsCompatible,\n type CollaborativeModeler,\n type ElementBounds,\n type ElementsSurface,\n MODELER_API_VERSION,\n} from \"./index.js\";\n\nexport { apiVersionsCompatible };\n\nexport interface UserMutation {\n /** names the failing mutation in the kit's error message */\n name: string;\n run(modeler: CollaborativeModeler): Promise<void> | void;\n}\n\nexport interface ConformanceHarness {\n /**\n * a fresh EDITABLE modeler, attached to a host element that is IN the\n * document with a non-zero size (`attachedHost()` below) — diagram-js\n * engines compute viewboxes from the host's client size, so a detached\n * or 0×0 host yields NaN view state; they also need a real browser\n * (vitest browser mode / Playwright), jsdom has no getBBox. Keep\n * `fitOnImport` at its default: the L5 cases check the modeler's own fit\n */\n create(): Promise<CollaborativeModeler>;\n /** a fresh READ-ONLY instance (`meta.editable === false`) — the viewer\n * mount hosts use on read-only surfaces; absent = the package ships no\n * viewer and the viewer case is reported as skipped */\n createReadonly?(): Promise<CollaborativeModeler>;\n /**\n * CANONICAL sample documents of the notation (>= 2, distinct, at least one\n * rendering an element, ideally several covering config/axis content too)\n * — exactly what exportText emits. Obtain them by exporting a hand-authored\n * document and REVIEWING the bytes, not by pasting whatever the current\n * build prints: L2 only proves the serializer is a fixpoint of the texts\n * you vouch for\n */\n canonicalTexts: string[];\n /** importable but non-canonical inputs (hand-authored variants); the kit\n * verifies canonicalization is IDEMPOTENT on them, not byte-stable.\n * `undefined` = skipped; `[]` = the notation has no loose form */\n looseTexts?: string[];\n /**\n * NON-importable inputs (half-typed peer text, wrong notation) — the kit\n * verifies importText REJECTS, leaves no trace and stays usable (L7).\n * `undefined` = not provided (the L7 cases report a SKIP); `[]` = the\n * deliberate statement that this notation has no LISTED non-importable\n * text (the lenient line DSLs keep every line, so nothing rejects). The\n * probes below run either way, so a parser that does reject some input\n * is held to L7 on it\n */\n invalidTexts?: string[];\n /**\n * extra inputs for the L7 probe case, on top of the probes the kit derives\n * from every canonical text: its first half, its first third, the text\n * without its last character and the text followed by a NUL character.\n * Unlike `invalidTexts`, a probe need not reject: one that imports must\n * be silent (L1) with `exportText` total (L6), one that rejects must leave\n * no trace (L7). Add the damaged forms your parser is likely to meet (a\n * cut-off JSON object, an unclosed block). `undefined` and `[]` both mean\n * \"the derived probes only\" — the probe case never skips\n */\n probeTexts?: string[];\n /**\n * importable documents carrying content the modeler does NOT understand\n * (vendor extensions, unknown lines, unknown JSON keys), each with the\n * fragments that must come back from an import → export round-trip (L6).\n * `undefined` = skipped; `[]` = the notation has no foreign form\n */\n foreignTexts?: Array<{ text: string; mustSurvive: string[] }>;\n /**\n * a NON-default view state the modeler accepts — a panned/zoomed viewport\n * (e.g. a viewbox) that differs from what an import leaves; L5 cannot tell\n * a restore from a no-op without one. The kit never compares a readback\n * with this literal: it sets it, reads the modeler's own (possibly\n * normalised) state back, and requires THAT to survive a re-import and to\n * be settable itself. `undefined` = L5 is reported as skipped\n */\n viewState?: unknown;\n /** wait until deferred/debounced change events have been delivered —\n * MUST outlast the modeler's event debounce; defaults to one macrotask */\n settle?(): Promise<void>;\n /**\n * perform ONE user-visible atomic ELEMENT command through the modeler's\n * own commands: ADD an element — never rename or delete one (the elements\n * cases treat it as an edit unrelated to the existing elements and compare\n * the ids two instances allocate for it, and L4 builds undo history from\n * it, so it must be undoable). Let each call's element differ in content\n * from the previous one (a counter the harness shares across instances,\n * as the reference harness does): the collision case compares the ids two\n * fresh instances allocate for one new element each, and an id derived\n * from identical content (one that spells out the element's name)\n * collides by design. The kit also runs it once on a\n * fresh instance BEFORE the first import; a throw there is tolerated, and\n * so is a call that never settles (a mutate waiting for the change event\n * of a command the modeler ignores without a document): the kit stops\n * waiting after 2 s — what a command does without a document is the\n * modeler's choice\n */\n mutate(modeler: CollaborativeModeler): Promise<void> | void;\n /**\n * user-visible changes that do NOT run through an element command:\n * config/axis/title/style/size edits that live in the document. A notation\n * with such surfaces MUST list them — the kit cannot see what the canvas\n * offers, and a modeler that only forwards its command stack passes\n * `mutate` while a host loses exactly these edits. `undefined` = skipped;\n * `[]` = the notation has no such surface\n */\n configMutations?: UserMutation[];\n /** trigger the modeler's undo; `undefined` = the notation has no undo\n * (the undo cases are reported as skipped) */\n undo?(modeler: CollaborativeModeler): Promise<void> | void;\n /** trigger the modeler's redo; `undefined` with `undo` defined = the redo\n * half of the undo/redo case is reported as skipped */\n redo?(modeler: CollaborativeModeler): Promise<void> | void;\n /**\n * move ONE element read from `canonicalTexts[0]` (imported, then one\n * `mutate` added an element) through the modeler's own commands, the way\n * a user drags it, far enough that its box changes position after any\n * snapping, rounding or clamping — and return that element's id\n * (ElementInfo.id). The bounds case requires `elements.bounds` to report\n * the moved box. `undefined` = that half of the bounds case is reported as\n * skipped (only when the modeler has `bounds`)\n */\n moveElement?(modeler: CollaborativeModeler): Promise<string> | string;\n /**\n * open an INTERACTION on an element of `canonicalTexts[0]` (already\n * imported) the way a user does — its label editor, or a popup with an\n * input — and type input WITHOUT committing it (no Enter, no blur). The\n * kit then imports over it (L1) and changes the view over it (L5), and\n * neither may commit it. Type the same input on every call, one the\n * serializer writes verbatim: the L5 case looks for it in the export and\n * compares what a commit writes with and without a view change in\n * between. `undefined` = the L1 and L5 interaction cases are reported as\n * skipped\n */\n openInteraction?(modeler: CollaborativeModeler): Promise<void> | void;\n /**\n * the interaction open right now — the element it edits and its\n * uncommitted input — or `undefined` when none is open. The kit reads it\n * before and after a re-import of the same text to check the RECOMMENDED\n * keep-and-reopen (an advisory, never a failure). `undefined` = that half\n * of the L1 interaction case is reported as skipped\n */\n interactionState?(modeler: CollaborativeModeler): InteractionState | undefined;\n /**\n * commit the interaction `openInteraction` opened, the way a user does\n * (Enter, or a click on the canvas). The L5 interaction case commits once\n * without a view change, proving the typed input changes the document,\n * and once after a host's view change, checking the RECOMMENDED keep-open\n * (an advisory, never a failure). `undefined` = both halves are reported\n * as skipped\n */\n commitInteraction?(modeler: CollaborativeModeler): Promise<void> | void;\n}\n\n/** an interaction in progress, as `ConformanceHarness.interactionState` reports it */\nexport interface InteractionState {\n /** the stable id of the element the interaction edits (ElementInfo.id) */\n elementId: string;\n /** the uncommitted input, when the interaction has one */\n text?: string;\n}\n\nexport interface CaseOutcome {\n /** the case could not (fully) verify its law — the harness left the field\n * it needs undefined, or the modeler has no such optional surface; the\n * reason names which */\n skipped?: string;\n /**\n * RECOMMENDED behaviour the modeler does not show. The case passed — the\n * contract only recommends what is missing (a candidate for a law in the\n * next major) — and registerConformance reports each advice through\n * `onAdvisory`, never as a failure\n */\n advisories?: string[];\n}\n\nexport interface ConformanceCase {\n name: string;\n run(harness: ConformanceHarness): Promise<CaseOutcome | void>;\n}\n\n/**\n * a host element of the given size, attached to the document — what\n * `create()` should mount into (browser only). The returned element sits\n * INSIDE a sized wrapper: the Miragon renderers restyle the container they\n * are given to 100% × 100%, which then resolves against the wrapper\n */\nexport function attachedHost(width = 800, height = 600): HTMLElement {\n const wrapper = document.createElement(\"div\");\n wrapper.style.cssText = `width:${width}px;height:${height}px;position:absolute;left:0;top:0;overflow:hidden`;\n const host = document.createElement(\"div\");\n host.style.cssText = \"width:100%;height:100%\";\n wrapper.append(host);\n document.body.append(wrapper);\n return host;\n}\n\nfunction fail(message: string): never {\n throw new Error(`modeler-api conformance: ${message}`);\n}\n\nconst skip = (reason: string): CaseOutcome => ({ skipped: reason });\n\nfunction exportOrFail(modeler: CollaborativeModeler, when: string): string {\n try {\n return modeler.exportText();\n } catch (e) {\n fail(`exportText threw ${when}: ${String(e)}`);\n }\n}\n\nconst same = (a: unknown, b: unknown): boolean => JSON.stringify(a) === JSON.stringify(b);\n\ntype BoundedElements = ElementsSurface & { bounds(id: string): ElementBounds | undefined };\n\nconst hasBounds = (elements: ElementsSurface): elements is BoundedElements =>\n typeof elements.bounds === \"function\";\n\nconst isFiniteBox = (box: ElementBounds | undefined): box is ElementBounds =>\n box !== undefined &&\n [box.x, box.y, box.width, box.height].every((n) => typeof n === \"number\" && Number.isFinite(n)) &&\n box.width >= 0 &&\n box.height >= 0;\n\nconst describeBox = (box: ElementBounds | undefined): string =>\n box === undefined\n ? \"undefined\"\n : `{ x: ${box.x}, y: ${box.y}, width: ${box.width}, height: ${box.height} }`;\n\ntype ContentBounded = CollaborativeModeler & { contentBounds(): ElementBounds | undefined };\n\nconst hasContentBounds = (m: CollaborativeModeler): m is ContentBounded =>\n typeof m.contentBounds === \"function\";\n\n/**\n * how far a content edge may fall short of an element's edge: a box measured on the live SVG\n * (`getBBox`) comes back in float32, which rounds 123.4 to 123.4000015…, and that rounding grows\n * with the coordinate. A thousandth of a unit, or 2^-20 of the edge where that is more, stays far\n * below a pixel and far below what a stale or unsized box misses by\n */\nconst edgeTolerance = (edge: number): number => Math.max(1e-3, Math.abs(edge) * 2 ** -20);\n\nconst covers = (outer: ElementBounds, inner: ElementBounds): boolean => {\n const right = outer.x + outer.width;\n const bottom = outer.y + outer.height;\n return (\n inner.x >= outer.x - edgeTolerance(outer.x) &&\n inner.y >= outer.y - edgeTolerance(outer.y) &&\n inner.x + inner.width <= right + edgeTolerance(right) &&\n inner.y + inner.height <= bottom + edgeTolerance(bottom)\n );\n};\n\n/** `contentBounds()` copied, or `undefined` — a throw, a non-finite box or a negative size fails */\nfunction contentBoxOf(m: ContentBounded, when: string): ElementBounds | undefined {\n let box: ElementBounds | undefined;\n try {\n box = m.contentBounds();\n } catch (e) {\n fail(`contentBounds() threw ${when}: ${String(e)}`);\n }\n if (box === undefined) return undefined;\n if (!isFiniteBox(box)) {\n fail(\n `contentBounds() ${when} is ${describeBox(box)} — the content box must be finite with a non-negative size, or undefined when there is nothing to fit`,\n );\n }\n return { x: box.x, y: box.y, width: box.width, height: box.height };\n}\n\n/**\n * the content box around everything the elements surface lists: defined as\n * soon as one element is listed, and around each element's own box. An\n * element box that is itself broken is the bounds case's failure, not this one's\n */\nfunction expectContentAroundElements(m: ContentBounded, when: string): ElementBounds | undefined {\n const box = contentBoxOf(m, when);\n const listed = m.elements?.list() ?? [];\n if (box === undefined) {\n if (listed.length > 0) {\n fail(\n `contentBounds() ${when} is undefined while elements.list() reports ${listed.length} element(s) — undefined means there is nothing to fit`,\n );\n }\n return undefined;\n }\n if (m.elements && hasBounds(m.elements)) {\n for (const { id } of listed) {\n const element = m.elements.bounds(id);\n if (!isFiniteBox(element)) continue;\n if (!covers(box, element)) {\n fail(\n `contentBounds() ${when} is ${describeBox(box)}, which does not cover elements.bounds('${id}') = ${describeBox(element)} — the content box holds every element (and reads the live canvas)`,\n );\n }\n }\n }\n return box;\n}\n\n/** every listed element's box, copied — a listed id without a finite box fails */\nfunction boxesOf(elements: BoundedElements, when: string): Map<string, ElementBounds> {\n const boxes = new Map<string, ElementBounds>();\n for (const { id } of elements.list()) {\n const box = elements.bounds(id);\n if (!isFiniteBox(box)) {\n fail(\n `elements.bounds('${id}') ${when} is ${describeBox(box)} — every listed id must give a finite box with a non-negative size`,\n );\n }\n boxes.set(id, { x: box.x, y: box.y, width: box.width, height: box.height });\n }\n return boxes;\n}\n\n/** a view state with NaN/Infinity is what a detached or 0×0 host produces */\nfunction assertFinite(state: unknown, when: string): void {\n const json = JSON.stringify(state, (_k, v: unknown) =>\n typeof v === \"number\" && !Number.isFinite(v) ? \"__non_finite__\" : v,\n );\n if (json?.includes(\"__non_finite__\")) {\n fail(\n `getViewState() ${when} contains a non-finite number — the host has no size (mount into attachedHost())`,\n );\n }\n}\n\nconst defaultSettle = (): Promise<void> => new Promise((resolve) => setTimeout(resolve, 0));\n\n/** how long the pre-import case waits for `mutate` on an instance without a document */\nconst PRE_IMPORT_CALL_BOUND_MS = 2000;\n\n/** run a harness call whose throw and whose hang are both tolerated: it gets\n * `ms` to settle, then the kit moves on (the call may keep running) */\nasync function toleratedCall(action: () => Promise<void> | void, ms: number): Promise<void> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const call = Promise.resolve()\n .then(action)\n .catch(() => undefined);\n const bound = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, ms);\n });\n try {\n await Promise.race([call, bound]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** count invocations of onContentChanged around an action — settle-aware, so\n * debounced engines neither hide an echo nor fail a legitimate event; the\n * export seen INSIDE the last delivery is returned too (L3's ordering rule) */\nasync function changeEvents(\n harness: ConformanceHarness,\n modeler: CollaborativeModeler,\n action: () => Promise<void> | void,\n): Promise<{ calls: number; exportAtEmit: string | undefined }> {\n const settle = harness.settle ?? defaultSettle;\n let calls = 0;\n let exportAtEmit: string | undefined;\n const off = modeler.onContentChanged(() => {\n calls += 1;\n exportAtEmit = modeler.exportText();\n });\n try {\n await action();\n await settle();\n } finally {\n off();\n }\n return { calls, exportAtEmit };\n}\n\n/** an id or a name reduced to its letters and digits, lower case — `component_new_component` and\n * `New Component` share `newcomponent` */\nconst lettersAndDigits = (value: string): string => value.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, \"\");\n\nconst secondText = (h: ConformanceHarness): string => h.canonicalTexts[1] ?? h.canonicalTexts[0] ?? \"\";\n\n/** the harness's user mutations: the element command first, then every config edit */\nconst mutationsOf = (h: ConformanceHarness): UserMutation[] => [\n { name: \"mutate (element command)\", run: (m) => h.mutate(m) },\n ...(h.configMutations ?? []),\n];\n\nconst sortedIds = (m: CollaborativeModeler): string[] | undefined =>\n m.elements ? [...m.elements.list().map((e) => e.id)].sort() : undefined;\n\n/** element id → name; `undefined` without an elements surface */\nconst namesById = (m: CollaborativeModeler): Map<string, string | undefined> | undefined =>\n m.elements ? new Map(m.elements.list().map((e) => [e.id, e.name])) : undefined;\n\nasync function importOrFail(m: CollaborativeModeler, text: string, failure: string): Promise<void> {\n await m.importText(text).catch((e: unknown) => fail(`${failure}: ${String(e)}`));\n}\n\ninterface Probe {\n /** where the probe comes from, for the failure message */\n label: string;\n text: string;\n}\n\nconst describeProbe = (probe: Probe): string => {\n const excerpt = probe.text.length > 40 ? `${probe.text.slice(0, 40)}…` : probe.text;\n return `${probe.label} (${JSON.stringify(excerpt)})`;\n};\n\n/**\n * damaged forms of every canonical text — what a host re-imports while a\n * peer is still typing (cut mid-way, the last character missing) or after a\n * transport glitch (a trailing NUL) — plus the harness's own probeTexts.\n * Cuts fall on code points, never inside a surrogate pair; duplicates are\n * dropped so each input runs once\n */\nfunction probesOf(h: ConformanceHarness): Probe[] {\n const probes: Probe[] = [];\n h.canonicalTexts.forEach((text, index) => {\n const source = `canonicalTexts[${index}]`;\n const codePoints = Array.from(text);\n const cut = (length: number): string => codePoints.slice(0, length).join(\"\");\n probes.push(\n { label: `the first half of ${source}`, text: cut(Math.floor(codePoints.length / 2)) },\n { label: `the first third of ${source}`, text: cut(Math.floor(codePoints.length / 3)) },\n { label: `${source} without its last character`, text: cut(codePoints.length - 1) },\n { label: `${source} followed by a NUL character`, text: `${text}\\u0000` },\n );\n });\n (h.probeTexts ?? []).forEach((text, index) => probes.push({ label: `probeTexts[${index}]`, text }));\n const seen = new Set<string>();\n return probes.filter((probe) => {\n if (seen.has(probe.text)) return false;\n seen.add(probe.text);\n return true;\n });\n}\n\n/**\n * import the first canonical text that renders at least one element (an\n * empty document has no fitted view — renderers leave the viewport alone),\n * and return it; without an elements surface the first text is used\n */\nasync function importContentText(h: ConformanceHarness, m: CollaborativeModeler): Promise<string> {\n for (const text of h.canonicalTexts) {\n await m.importText(text);\n if (!m.elements || m.elements.list().length > 0) return text;\n }\n fail(\"L5 needs a canonical text that renders at least one element — an empty document has no fitted view\");\n}\n\nexport function conformanceCases(): ConformanceCase[] {\n return [\n {\n name: \"meta declares the notation, editability and a compatible apiVersion\",\n async run(h) {\n const m = await h.create();\n try {\n if (!m.meta.notation) fail(\"meta.notation is empty\");\n if (m.meta.editable !== true)\n fail(\"create() must return an EDITABLE modeler (meta.editable === true)\");\n if (!apiVersionsCompatible(m.meta.apiVersion, MODELER_API_VERSION)) {\n fail(`apiVersion ${m.meta.apiVersion} is not compatible with ${MODELER_API_VERSION}`);\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"calls before the first import never wedge the instance\",\n async run(h) {\n const m = await h.create();\n let control: CollaborativeModeler | undefined;\n try {\n // what these return without a document is the modeler's choice —\n // only the instance has to survive them\n try {\n m.exportText();\n } catch {\n // a throw before the first import is allowed\n }\n await toleratedCall(() => h.mutate(m), PRE_IMPORT_CALL_BOUND_MS);\n await (h.settle ?? defaultSettle)();\n control = await h.create();\n const texts = h.canonicalTexts.length > 0 ? h.canonicalTexts.slice(0, 2) : [\"\"];\n let last = \"\";\n for (const [index, text] of texts.entries()) {\n const source = `canonicalTexts[${index}]`;\n // the oracle is a fresh instance's export of the same text: this\n // case isolates the pre-import calls — a non-canonical serializer\n // fails L2, not here\n await control.importText(text);\n const expected = exportOrFail(control, `after importing ${source} into a fresh instance`);\n await importOrFail(\n m,\n text,\n `importText(${source}) rejected on an instance that ran exportText() and a user command before its first import (wedged)`,\n );\n last = exportOrFail(m, `after importing ${source} into an instance used before its first import`);\n if (last !== expected) {\n fail(\n `importText(${source}) on an instance that ran exportText() and a user command before its first import did not render that document:\\n--- expected (a fresh instance's export)\\n${expected}\\n--- got\\n${last}`,\n );\n }\n }\n const { calls } = await changeEvents(h, m, () => h.mutate(m));\n if (calls === 0) {\n fail(\n \"a user mutation fired no onContentChanged on an instance used before its first import (wedged)\",\n );\n }\n if (exportOrFail(m, \"after a user mutation on an instance used before its first import\") === last) {\n fail(\"a user mutation did not apply on an instance used before its first import (wedged)\");\n }\n } finally {\n m.destroy();\n control?.destroy();\n }\n },\n },\n {\n name: \"L1: importText is silent (no change events, for canonical, loose and foreign inputs)\",\n async run(h) {\n const m = await h.create();\n try {\n const texts = [\n ...h.canonicalTexts,\n ...(h.looseTexts ?? []),\n ...(h.foreignTexts ?? []).map((f) => f.text),\n ];\n for (const text of texts) {\n const { calls } = await changeEvents(h, m, () => m.importText(text).then(() => undefined));\n if (calls > 0) fail(`importText fired onContentChanged ${calls}x`);\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L1: importText over EXISTING undo history is silent too\",\n async run(h) {\n // diagram-js' commandStack.clear() emits 'changed' whether or not the\n // stack is empty — but an engine that only emits when it has something\n // to clear would pass the fresh-instance case above\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const { calls } = await changeEvents(h, m, () => m.importText(secondText(h)).then(() => undefined));\n if (calls > 0) fail(`importText over a non-empty undo history fired onContentChanged ${calls}x`);\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L1: an interaction open during importText never commits\",\n async run(h) {\n if (!h.openInteraction) {\n return skip(\n \"openInteraction is undefined — an interaction open during an import (a label editor with typed input) was not verified\",\n );\n }\n const openInteraction = h.openInteraction;\n const first = h.canonicalTexts[0] ?? \"\";\n const second = h.canonicalTexts[1];\n const m = await h.create();\n try {\n // the oracles come from the modeler's OWN serializer: this case\n // isolates the interaction — a non-canonical serializer fails L2\n const legs: Array<{ text: string; expected: string; what: string }> = [];\n // a DIFFERENT document usually removes the edited element (a commit\n // would land on a removed element); the SAME document keeps it (a\n // commit would write the typed input into the re-imported document)\n if (second !== undefined) {\n await m.importText(second);\n const expected = exportOrFail(m, \"after importing canonicalTexts[1]\");\n legs.push({ text: second, expected, what: \"a different document (canonicalTexts[1])\" });\n }\n await m.importText(first);\n const firstExport = exportOrFail(m, \"after importing canonicalTexts[0]\");\n legs.push({\n text: first,\n expected: firstExport,\n what: \"the same document again (canonicalTexts[0])\",\n });\n let advice: string | undefined;\n for (const [index, leg] of legs.entries()) {\n await m.importText(first);\n await openInteraction(m);\n await (h.settle ?? defaultSettle)();\n const opened = h.interactionState?.(m);\n if (h.interactionState && opened === undefined) {\n fail(\"interactionState reports no interaction after openInteraction — the case proves nothing\");\n }\n const { calls } = await changeEvents(h, m, () => m.importText(leg.text).then(() => undefined));\n if (calls > 0) {\n fail(\n `importing ${leg.what} over an open interaction fired onContentChanged ${calls}x — the interaction committed during or because of the import (if every import emits, see the L1 cases first)`,\n );\n }\n const reopened = h.interactionState?.(m);\n if (exportOrFail(m, `after importing ${leg.what} over an open interaction`) !== leg.expected) {\n fail(\n `importing ${leg.what} over an open interaction did not leave that document — the interaction's input was applied to it`,\n );\n }\n if (h.undo) {\n await h.undo(m);\n await (h.settle ?? defaultSettle)();\n if (exportOrFail(m, `after an undo that followed importing ${leg.what}`) !== leg.expected) {\n fail(\n `undo after importing ${leg.what} over an open interaction changed the document — the interaction was committed onto the fresh undo history (L4)`,\n );\n }\n }\n const sameDocument = index === legs.length - 1;\n const kept = reopened?.elementId === opened?.elementId && reopened?.text === opened?.text;\n if (sameDocument && opened !== undefined && !kept) {\n const input = opened.text === undefined ? \"\" : ` with the input ${JSON.stringify(opened.text)}`;\n const after = reopened === undefined ? \"closed it\" : `left ${JSON.stringify(reopened)} open`;\n advice = `an interaction on '${opened.elementId}'${input} did not survive a re-import of the same document (the import ${after}) — RECOMMENDED: keep the typed input and reopen the interaction on the element with the same id, so a remote re-import does not cost the user what they were typing`;\n }\n }\n const unverified = [\n ...(second === undefined\n ? [\n \"canonicalTexts holds one text — importing a DIFFERENT document over an open interaction was not verified (add a second canonical text)\",\n ]\n : []),\n ...(h.interactionState\n ? []\n : [\n \"interactionState is undefined — the RECOMMENDED keep-and-reopen of an interaction across an import was not checked (pass interactionState to check it)\",\n ]),\n ];\n return {\n ...(unverified.length > 0 ? { skipped: unverified.join(\"; \") } : {}),\n ...(advice === undefined ? {} : { advisories: [advice] }),\n };\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L2: canonical texts are byte fixpoints of import → export\",\n async run(h) {\n if (h.canonicalTexts.length === 0) fail(\"harness provides no canonicalTexts\");\n const m = await h.create();\n try {\n for (const text of h.canonicalTexts) {\n await m.importText(text);\n const out = m.exportText();\n if (out !== text)\n fail(`export after import differs from the canonical input:\\n--- in\\n${text}\\n--- out\\n${out}`);\n if (m.exportText() !== out)\n fail(\"exportText is not deterministic — two exports of one document differ\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L2: canonicalization of loose input is idempotent\",\n async run(h) {\n if (h.looseTexts === undefined)\n return skip(\"looseTexts is undefined — pass [] if the notation has no loose form\");\n if (h.looseTexts.length === 0) return;\n const m = await h.create();\n try {\n for (const text of h.looseTexts) {\n await m.importText(text);\n const canonical = m.exportText();\n await m.importText(canonical);\n const again = m.exportText();\n if (again !== canonical) fail(\"canonicalization is not idempotent on loose input\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L3: a scripted user mutation fires onContentChanged, and the export already reflects it inside the listener\",\n async run(h) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const before = m.exportText();\n const { calls, exportAtEmit } = await changeEvents(h, m, () => h.mutate(m));\n if (calls === 0) fail(\"a user mutation fired no onContentChanged\");\n const after = m.exportText();\n if (after === before)\n fail(\"the harness mutation did not change the export — the case proves nothing\");\n if (exportAtEmit !== after) {\n fail(\n \"exportText() inside the onContentChanged listener did not return the post-change document (emit before apply)\",\n );\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L3: config/axis edits fire onContentChanged too, with the export already updated\",\n async run(h) {\n if (h.configMutations === undefined) {\n return skip(\n \"configMutations is undefined — pass [] if the notation has no config/axis/title surface\",\n );\n }\n for (const mutation of h.configMutations) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const before = m.exportText();\n const { calls, exportAtEmit } = await changeEvents(h, m, () => mutation.run(m));\n if (calls === 0) fail(`config mutation \"${mutation.name}\" fired no onContentChanged`);\n const after = m.exportText();\n if (after === before) {\n fail(`config mutation \"${mutation.name}\" did not change the export — the case proves nothing`);\n }\n if (exportAtEmit !== after) {\n fail(\n `exportText() inside the listener of config mutation \"${mutation.name}\" did not return the post-change document`,\n );\n }\n } finally {\n m.destroy();\n }\n }\n },\n },\n {\n name: \"L3: unsubscribe stops delivery\",\n async run(h) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n let calls = 0;\n const off = m.onContentChanged(() => {\n calls += 1;\n });\n off();\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n if (calls > 0) fail(\"onContentChanged delivered after unsubscribe\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L3: undo and redo fire onContentChanged and restore the export\",\n async run(h) {\n if (!h.undo) return skip(\"undo is undefined — the notation declares no undo\");\n const undo = h.undo;\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const before = m.exportText();\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const mutated = m.exportText();\n const undone = await changeEvents(h, m, () => undo(m));\n if (undone.calls === 0)\n fail(\"undo fired no onContentChanged — the host would never export the undone state\");\n if (m.exportText() !== before)\n fail(\"undo of a single mutation did not restore the pre-mutation export\");\n if (undone.exportAtEmit !== before)\n fail(\"exportText() inside the undo listener did not return the undone document\");\n if (!h.redo)\n return skip(\n \"redo is undefined — the redo half of this case was not verified (pass redo to verify it)\",\n );\n const redo = h.redo;\n const redone = await changeEvents(h, m, () => redo(m));\n if (redone.calls === 0) fail(\"redo fired no onContentChanged\");\n if (m.exportText() !== mutated) fail(\"redo did not restore the mutated export\");\n if (redone.exportAtEmit !== mutated)\n fail(\"exportText() inside the redo listener did not return the redone document\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L4: undo directly after an import is a no-op\",\n async run(h) {\n if (!h.undo) return skip(\"undo is undefined — the notation declares no undo\");\n const first = h.canonicalTexts[0];\n const second = h.canonicalTexts[1];\n if (first === undefined || second === undefined || first === second) {\n fail(\"the L4 case needs TWO DISTINCT canonicalTexts — with one, stale undo is undetectable\");\n }\n const m = await h.create();\n try {\n await m.importText(first);\n await h.mutate(m); // real history exists…\n await h.mutate(m); // …more than one entry deep…\n // leg 1 — GUARANTEED id coincidence: re-import the mutated document\n // itself. A stale diagram-js stack whose revert removes the created\n // shape by id is a silent no-op on any other document and deletes a\n // re-imported element on this one — the tt drift as it really bites\n const mutated = m.exportText();\n await m.importText(mutated);\n const baselineSame = m.exportText();\n const idsSame = sortedIds(m);\n const { calls } = await changeEvents(h, m, () => h.undo!(m));\n if (calls > 0)\n fail(\n \"undo directly after importText fired onContentChanged — history housekeeping is not a change\",\n );\n if (m.exportText() !== baselineSame || (idsSame && !same(idsSame, sortedIds(m)))) {\n fail(\n \"undo after importText removed a re-imported element by id coincidence (stale history applied)\",\n );\n }\n // leg 2 — a DIFFERENT document replaces the doc; a snapshot-restoring\n // stale stack would resurrect the previous one\n await h.mutate(m);\n await m.importText(second);\n // baseline via the modeler's OWN serializer: this case isolates the\n // undo law — a non-canonical serializer must fail L2, not here\n const baseline = m.exportText();\n await h.undo(m);\n await h.undo(m); // drain a stale multi-entry history too\n if (m.exportText() !== baseline) {\n fail(\"undo after importText mutated the freshly imported document (stale history applied)\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L5: getViewState never throws before the first import\",\n async run(h) {\n const m = await h.create();\n try {\n let state: unknown;\n try {\n state = m.getViewState();\n } catch (e) {\n fail(`getViewState threw before the first import: ${String(e)}`);\n }\n if (state !== undefined) assertFinite(state, \"before the first import\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L5: view state round-trips across a re-import, an import fits the view — and none of it is document content\",\n async run(h) {\n if (h.viewState === undefined) {\n return skip(\n \"viewState is undefined — supply a panned/zoomed state, a no-op setViewState is otherwise undetectable\",\n );\n }\n const alt = h.viewState;\n const m = await h.create();\n try {\n const text = await importContentText(h, m);\n const doc = m.exportText();\n const fitted = m.getViewState();\n assertFinite(fitted, \"after the first import\");\n // the modeler's OWN readback is the oracle from here on — a\n // diagram-js viewbox comes back rounded and enriched (scale, inner,\n // outer), never byte-equal to the harness literal\n m.setViewState(alt);\n const applied = m.getViewState();\n assertFinite(applied, \"after setViewState\");\n if (same(applied, fitted)) {\n fail(\"setViewState(viewState) had no effect — supply a state that differs from the fitted view\");\n }\n await m.importText(text);\n if (!same(m.getViewState(), fitted)) {\n fail(\n \"an import must leave the view FITTED to the content (the same state the first import produced)\",\n );\n }\n // the host restores with what IT read back before the re-import —\n // the readback must be settable and yield itself again\n const { calls } = await changeEvents(h, m, () => m.setViewState(applied));\n if (calls > 0) fail(\"setViewState fired onContentChanged — view state is not document content\");\n if (m.exportText() !== doc)\n fail(\"setViewState changed the export — view state leaked into the document\");\n if (!same(m.getViewState(), applied)) {\n fail(\n \"view state did not survive re-import + restore (setting the modeler's own readback must yield that readback)\",\n );\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L5: a host's view change never commits an open interaction\",\n async run(h) {\n if (!h.openInteraction) {\n return skip(\n \"openInteraction is undefined — a host's view change over an open interaction (a label editor with typed input) was not verified\",\n );\n }\n if (h.viewState === undefined) {\n return skip(\n \"viewState is undefined — a host's view change over an open interaction was not verified (supply a panned/zoomed state)\",\n );\n }\n const openInteraction = h.openInteraction;\n const commitInteraction = h.commitInteraction;\n const viewState = h.viewState;\n const settle = h.settle ?? defaultSettle;\n const first = h.canonicalTexts[0] ?? \"\";\n const m = await h.create();\n try {\n await m.importText(first);\n const doc = exportOrFail(m, \"after importing canonicalTexts[0]\");\n const open = async (): Promise<InteractionState | undefined> => {\n await openInteraction(m);\n await settle();\n const opened = h.interactionState?.(m);\n if (h.interactionState && opened === undefined) {\n fail(\"interactionState reports no interaction after openInteraction — the case proves nothing\");\n }\n return opened;\n };\n // the document a commit writes WITHOUT a view change: proof that the\n // typed input is real, and the oracle for the commit after one\n let committed: string | undefined;\n if (commitInteraction) {\n const typed = (await open())?.text;\n await commitInteraction(m);\n await settle();\n committed = exportOrFail(m, \"after committing the interaction\");\n if (committed === doc || (typed && !committed.includes(typed))) {\n fail(\n \"committing the interaction openInteraction opened did not write its typed input into the export — the case proves nothing (commitInteraction must commit the way a user does, openInteraction type input the serializer writes verbatim)\",\n );\n }\n await importOrFail(m, first, \"re-importing canonicalTexts[0] after the commit rejected\");\n }\n const opened = await open();\n const view = m.getViewState();\n const { calls } = await changeEvents(h, m, () => m.setViewState(viewState));\n if (calls > 0) {\n fail(\n `setViewState over an open interaction fired onContentChanged ${calls}x — the host's view change committed it (L5; if every setViewState emits, see the L5 round-trip case first)`,\n );\n }\n if (exportOrFail(m, \"after setViewState over an open interaction\") !== doc) {\n fail(\n \"setViewState over an open interaction changed the export — the host's view change committed it (L5)\",\n );\n }\n if (same(m.getViewState(), view)) {\n fail(\n \"setViewState(viewState) had no effect over an open interaction — the case proves nothing (supply a state that differs from the fitted view)\",\n );\n }\n const after = h.interactionState?.(m);\n let advice: string | undefined;\n if (\n opened !== undefined &&\n (after?.elementId !== opened.elementId || after?.text !== opened.text)\n ) {\n const input = opened.text === undefined ? \"\" : ` with the input ${JSON.stringify(opened.text)}`;\n const what = after === undefined ? \"closed it\" : `left ${JSON.stringify(after)} open`;\n advice = `an interaction on '${opened.elementId}'${input} did not survive a host's view change (setViewState ${what}) — RECOMMENDED: keep it open with its typed input, so the user's commit afterwards writes what it would have written without the view change`;\n } else if (commitInteraction && committed !== undefined) {\n await commitInteraction(m);\n await settle();\n const out = exportOrFail(m, \"after committing the interaction after a view change\");\n if (out !== committed) {\n advice = `committing an interaction after a host's view change wrote another document than committing it without one — RECOMMENDED: keep it open with its typed input across a view change (if openInteraction types different input per call, this advice is the harness's):\\n--- committed without a view change\\n${committed}\\n--- committed after setViewState\\n${out}`;\n }\n }\n return {\n ...(commitInteraction\n ? {}\n : {\n skipped:\n \"commitInteraction is undefined — that the typed input changes the document (without it the case may prove nothing) and that it still commits after the view change were not checked (pass commitInteraction to check both)\",\n }),\n ...(advice === undefined ? {} : { advisories: [advice] }),\n };\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"elements (when present): stable ids across re-imports and unrelated edits, reveal and selection semantics\",\n async run(h) {\n const m = await h.create();\n try {\n const text = h.canonicalTexts[0] ?? \"\";\n await m.importText(text);\n const elements = m.elements;\n if (!elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n const ids = elements.list().map((e) => e.id);\n if (new Set(ids).size !== ids.length) fail(\"element ids are not unique\");\n await m.importText(text);\n const again = elements.list().map((e) => e.id);\n if (!same([...ids].sort(), [...again].sort()))\n fail(\"element ids are not stable across re-imports of the same text\");\n if (elements.reveal(\"__modeler_api_no_such_id__\") !== false)\n fail(\"reveal(unknown id) must return false\");\n const firstId = ids[0];\n if (firstId !== undefined) {\n const deliveries: string[][] = [];\n const off = elements.onSelection((selected) => deliveries.push([...selected]));\n const { calls } = await changeEvents(h, m, () => {\n if (elements.reveal(firstId) !== true) fail(\"reveal(known id) must return true\");\n });\n if (calls > 0) fail(\"reveal fired onContentChanged — revealing is view behavior, not an edit\");\n if (!deliveries.some((d) => d.includes(firstId))) {\n fail(\n `reveal('${firstId}') delivered no selection containing the id — is it a selectable element (not a root or a label)?`,\n );\n }\n for (const d of deliveries) {\n for (const id of d) {\n if (!again.includes(id)) {\n fail(\n `onSelection reported an id that is not an element: '${id}' (label ids must resolve to their target)`,\n );\n }\n }\n }\n if (!elements.selection().includes(firstId)) fail(\"selection() does not contain the revealed id\");\n const seen = deliveries.length;\n off();\n // a DIFFERENT selection after the unsubscribe — re-revealing the\n // same id would be deduplicated by many engines and prove nothing\n const otherId = ids[1];\n if (otherId !== undefined) elements.reveal(otherId);\n else await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n if (deliveries.length !== seen) fail(\"onSelection delivered after unsubscribe\");\n }\n // an edit to ANOTHER element must not renumber existing ids: every id\n // still exists AND (where the notation has names) still names the\n // same element — a positional scheme keeps the id strings while\n // shifting what they point at\n const namesBefore = new Map(elements.list().map((e) => [e.id, e.name]));\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const afterEdit = new Map(elements.list().map((e) => [e.id, e.name]));\n if (afterEdit.size <= namesBefore.size) {\n fail(\n \"the harness mutate must ADD an element (the elements case verifies ids under an unrelated edit)\",\n );\n }\n for (const [id, name] of namesBefore) {\n if (!afterEdit.has(id)) {\n fail(\n `element id '${id}' vanished after an unrelated edit — ids must survive edits to other elements`,\n );\n }\n if (name !== undefined && afterEdit.get(id) !== name) {\n fail(\n `element id '${id}' names a different element after an unrelated edit ('${name}' → '${String(afterEdit.get(id))}')`,\n );\n }\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"elements (when present): ids and names survive export → import, in this and in a fresh instance\",\n async run(h) {\n const m = await h.create();\n const others: CollaborativeModeler[] = [];\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n const elements = m.elements;\n if (!elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n // the element the session just created is the one an in-memory id\n // scheme gives away: its id was never read back from a text\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const session = new Map(elements.list().map((e) => [e.id, e.name]));\n const exported = exportOrFail(m, \"after a user mutation\");\n const expectSessionIds = (target: CollaborativeModeler, where: string): void => {\n const after = namesById(target);\n if (!after) fail(`${where} exposes no elements surface — the editor does`);\n for (const [id, name] of session) {\n if (!after.has(id)) {\n fail(\n `element id '${id}' is gone after export → import ${where} — the id a session reports must be the element's id in the document (write it back)`,\n );\n }\n // an empty name and an absent one are the same across the\n // serializer: the contract fixes ids, not how a parser reports\n // an element without a label\n if (name !== undefined && (after.get(id) ?? \"\") !== name) {\n fail(\n `element id '${id}' names a different element after export → import ${where} ('${name}' → '${String(after.get(id))}')`,\n );\n }\n }\n };\n await importOrFail(m, exported, \"importText rejected the modeler's own export\");\n expectSessionIds(m, \"into the same instance\");\n const fresh = await h.create();\n others.push(fresh);\n await importOrFail(fresh, exported, \"a fresh instance rejected the modeler's own export\");\n expectSessionIds(fresh, \"into a fresh instance\");\n if (h.createReadonly) {\n const viewer = await h.createReadonly();\n others.push(viewer);\n await importOrFail(viewer, exported, \"the viewer rejected the editor's export\");\n if (viewer.elements) expectSessionIds(viewer, \"into the viewer\");\n }\n } finally {\n m.destroy();\n for (const other of others) other.destroy();\n }\n },\n },\n {\n name: \"elements (when present, recommended): ids created on two peers at the same time do not collide\",\n async run(h) {\n const text = h.canonicalTexts[0] ?? \"\";\n const peers: CollaborativeModeler[] = [];\n try {\n // two peers start from the same document and each creates one\n // element — what happens when two users add an element at once\n const created: Array<Map<string, string | undefined>> = [];\n for (let count = 0; count < 2; count += 1) {\n const peer = await h.create();\n peers.push(peer);\n await peer.importText(text);\n if (!peer.elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n const before = new Set(peer.elements.list().map((e) => e.id));\n await h.mutate(peer);\n await (h.settle ?? defaultSettle)();\n const added = new Map(\n peer.elements\n .list()\n .filter((e) => !before.has(e.id))\n .map((e) => [e.id, e.name]),\n );\n if (added.size === 0) {\n fail(\n \"the harness mutate must ADD an element (the elements cases compare the ids two instances allocate)\",\n );\n }\n created.push(added);\n }\n const [\n onFirst = new Map<string, string | undefined>(),\n onSecond = new Map<string, string | undefined>(),\n ] = created;\n const shared = [...onFirst.keys()].filter((id) => onSecond.has(id));\n // an id derived from the content (OWM's component_<slug>) collides\n // when both peers create the same named element — by design, and the\n // merge reconciles identical content anyway; only an id allocated\n // regardless of the content is the recommendation's concern. An id\n // that spells out its element's name counts as derived from it\n const derivedFromContent = (id: string): boolean => {\n const name = onFirst.get(id) ?? \"\";\n if (name === \"\" || name !== (onSecond.get(id) ?? \"\")) return false;\n const spelled = lettersAndDigits(name);\n return spelled !== \"\" && lettersAndDigits(id).includes(spelled);\n };\n const allocated = shared.filter((id) => !derivedFromContent(id));\n const quoted = (ids: string[]): string => ids.map((id) => `'${id}'`).join(\", \");\n if (allocated.length > 0) {\n return {\n advisories: [\n `two instances that imported the same document and each created one element, not of the same name, allocated the same id (${quoted(allocated)}) — RECOMMENDED: allocate ids for new elements that do not collide across peers (random or peer-scoped, not a per-instance counter); once both edits merge, two elements share one id`,\n ],\n };\n }\n if (shared.length > 0) {\n return skip(\n `both instances created an element of the same name and allocated the same id, one derived from that name (${quoted(shared)}) — such ids collide for identical content by design, so the check is inconclusive: let mutate's elements differ in content (a counter the harness shares across instances)`,\n );\n }\n } finally {\n for (const peer of peers) peer.destroy();\n }\n },\n },\n {\n name: \"elements.bounds (when present): a finite box in diagram coordinates for every listed id, undefined for an unknown one, live after a new element and a move\",\n async run(h) {\n const text = h.canonicalTexts[0] ?? \"\";\n const settle = h.settle ?? defaultSettle;\n const m = await h.create();\n let viewer: CollaborativeModeler | undefined;\n try {\n await m.importText(text);\n const elements = m.elements;\n if (!elements)\n return skip(\"the modeler exposes no elements surface (optional) — nothing to verify\");\n if (!hasBounds(elements))\n return skip(\"the modeler exposes no elements.bounds (optional) — nothing to verify\");\n boxesOf(elements, \"after an import\");\n if (elements.bounds(\"__modeler_api_no_such_id__\") !== undefined)\n fail(\"elements.bounds(unknown id) must return undefined\");\n // what a box cached at the last import gives away: an element the\n // session created has none, a moved one keeps its old position\n const imported = new Set(elements.list().map((e) => e.id));\n await h.mutate(m);\n await settle();\n for (const { id } of elements.list().filter((e) => !imported.has(e.id))) {\n const box = elements.bounds(id);\n if (!isFiniteBox(box)) {\n fail(\n `elements.bounds('${id}') of an element created in the session is ${describeBox(box)} — bounds must read the live canvas, not the last import`,\n );\n }\n }\n const unverified: string[] = [];\n if (h.moveElement) {\n const before = boxesOf(elements, \"before a move\");\n const movedId = await h.moveElement(m);\n await settle();\n const was = before.get(movedId);\n if (was === undefined)\n fail(`moveElement returned '${movedId}', an id elements.list() did not report before the move`);\n const box = boxesOf(elements, \"after a move\").get(movedId);\n if (box === undefined)\n fail(`'${movedId}' is gone from elements.list() after moveElement moved it`);\n if (box.x === was.x && box.y === was.y) {\n fail(\n `elements.bounds('${movedId}') did not follow a move made through the modeler's own commands (still ${describeBox(was)}) — bounds must read the live canvas, not the last import (or moveElement did not move the element)`,\n );\n }\n } else {\n unverified.push(\"moveElement is undefined — that a box follows a move was not verified\");\n }\n if (h.viewState !== undefined) {\n const atRest = boxesOf(elements, \"before a view change\");\n m.setViewState(h.viewState);\n for (const [id, box] of boxesOf(elements, \"after setViewState\")) {\n if (!same(box, atRest.get(id))) {\n fail(\n `elements.bounds('${id}') changed with the view (${describeBox(atRest.get(id))} → ${describeBox(box)}) — boxes are in diagram coordinates, which zoom and scroll leave alone`,\n );\n }\n }\n } else {\n unverified.push(\n \"viewState is undefined — that boxes are independent of the view was not verified\",\n );\n }\n if (h.createReadonly) {\n viewer = await h.createReadonly();\n await importOrFail(viewer, text, \"the viewer rejected canonicalTexts[0]\");\n if (viewer.elements && hasBounds(viewer.elements)) {\n boxesOf(viewer.elements, \"on the viewer after an import\");\n if (viewer.elements.bounds(\"__modeler_api_no_such_id__\") !== undefined)\n fail(\"the viewer's elements.bounds(unknown id) must return undefined\");\n }\n }\n if (unverified.length > 0) return skip(unverified.join(\"; \"));\n } finally {\n m.destroy();\n viewer?.destroy();\n }\n },\n },\n {\n name: \"contentBounds (when present): a finite box in diagram coordinates around every listed element, live after a new element, unchanged by zoom and scroll\",\n async run(h) {\n const settle = h.settle ?? defaultSettle;\n const m = await h.create();\n let viewer: CollaborativeModeler | undefined;\n try {\n if (!hasContentBounds(m))\n return skip(\"the modeler exposes no contentBounds (optional, 1.3) — nothing to verify\");\n contentBoxOf(m, \"before the first import\");\n for (const [index, text] of h.canonicalTexts.entries()) {\n await importOrFail(m, text, `importText(canonicalTexts[${index}]) rejected`);\n expectContentAroundElements(m, `after importing canonicalTexts[${index}]`);\n }\n // a box cached at the last import gives itself away here: the\n // element the session created lies outside it, or it has none\n await importOrFail(m, h.canonicalTexts[0] ?? \"\", \"importText(canonicalTexts[0]) rejected\");\n await h.mutate(m);\n await settle();\n const atRest = expectContentAroundElements(m, \"after a user mutation added an element\");\n const unverified: string[] = [];\n if (h.viewState !== undefined) {\n m.setViewState(h.viewState);\n const viewed = contentBoxOf(m, \"after setViewState\");\n if (!same(viewed, atRest)) {\n fail(\n `contentBounds() changed with the view (${describeBox(atRest)} → ${describeBox(viewed)}) — the content box is in diagram coordinates, which zoom and scroll leave alone`,\n );\n }\n } else {\n unverified.push(\n \"viewState is undefined — that the content box is independent of the view was not verified\",\n );\n }\n if (!m.elements || !hasBounds(m.elements)) {\n unverified.push(\n \"the modeler exposes no elements.bounds — that the content box covers every element was not verified\",\n );\n }\n if (h.createReadonly) {\n viewer = await h.createReadonly();\n if (hasContentBounds(viewer)) {\n contentBoxOf(viewer, \"on the viewer before the first import\");\n await importOrFail(viewer, h.canonicalTexts[0] ?? \"\", \"the viewer rejected canonicalTexts[0]\");\n expectContentAroundElements(viewer, \"on the viewer after an import\");\n }\n }\n if (unverified.length > 0) return skip(unverified.join(\"; \"));\n } finally {\n m.destroy();\n viewer?.destroy();\n }\n },\n },\n {\n name: \"L6: export is total after imports, user mutations and undo\",\n async run(h) {\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n for (const mutation of mutationsOf(h)) {\n await mutation.run(m);\n exportOrFail(m, `after ${mutation.name}`);\n }\n if (h.undo) {\n await h.undo(m);\n exportOrFail(m, \"after an undo\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L6: foreign content survives an import → export round-trip\",\n async run(h) {\n if (h.foreignTexts === undefined) {\n return skip(\"foreignTexts is undefined — pass [] if the notation has no foreign form\");\n }\n if (h.foreignTexts.length === 0) return;\n const m = await h.create();\n try {\n await foreignRoundTrips(h, m, \"\");\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L7: a rejected import leaves no trace\",\n async run(h) {\n if (h.invalidTexts === undefined) {\n return skip(\"invalidTexts is undefined — pass [] if the notation has no non-importable text\");\n }\n if (h.invalidTexts.length === 0) return;\n const m = await h.create();\n try {\n const text = h.canonicalTexts[0] ?? \"\";\n await m.importText(text);\n const beforeEdit = m.exportText();\n // with undo history on the stack: a rejected import must leave it\n // intact too (an engine that erases history BEFORE parsing does not)\n if (h.undo) {\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n }\n const doc = m.exportText();\n const ids = sortedIds(m);\n for (const bad of h.invalidTexts) {\n let rejected = false;\n const { calls } = await changeEvents(h, m, () =>\n m.importText(bad).then(\n () => undefined,\n () => {\n rejected = true;\n },\n ),\n );\n if (!rejected) fail(\"importText resolved for a non-importable input — it must REJECT\");\n if (calls > 0) fail(\"a rejected import fired onContentChanged\");\n if (m.exportText() !== doc)\n fail(\"a rejected import changed the document — the previous state must stay intact\");\n if (ids && !same(ids, sortedIds(m))) {\n fail(\n \"a rejected import changed the rendered elements — the canvas must keep the previous document\",\n );\n }\n }\n if (h.undo) {\n await h.undo(m);\n if (m.exportText() !== beforeEdit) {\n fail(\n \"a rejected import erased the undo history — the previous document's history must stay intact\",\n );\n }\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L7: the modeler stays usable after a rejected import\",\n async run(h) {\n if (h.invalidTexts === undefined) {\n return skip(\"invalidTexts is undefined — pass [] if the notation has no non-importable text\");\n }\n const bad = h.invalidTexts[0];\n if (bad === undefined) return;\n const m = await h.create();\n try {\n await m.importText(h.canonicalTexts[0] ?? \"\");\n await m.importText(bad).then(\n () => fail(\"importText resolved for a non-importable input — it must REJECT\"),\n () => undefined,\n );\n const next = secondText(h);\n await m\n .importText(next)\n .catch((e) => fail(`the next VALID import after a rejection did not render: ${String(e)}`));\n if (m.exportText() !== next)\n fail(\"the next valid import after a rejection did not replace the document\");\n const before = m.exportText();\n const { calls } = await changeEvents(h, m, () => h.mutate(m));\n if (calls === 0) fail(\"a user mutation after a rejected import fired no onContentChanged (wedged)\");\n if (exportOrFail(m, \"after a mutation that followed a rejected import\") === before) {\n fail(\"a user mutation after a rejected import did not apply (wedged)\");\n }\n if (h.undo) {\n await h.undo(m);\n exportOrFail(m, \"after an undo that followed a rejected import\");\n }\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"L7: every rejection of a derived probe leaves no trace\",\n async run(h) {\n const base = h.canonicalTexts[0] ?? \"\";\n const m = await h.create();\n try {\n await m.importText(base);\n // the baseline comes from the modeler's OWN serializer: this case\n // isolates the rejection path — a non-canonical serializer fails L2\n const baseline = exportOrFail(m, \"after importing canonicalTexts[0]\");\n const baseIds = sortedIds(m);\n let previous: Probe | undefined;\n const reimportBase = async (): Promise<void> => {\n if (previous === undefined) return;\n const after = `after importing ${describeProbe(previous)}`;\n await importOrFail(m, base, `the next valid import ${after} did not render`);\n const doc = exportOrFail(m, `on the next valid import ${after}`);\n if (doc !== baseline || (baseIds && !same(baseIds, sortedIds(m)))) {\n fail(`the next valid import ${after} did not replace the document (wedged)`);\n }\n };\n const mutateAndExpectApplied = async (): Promise<string> => {\n await h.mutate(m);\n await (h.settle ?? defaultSettle)();\n const doc = exportOrFail(m, \"after a user mutation\");\n if (doc === baseline) {\n fail(\n previous === undefined\n ? \"the harness mutation did not change the export — the case proves nothing\"\n : `a user mutation after importing ${describeProbe(previous)} did not apply (wedged)`,\n );\n }\n return doc;\n };\n for (const probe of probesOf(h)) {\n await reimportBase();\n // a document WITH undo history: a rejection must keep both\n const doc = await mutateAndExpectApplied();\n const ids = sortedIds(m);\n const what = `importText(${describeProbe(probe)})`;\n let rejected = false;\n const { calls } = await changeEvents(h, m, () =>\n m.importText(probe.text).then(\n () => undefined,\n () => {\n rejected = true;\n },\n ),\n );\n if (rejected) {\n if (calls > 0) fail(`a rejected ${what} fired onContentChanged ${calls}x (L7)`);\n if (exportOrFail(m, `after a rejected ${what}`) !== doc) {\n fail(`a rejected ${what} changed the document — the previous state must stay intact (L7)`);\n }\n if (ids && !same(ids, sortedIds(m))) {\n fail(\n `a rejected ${what} changed the rendered elements — the canvas must keep the previous document (L7)`,\n );\n }\n if (h.undo) {\n await h.undo(m);\n if (exportOrFail(m, `after an undo that followed a rejected ${what}`) !== baseline) {\n fail(\n `a rejected ${what} erased the undo history — the previous document's history must stay intact (L7)`,\n );\n }\n }\n } else {\n if (calls > 0)\n fail(`${what} resolved and fired onContentChanged ${calls}x — an import is silent (L1)`);\n exportOrFail(m, `after ${what} resolved (L6)`);\n }\n previous = probe;\n }\n await reimportBase();\n await mutateAndExpectApplied();\n } finally {\n m.destroy();\n }\n },\n },\n {\n name: \"viewer (when shipped): read-only, silent, canonical, fits, reveals, keeps foreign content, unshaken by a rejected import\",\n async run(h) {\n if (!h.createReadonly) return skip(\"createReadonly is undefined — the package ships no viewer mount\");\n const v = await h.createReadonly();\n try {\n if (v.meta.editable !== false)\n fail(\"createReadonly() must return a viewer (meta.editable === false)\");\n try {\n const fresh = v.getViewState();\n if (fresh !== undefined) assertFinite(fresh, \"on the viewer before the first import\");\n } catch (e) {\n fail(`the viewer's getViewState threw before the first import: ${String(e)}`);\n }\n let calls = 0;\n const off = v.onContentChanged(() => {\n calls += 1;\n });\n try {\n for (const text of h.canonicalTexts) {\n await v\n .importText(text)\n .catch((e) => fail(`the viewer rejected a canonical text: ${String(e)}`));\n if (exportOrFail(v, \"on the viewer\") !== text)\n fail(\"the viewer's export is not the canonical text\");\n }\n const doc = v.exportText();\n const ids = sortedIds(v);\n if (v.elements) {\n const firstId = v.elements.list()[0]?.id;\n if (firstId !== undefined) {\n const deliveries: string[][] = [];\n const offSel = v.elements.onSelection((s) => deliveries.push([...s]));\n if (v.elements.reveal(firstId) !== true)\n fail(\"the viewer's reveal(known id) must return true\");\n await (h.settle ?? defaultSettle)();\n if (!deliveries.some((d) => d.includes(firstId)))\n fail(\"the viewer's reveal delivered no selection containing the id\");\n if (!v.elements.selection().includes(firstId))\n fail(\"the viewer's selection() does not contain the revealed id\");\n offSel();\n }\n if (v.elements.reveal(\"__modeler_api_no_such_id__\") !== false)\n fail(\"the viewer's reveal(unknown id) must return false\");\n }\n for (const bad of h.invalidTexts ?? []) {\n await v.importText(bad).then(\n () => fail(\"the viewer resolved a non-importable input — it must REJECT\"),\n () => undefined,\n );\n if (v.exportText() !== doc) fail(\"a rejected import changed the viewer's document\");\n if (ids && !same(ids, sortedIds(v)))\n fail(\"a rejected import changed the viewer's rendered elements\");\n }\n await foreignRoundTrips(h, v, \"the viewer's \");\n if (h.viewState !== undefined) {\n const text = await importContentText(h, v);\n const fitted = v.getViewState();\n assertFinite(fitted, \"on the viewer after import\");\n v.setViewState(h.viewState);\n const applied = v.getViewState();\n if (same(applied, fitted)) fail(\"the viewer's setViewState had no effect\");\n await v.importText(text);\n if (!same(v.getViewState(), fitted))\n fail(\"the viewer's import must leave the view fitted (L5)\");\n v.setViewState(applied);\n if (!same(v.getViewState(), applied))\n fail(\"setting the viewer's own readback did not yield that readback\");\n }\n await (h.settle ?? defaultSettle)();\n if (calls > 0)\n fail(`the viewer fired onContentChanged ${calls}x — a viewer never changes content`);\n } finally {\n off();\n }\n } finally {\n v.destroy();\n v.destroy(); // must not throw — same as the editor\n }\n },\n },\n {\n name: \"destroy is safe to call twice\",\n async run(h) {\n const m = await h.create();\n m.destroy();\n m.destroy(); // must not throw\n },\n },\n ];\n}\n\n/** the L6 foreign-content round-trips, on an editor or a viewer */\nasync function foreignRoundTrips(h: ConformanceHarness, m: CollaborativeModeler, who: string): Promise<void> {\n for (const { text, mustSurvive } of h.foreignTexts ?? []) {\n if (mustSurvive.length === 0) fail(\"a foreignTexts entry must name at least one fragment in mustSurvive\");\n await m.importText(text); // warnings allowed — a throw is the violation\n const first = exportOrFail(m, `${who}after importing a document with foreign content`);\n for (const fragment of mustSurvive) {\n if (!first.includes(fragment))\n fail(`${who}foreign content was dropped on import → export: '${fragment}' is missing`);\n }\n await m.importText(first);\n const second = exportOrFail(m, `${who}after re-importing its own export of foreign content`);\n if (second !== first) fail(`${who}foreign content did not survive a second import → export round-trip`);\n }\n}\n\nexport interface RegisterOptions {\n /** how a SKIPPED case is reported — a law the kit could not (fully) verify\n * because the harness left its field undefined. Default: console.warn */\n onSkip?: (caseName: string, reason: string) => void;\n /** how an ADVISORY is reported — a RECOMMENDED behaviour the modeler does\n * not show; the case still passes. Called once per advice. Default:\n * console.warn */\n onAdvisory?: (caseName: string, advice: string) => void;\n}\n\n/** bind every case to a (name, fn) test runner — node:test, vitest, jest */\nexport function registerConformance(\n harness: ConformanceHarness,\n test: (name: string, fn: () => Promise<void>) => unknown,\n options: RegisterOptions = {},\n): void {\n const onSkip =\n options.onSkip ??\n ((name: string, reason: string) => {\n console.warn(`modeler-api conformance: SKIPPED \"${name}\" — ${reason}`);\n });\n const onAdvisory =\n options.onAdvisory ??\n ((name: string, advice: string) => {\n console.warn(`modeler-api conformance: ADVISORY \"${name}\" — ${advice}`);\n });\n for (const conformanceCase of conformanceCases()) {\n test(`conformance: ${conformanceCase.name}`, async () => {\n const outcome = await conformanceCase.run(harness);\n if (outcome?.skipped) onSkip(conformanceCase.name, outcome.skipped);\n for (const advice of outcome?.advisories ?? []) onAdvisory(conformanceCase.name, advice);\n });\n }\n}\n"],"mappings":";;;;;;AA+MO,SAAS,aAAa,QAAQ,KAAK,SAAS,KAAkB;AACnE,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,MAAM,UAAU,SAAS,KAAK,aAAa,MAAM;AACzD,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,MAAM,UAAU;AACrB,UAAQ,OAAO,IAAI;AACnB,WAAS,KAAK,OAAO,OAAO;AAC5B,SAAO;AACT;AAEA,SAAS,KAAK,SAAwB;AACpC,QAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AACvD;AAEA,IAAM,OAAO,CAAC,YAAiC,EAAE,SAAS,OAAO;AAEjE,SAAS,aAAa,SAA+B,MAAsB;AACzE,MAAI;AACF,WAAO,QAAQ,WAAW;AAAA,EAC5B,SAAS,GAAG;AACV,SAAK,oBAAoB,IAAI,KAAK,OAAO,CAAC,CAAC,EAAE;AAAA,EAC/C;AACF;AAEA,IAAM,OAAO,CAAC,GAAY,MAAwB,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;AAIxF,IAAM,YAAY,CAAC,aACjB,OAAO,SAAS,WAAW;AAE7B,IAAM,cAAc,CAAC,QACnB,QAAQ,UACR,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,MAAM,EAAE,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,CAAC,KAC9F,IAAI,SAAS,KACb,IAAI,UAAU;AAEhB,IAAM,cAAc,CAAC,QACnB,QAAQ,SACJ,cACA,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,IAAI,KAAK,aAAa,IAAI,MAAM;AAI5E,IAAM,mBAAmB,CAAC,MACxB,OAAO,EAAE,kBAAkB;AAQ7B,IAAM,gBAAgB,CAAC,SAAyB,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG;AAExF,IAAM,SAAS,CAAC,OAAsB,UAAkC;AACtE,QAAM,QAAQ,MAAM,IAAI,MAAM;AAC9B,QAAM,SAAS,MAAM,IAAI,MAAM;AAC/B,SACE,MAAM,KAAK,MAAM,IAAI,cAAc,MAAM,CAAC,KAC1C,MAAM,KAAK,MAAM,IAAI,cAAc,MAAM,CAAC,KAC1C,MAAM,IAAI,MAAM,SAAS,QAAQ,cAAc,KAAK,KACpD,MAAM,IAAI,MAAM,UAAU,SAAS,cAAc,MAAM;AAE3D;AAGA,SAAS,aAAa,GAAmB,MAAyC;AAChF,MAAI;AACJ,MAAI;AACF,UAAM,EAAE,cAAc;AAAA,EACxB,SAAS,GAAG;AACV,SAAK,yBAAyB,IAAI,KAAK,OAAO,CAAC,CAAC,EAAE;AAAA,EACpD;AACA,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI,CAAC,YAAY,GAAG,GAAG;AACrB;AAAA,MACE,mBAAmB,IAAI,OAAO,YAAY,GAAG,CAAC;AAAA,IAChD;AAAA,EACF;AACA,SAAO,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO;AACpE;AAOA,SAAS,4BAA4B,GAAmB,MAAyC;AAC/F,QAAM,MAAM,aAAa,GAAG,IAAI;AAChC,QAAM,SAAS,EAAE,UAAU,KAAK,KAAK,CAAC;AACtC,MAAI,QAAQ,QAAW;AACrB,QAAI,OAAO,SAAS,GAAG;AACrB;AAAA,QACE,mBAAmB,IAAI,+CAA+C,OAAO,MAAM;AAAA,MACrF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,MAAI,EAAE,YAAY,UAAU,EAAE,QAAQ,GAAG;AACvC,eAAW,EAAE,GAAG,KAAK,QAAQ;AAC3B,YAAM,UAAU,EAAE,SAAS,OAAO,EAAE;AACpC,UAAI,CAAC,YAAY,OAAO,EAAG;AAC3B,UAAI,CAAC,OAAO,KAAK,OAAO,GAAG;AACzB;AAAA,UACE,mBAAmB,IAAI,OAAO,YAAY,GAAG,CAAC,2CAA2C,EAAE,QAAQ,YAAY,OAAO,CAAC;AAAA,QACzH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,QAAQ,UAA2B,MAA0C;AACpF,QAAM,QAAQ,oBAAI,IAA2B;AAC7C,aAAW,EAAE,GAAG,KAAK,SAAS,KAAK,GAAG;AACpC,UAAM,MAAM,SAAS,OAAO,EAAE;AAC9B,QAAI,CAAC,YAAY,GAAG,GAAG;AACrB;AAAA,QACE,oBAAoB,EAAE,MAAM,IAAI,OAAO,YAAY,GAAG,CAAC;AAAA,MACzD;AAAA,IACF;AACA,UAAM,IAAI,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO,CAAC;AAAA,EAC5E;AACA,SAAO;AACT;AAGA,SAAS,aAAa,OAAgB,MAAoB;AACxD,QAAM,OAAO,KAAK;AAAA,IAAU;AAAA,IAAO,CAAC,IAAI,MACtC,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,IAAI,mBAAmB;AAAA,EACpE;AACA,MAAI,MAAM,SAAS,gBAAgB,GAAG;AACpC;AAAA,MACE,kBAAkB,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAEA,IAAM,gBAAgB,MAAqB,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAG1F,IAAM,2BAA2B;AAIjC,eAAe,cAAc,QAAoC,IAA2B;AAC1F,MAAI;AACJ,QAAM,OAAO,QAAQ,QAAQ,EAC1B,KAAK,MAAM,EACX,MAAM,MAAM,MAAS;AACxB,QAAM,QAAQ,IAAI,QAAc,CAAC,YAAY;AAC3C,YAAQ,WAAW,SAAS,EAAE;AAAA,EAChC,CAAC;AACD,MAAI;AACF,UAAM,QAAQ,KAAK,CAAC,MAAM,KAAK,CAAC;AAAA,EAClC,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AACF;AAKA,eAAe,aACb,SACA,SACA,QAC8D;AAC9D,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,QAAQ;AACZ,MAAI;AACJ,QAAM,MAAM,QAAQ,iBAAiB,MAAM;AACzC,aAAS;AACT,mBAAe,QAAQ,WAAW;AAAA,EACpC,CAAC;AACD,MAAI;AACF,UAAM,OAAO;AACb,UAAM,OAAO;AAAA,EACf,UAAE;AACA,QAAI;AAAA,EACN;AACA,SAAO,EAAE,OAAO,aAAa;AAC/B;AAIA,IAAM,mBAAmB,CAAC,UAA0B,MAAM,YAAY,EAAE,QAAQ,oBAAoB,EAAE;AAEtG,IAAM,aAAa,CAAC,MAAkC,EAAE,eAAe,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK;AAGpG,IAAM,cAAc,CAAC,MAA0C;AAAA,EAC7D,EAAE,MAAM,4BAA4B,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAAA,EAC5D,GAAI,EAAE,mBAAmB,CAAC;AAC5B;AAEA,IAAM,YAAY,CAAC,MACjB,EAAE,WAAW,CAAC,GAAG,EAAE,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI;AAGhE,IAAM,YAAY,CAAC,MACjB,EAAE,WAAW,IAAI,IAAI,EAAE,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI;AAEvE,eAAe,aAAa,GAAyB,MAAc,SAAgC;AACjG,QAAM,EAAE,WAAW,IAAI,EAAE,MAAM,CAAC,MAAe,KAAK,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC;AACjF;AAQA,IAAM,gBAAgB,CAAC,UAAyB;AAC9C,QAAM,UAAU,MAAM,KAAK,SAAS,KAAK,GAAG,MAAM,KAAK,MAAM,GAAG,EAAE,CAAC,WAAM,MAAM;AAC/E,SAAO,GAAG,MAAM,KAAK,KAAK,KAAK,UAAU,OAAO,CAAC;AACnD;AASA,SAAS,SAAS,GAAgC;AAChD,QAAM,SAAkB,CAAC;AACzB,IAAE,eAAe,QAAQ,CAAC,MAAM,UAAU;AACxC,UAAM,SAAS,kBAAkB,KAAK;AACtC,UAAM,aAAa,MAAM,KAAK,IAAI;AAClC,UAAM,MAAM,CAAC,WAA2B,WAAW,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE;AAC3E,WAAO;AAAA,MACL,EAAE,OAAO,qBAAqB,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE;AAAA,MACrF,EAAE,OAAO,sBAAsB,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE;AAAA,MACtF,EAAE,OAAO,GAAG,MAAM,+BAA+B,MAAM,IAAI,WAAW,SAAS,CAAC,EAAE;AAAA,MAClF,EAAE,OAAO,GAAG,MAAM,gCAAgC,MAAM,GAAG,IAAI,KAAS;AAAA,IAC1E;AAAA,EACF,CAAC;AACD,GAAC,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,MAAM,UAAU,OAAO,KAAK,EAAE,OAAO,cAAc,KAAK,KAAK,KAAK,CAAC,CAAC;AAClG,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,OAAO,OAAO,CAAC,UAAU;AAC9B,QAAI,KAAK,IAAI,MAAM,IAAI,EAAG,QAAO;AACjC,SAAK,IAAI,MAAM,IAAI;AACnB,WAAO;AAAA,EACT,CAAC;AACH;AAOA,eAAe,kBAAkB,GAAuB,GAA0C;AAChG,aAAW,QAAQ,EAAE,gBAAgB;AACnC,UAAM,EAAE,WAAW,IAAI;AACvB,QAAI,CAAC,EAAE,YAAY,EAAE,SAAS,KAAK,EAAE,SAAS,EAAG,QAAO;AAAA,EAC1D;AACA,OAAK,yGAAoG;AAC3G;AAEO,SAAS,mBAAsC;AACpD,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,cAAI,CAAC,EAAE,KAAK,SAAU,MAAK,wBAAwB;AACnD,cAAI,EAAE,KAAK,aAAa;AACtB,iBAAK,mEAAmE;AAC1E,cAAI,CAAC,sBAAsB,EAAE,KAAK,YAAY,mBAAmB,GAAG;AAClE,iBAAK,cAAc,EAAE,KAAK,UAAU,2BAA2B,mBAAmB,EAAE;AAAA,UACtF;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACJ,YAAI;AAGF,cAAI;AACF,cAAE,WAAW;AAAA,UACf,QAAQ;AAAA,UAER;AACA,gBAAM,cAAc,MAAM,EAAE,OAAO,CAAC,GAAG,wBAAwB;AAC/D,iBAAO,EAAE,UAAU,eAAe;AAClC,oBAAU,MAAM,EAAE,OAAO;AACzB,gBAAM,QAAQ,EAAE,eAAe,SAAS,IAAI,EAAE,eAAe,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE;AAC9E,cAAI,OAAO;AACX,qBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,kBAAM,SAAS,kBAAkB,KAAK;AAItC,kBAAM,QAAQ,WAAW,IAAI;AAC7B,kBAAM,WAAW,aAAa,SAAS,mBAAmB,MAAM,wBAAwB;AACxF,kBAAM;AAAA,cACJ;AAAA,cACA;AAAA,cACA,cAAc,MAAM;AAAA,YACtB;AACA,mBAAO,aAAa,GAAG,mBAAmB,MAAM,gDAAgD;AAChG,gBAAI,SAAS,UAAU;AACrB;AAAA,gBACE,cAAc,MAAM;AAAA;AAAA,EAA8J,QAAQ;AAAA;AAAA,EAAc,IAAI;AAAA,cAC9M;AAAA,YACF;AAAA,UACF;AACA,gBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5D,cAAI,UAAU,GAAG;AACf;AAAA,cACE;AAAA,YACF;AAAA,UACF;AACA,cAAI,aAAa,GAAG,mEAAmE,MAAM,MAAM;AACjG,iBAAK,oFAAoF;AAAA,UAC3F;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AACV,mBAAS,QAAQ;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,QAAQ;AAAA,YACZ,GAAG,EAAE;AAAA,YACL,GAAI,EAAE,cAAc,CAAC;AAAA,YACrB,IAAI,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,UAC7C;AACA,qBAAW,QAAQ,OAAO;AACxB,kBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,WAAW,IAAI,EAAE,KAAK,MAAM,MAAS,CAAC;AACzF,gBAAI,QAAQ,EAAG,MAAK,qCAAqC,KAAK,GAAG;AAAA,UACnE;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AAIX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,gBAAM,EAAE,OAAO,CAAC;AAChB,iBAAO,EAAE,UAAU,eAAe;AAClC,gBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,WAAW,WAAW,CAAC,CAAC,EAAE,KAAK,MAAM,MAAS,CAAC;AAClG,cAAI,QAAQ,EAAG,MAAK,mEAAmE,KAAK,GAAG;AAAA,QACjG,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,CAAC,EAAE,iBAAiB;AACtB,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AACA,cAAM,kBAAkB,EAAE;AAC1B,cAAM,QAAQ,EAAE,eAAe,CAAC,KAAK;AACrC,cAAM,SAAS,EAAE,eAAe,CAAC;AACjC,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AAGF,gBAAM,OAAgE,CAAC;AAIvE,cAAI,WAAW,QAAW;AACxB,kBAAM,EAAE,WAAW,MAAM;AACzB,kBAAM,WAAW,aAAa,GAAG,mCAAmC;AACpE,iBAAK,KAAK,EAAE,MAAM,QAAQ,UAAU,MAAM,2CAA2C,CAAC;AAAA,UACxF;AACA,gBAAM,EAAE,WAAW,KAAK;AACxB,gBAAM,cAAc,aAAa,GAAG,mCAAmC;AACvE,eAAK,KAAK;AAAA,YACR,MAAM;AAAA,YACN,UAAU;AAAA,YACV,MAAM;AAAA,UACR,CAAC;AACD,cAAI;AACJ,qBAAW,CAAC,OAAO,GAAG,KAAK,KAAK,QAAQ,GAAG;AACzC,kBAAM,EAAE,WAAW,KAAK;AACxB,kBAAM,gBAAgB,CAAC;AACvB,mBAAO,EAAE,UAAU,eAAe;AAClC,kBAAM,SAAS,EAAE,mBAAmB,CAAC;AACrC,gBAAI,EAAE,oBAAoB,WAAW,QAAW;AAC9C,mBAAK,8FAAyF;AAAA,YAChG;AACA,kBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,WAAW,IAAI,IAAI,EAAE,KAAK,MAAM,MAAS,CAAC;AAC7F,gBAAI,QAAQ,GAAG;AACb;AAAA,gBACE,aAAa,IAAI,IAAI,oDAAoD,KAAK;AAAA,cAChF;AAAA,YACF;AACA,kBAAM,WAAW,EAAE,mBAAmB,CAAC;AACvC,gBAAI,aAAa,GAAG,mBAAmB,IAAI,IAAI,2BAA2B,MAAM,IAAI,UAAU;AAC5F;AAAA,gBACE,aAAa,IAAI,IAAI;AAAA,cACvB;AAAA,YACF;AACA,gBAAI,EAAE,MAAM;AACV,oBAAM,EAAE,KAAK,CAAC;AACd,qBAAO,EAAE,UAAU,eAAe;AAClC,kBAAI,aAAa,GAAG,yCAAyC,IAAI,IAAI,EAAE,MAAM,IAAI,UAAU;AACzF;AAAA,kBACE,wBAAwB,IAAI,IAAI;AAAA,gBAClC;AAAA,cACF;AAAA,YACF;AACA,kBAAM,eAAe,UAAU,KAAK,SAAS;AAC7C,kBAAM,OAAO,UAAU,cAAc,QAAQ,aAAa,UAAU,SAAS,QAAQ;AACrF,gBAAI,gBAAgB,WAAW,UAAa,CAAC,MAAM;AACjD,oBAAM,QAAQ,OAAO,SAAS,SAAY,KAAK,mBAAmB,KAAK,UAAU,OAAO,IAAI,CAAC;AAC7F,oBAAM,QAAQ,aAAa,SAAY,cAAc,QAAQ,KAAK,UAAU,QAAQ,CAAC;AACrF,uBAAS,sBAAsB,OAAO,SAAS,IAAI,KAAK,iEAAiE,KAAK;AAAA,YAChI;AAAA,UACF;AACA,gBAAM,aAAa;AAAA,YACjB,GAAI,WAAW,SACX;AAAA,cACE;AAAA,YACF,IACA,CAAC;AAAA,YACL,GAAI,EAAE,mBACF,CAAC,IACD;AAAA,cACE;AAAA,YACF;AAAA,UACN;AACA,iBAAO;AAAA,YACL,GAAI,WAAW,SAAS,IAAI,EAAE,SAAS,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC;AAAA,YAClE,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,EAAE;AAAA,UACzD;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,eAAe,WAAW,EAAG,MAAK,oCAAoC;AAC5E,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,qBAAW,QAAQ,EAAE,gBAAgB;AACnC,kBAAM,EAAE,WAAW,IAAI;AACvB,kBAAM,MAAM,EAAE,WAAW;AACzB,gBAAI,QAAQ;AACV,mBAAK;AAAA;AAAA,EAAkE,IAAI;AAAA;AAAA,EAAc,GAAG,EAAE;AAChG,gBAAI,EAAE,WAAW,MAAM;AACrB,mBAAK,2EAAsE;AAAA,UAC/E;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,eAAe;AACnB,iBAAO,KAAK,0EAAqE;AACnF,YAAI,EAAE,WAAW,WAAW,EAAG;AAC/B,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,qBAAW,QAAQ,EAAE,YAAY;AAC/B,kBAAM,EAAE,WAAW,IAAI;AACvB,kBAAM,YAAY,EAAE,WAAW;AAC/B,kBAAM,EAAE,WAAW,SAAS;AAC5B,kBAAM,QAAQ,EAAE,WAAW;AAC3B,gBAAI,UAAU,UAAW,MAAK,mDAAmD;AAAA,UACnF;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,gBAAM,SAAS,EAAE,WAAW;AAC5B,gBAAM,EAAE,OAAO,aAAa,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;AAC1E,cAAI,UAAU,EAAG,MAAK,2CAA2C;AACjE,gBAAM,QAAQ,EAAE,WAAW;AAC3B,cAAI,UAAU;AACZ,iBAAK,+EAA0E;AACjF,cAAI,iBAAiB,OAAO;AAC1B;AAAA,cACE;AAAA,YACF;AAAA,UACF;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,oBAAoB,QAAW;AACnC,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AACA,mBAAW,YAAY,EAAE,iBAAiB;AACxC,gBAAM,IAAI,MAAM,EAAE,OAAO;AACzB,cAAI;AACF,kBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,kBAAM,SAAS,EAAE,WAAW;AAC5B,kBAAM,EAAE,OAAO,aAAa,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,SAAS,IAAI,CAAC,CAAC;AAC9E,gBAAI,UAAU,EAAG,MAAK,oBAAoB,SAAS,IAAI,6BAA6B;AACpF,kBAAM,QAAQ,EAAE,WAAW;AAC3B,gBAAI,UAAU,QAAQ;AACpB,mBAAK,oBAAoB,SAAS,IAAI,4DAAuD;AAAA,YAC/F;AACA,gBAAI,iBAAiB,OAAO;AAC1B;AAAA,gBACE,wDAAwD,SAAS,IAAI;AAAA,cACvE;AAAA,YACF;AAAA,UACF,UAAE;AACA,cAAE,QAAQ;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,cAAI,QAAQ;AACZ,gBAAM,MAAM,EAAE,iBAAiB,MAAM;AACnC,qBAAS;AAAA,UACX,CAAC;AACD,cAAI;AACJ,gBAAM,EAAE,OAAO,CAAC;AAChB,iBAAO,EAAE,UAAU,eAAe;AAClC,cAAI,QAAQ,EAAG,MAAK,8CAA8C;AAAA,QACpE,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,CAAC,EAAE,KAAM,QAAO,KAAK,wDAAmD;AAC5E,cAAM,OAAO,EAAE;AACf,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,gBAAM,SAAS,EAAE,WAAW;AAC5B,gBAAM,EAAE,OAAO,CAAC;AAChB,iBAAO,EAAE,UAAU,eAAe;AAClC,gBAAM,UAAU,EAAE,WAAW;AAC7B,gBAAM,SAAS,MAAM,aAAa,GAAG,GAAG,MAAM,KAAK,CAAC,CAAC;AACrD,cAAI,OAAO,UAAU;AACnB,iBAAK,oFAA+E;AACtF,cAAI,EAAE,WAAW,MAAM;AACrB,iBAAK,mEAAmE;AAC1E,cAAI,OAAO,iBAAiB;AAC1B,iBAAK,0EAA0E;AACjF,cAAI,CAAC,EAAE;AACL,mBAAO;AAAA,cACL;AAAA,YACF;AACF,gBAAM,OAAO,EAAE;AACf,gBAAM,SAAS,MAAM,aAAa,GAAG,GAAG,MAAM,KAAK,CAAC,CAAC;AACrD,cAAI,OAAO,UAAU,EAAG,MAAK,gCAAgC;AAC7D,cAAI,EAAE,WAAW,MAAM,QAAS,MAAK,yCAAyC;AAC9E,cAAI,OAAO,iBAAiB;AAC1B,iBAAK,0EAA0E;AAAA,QACnF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,CAAC,EAAE,KAAM,QAAO,KAAK,wDAAmD;AAC5E,cAAM,QAAQ,EAAE,eAAe,CAAC;AAChC,cAAM,SAAS,EAAE,eAAe,CAAC;AACjC,YAAI,UAAU,UAAa,WAAW,UAAa,UAAU,QAAQ;AACnE,eAAK,2FAAsF;AAAA,QAC7F;AACA,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,KAAK;AACxB,gBAAM,EAAE,OAAO,CAAC;AAChB,gBAAM,EAAE,OAAO,CAAC;AAKhB,gBAAM,UAAU,EAAE,WAAW;AAC7B,gBAAM,EAAE,WAAW,OAAO;AAC1B,gBAAM,eAAe,EAAE,WAAW;AAClC,gBAAM,UAAU,UAAU,CAAC;AAC3B,gBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,KAAM,CAAC,CAAC;AAC3D,cAAI,QAAQ;AACV;AAAA,cACE;AAAA,YACF;AACF,cAAI,EAAE,WAAW,MAAM,gBAAiB,WAAW,CAAC,KAAK,SAAS,UAAU,CAAC,CAAC,GAAI;AAChF;AAAA,cACE;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,EAAE,OAAO,CAAC;AAChB,gBAAM,EAAE,WAAW,MAAM;AAGzB,gBAAM,WAAW,EAAE,WAAW;AAC9B,gBAAM,EAAE,KAAK,CAAC;AACd,gBAAM,EAAE,KAAK,CAAC;AACd,cAAI,EAAE,WAAW,MAAM,UAAU;AAC/B,iBAAK,qFAAqF;AAAA,UAC5F;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,cAAI;AACJ,cAAI;AACF,oBAAQ,EAAE,aAAa;AAAA,UACzB,SAAS,GAAG;AACV,iBAAK,+CAA+C,OAAO,CAAC,CAAC,EAAE;AAAA,UACjE;AACA,cAAI,UAAU,OAAW,cAAa,OAAO,yBAAyB;AAAA,QACxE,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,cAAc,QAAW;AAC7B,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AACA,cAAM,MAAM,EAAE;AACd,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,OAAO,MAAM,kBAAkB,GAAG,CAAC;AACzC,gBAAM,MAAM,EAAE,WAAW;AACzB,gBAAM,SAAS,EAAE,aAAa;AAC9B,uBAAa,QAAQ,wBAAwB;AAI7C,YAAE,aAAa,GAAG;AAClB,gBAAM,UAAU,EAAE,aAAa;AAC/B,uBAAa,SAAS,oBAAoB;AAC1C,cAAI,KAAK,SAAS,MAAM,GAAG;AACzB,iBAAK,+FAA0F;AAAA,UACjG;AACA,gBAAM,EAAE,WAAW,IAAI;AACvB,cAAI,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG;AACnC;AAAA,cACE;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,aAAa,OAAO,CAAC;AACxE,cAAI,QAAQ,EAAG,MAAK,+EAA0E;AAC9F,cAAI,EAAE,WAAW,MAAM;AACrB,iBAAK,4EAAuE;AAC9E,cAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG;AACpC;AAAA,cACE;AAAA,YACF;AAAA,UACF;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,CAAC,EAAE,iBAAiB;AACtB,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AACA,YAAI,EAAE,cAAc,QAAW;AAC7B,iBAAO;AAAA,YACL;AAAA,UACF;AAAA,QACF;AACA,cAAM,kBAAkB,EAAE;AAC1B,cAAM,oBAAoB,EAAE;AAC5B,cAAM,YAAY,EAAE;AACpB,cAAM,SAAS,EAAE,UAAU;AAC3B,cAAM,QAAQ,EAAE,eAAe,CAAC,KAAK;AACrC,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,KAAK;AACxB,gBAAM,MAAM,aAAa,GAAG,mCAAmC;AAC/D,gBAAM,OAAO,YAAmD;AAC9D,kBAAM,gBAAgB,CAAC;AACvB,kBAAM,OAAO;AACb,kBAAMA,UAAS,EAAE,mBAAmB,CAAC;AACrC,gBAAI,EAAE,oBAAoBA,YAAW,QAAW;AAC9C,mBAAK,8FAAyF;AAAA,YAChG;AACA,mBAAOA;AAAA,UACT;AAGA,cAAI;AACJ,cAAI,mBAAmB;AACrB,kBAAM,SAAS,MAAM,KAAK,IAAI;AAC9B,kBAAM,kBAAkB,CAAC;AACzB,kBAAM,OAAO;AACb,wBAAY,aAAa,GAAG,kCAAkC;AAC9D,gBAAI,cAAc,OAAQ,SAAS,CAAC,UAAU,SAAS,KAAK,GAAI;AAC9D;AAAA,gBACE;AAAA,cACF;AAAA,YACF;AACA,kBAAM,aAAa,GAAG,OAAO,0DAA0D;AAAA,UACzF;AACA,gBAAM,SAAS,MAAM,KAAK;AAC1B,gBAAM,OAAO,EAAE,aAAa;AAC5B,gBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,aAAa,SAAS,CAAC;AAC1E,cAAI,QAAQ,GAAG;AACb;AAAA,cACE,gEAAgE,KAAK;AAAA,YACvE;AAAA,UACF;AACA,cAAI,aAAa,GAAG,6CAA6C,MAAM,KAAK;AAC1E;AAAA,cACE;AAAA,YACF;AAAA,UACF;AACA,cAAI,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG;AAChC;AAAA,cACE;AAAA,YACF;AAAA,UACF;AACA,gBAAM,QAAQ,EAAE,mBAAmB,CAAC;AACpC,cAAI;AACJ,cACE,WAAW,WACV,OAAO,cAAc,OAAO,aAAa,OAAO,SAAS,OAAO,OACjE;AACA,kBAAM,QAAQ,OAAO,SAAS,SAAY,KAAK,mBAAmB,KAAK,UAAU,OAAO,IAAI,CAAC;AAC7F,kBAAM,OAAO,UAAU,SAAY,cAAc,QAAQ,KAAK,UAAU,KAAK,CAAC;AAC9E,qBAAS,sBAAsB,OAAO,SAAS,IAAI,KAAK,uDAAuD,IAAI;AAAA,UACrH,WAAW,qBAAqB,cAAc,QAAW;AACvD,kBAAM,kBAAkB,CAAC;AACzB,kBAAM,OAAO;AACb,kBAAM,MAAM,aAAa,GAAG,sDAAsD;AAClF,gBAAI,QAAQ,WAAW;AACrB,uBAAS;AAAA;AAAA,EAA6S,SAAS;AAAA;AAAA,EAAuC,GAAG;AAAA,YAC3W;AAAA,UACF;AACA,iBAAO;AAAA,YACL,GAAI,oBACA,CAAC,IACD;AAAA,cACE,SACE;AAAA,YACJ;AAAA,YACJ,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,EAAE;AAAA,UACzD;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,OAAO,EAAE,eAAe,CAAC,KAAK;AACpC,gBAAM,EAAE,WAAW,IAAI;AACvB,gBAAM,WAAW,EAAE;AACnB,cAAI,CAAC;AACH,mBAAO,KAAK,6EAAwE;AACtF,gBAAM,MAAM,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAC3C,cAAI,IAAI,IAAI,GAAG,EAAE,SAAS,IAAI,OAAQ,MAAK,4BAA4B;AACvE,gBAAM,EAAE,WAAW,IAAI;AACvB,gBAAM,QAAQ,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAC7C,cAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC;AAC1C,iBAAK,+DAA+D;AACtE,cAAI,SAAS,OAAO,4BAA4B,MAAM;AACpD,iBAAK,sCAAsC;AAC7C,gBAAM,UAAU,IAAI,CAAC;AACrB,cAAI,YAAY,QAAW;AACzB,kBAAM,aAAyB,CAAC;AAChC,kBAAM,MAAM,SAAS,YAAY,CAAC,aAAa,WAAW,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC;AAC7E,kBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM;AAC/C,kBAAI,SAAS,OAAO,OAAO,MAAM,KAAM,MAAK,mCAAmC;AAAA,YACjF,CAAC;AACD,gBAAI,QAAQ,EAAG,MAAK,8EAAyE;AAC7F,gBAAI,CAAC,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,GAAG;AAChD;AAAA,gBACE,WAAW,OAAO;AAAA,cACpB;AAAA,YACF;AACA,uBAAW,KAAK,YAAY;AAC1B,yBAAW,MAAM,GAAG;AAClB,oBAAI,CAAC,MAAM,SAAS,EAAE,GAAG;AACvB;AAAA,oBACE,uDAAuD,EAAE;AAAA,kBAC3D;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AACA,gBAAI,CAAC,SAAS,UAAU,EAAE,SAAS,OAAO,EAAG,MAAK,8CAA8C;AAChG,kBAAM,OAAO,WAAW;AACxB,gBAAI;AAGJ,kBAAM,UAAU,IAAI,CAAC;AACrB,gBAAI,YAAY,OAAW,UAAS,OAAO,OAAO;AAAA,gBAC7C,OAAM,EAAE,OAAO,CAAC;AACrB,mBAAO,EAAE,UAAU,eAAe;AAClC,gBAAI,WAAW,WAAW,KAAM,MAAK,yCAAyC;AAAA,UAChF;AAKA,gBAAM,cAAc,IAAI,IAAI,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACtE,gBAAM,EAAE,OAAO,CAAC;AAChB,iBAAO,EAAE,UAAU,eAAe;AAClC,gBAAM,YAAY,IAAI,IAAI,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACpE,cAAI,UAAU,QAAQ,YAAY,MAAM;AACtC;AAAA,cACE;AAAA,YACF;AAAA,UACF;AACA,qBAAW,CAAC,IAAI,IAAI,KAAK,aAAa;AACpC,gBAAI,CAAC,UAAU,IAAI,EAAE,GAAG;AACtB;AAAA,gBACE,eAAe,EAAE;AAAA,cACnB;AAAA,YACF;AACA,gBAAI,SAAS,UAAa,UAAU,IAAI,EAAE,MAAM,MAAM;AACpD;AAAA,gBACE,eAAe,EAAE,yDAAyD,IAAI,aAAQ,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC;AAAA,cACjH;AAAA,YACF;AAAA,UACF;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,cAAM,SAAiC,CAAC;AACxC,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,gBAAM,WAAW,EAAE;AACnB,cAAI,CAAC;AACH,mBAAO,KAAK,6EAAwE;AAGtF,gBAAM,EAAE,OAAO,CAAC;AAChB,iBAAO,EAAE,UAAU,eAAe;AAClC,gBAAM,UAAU,IAAI,IAAI,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAClE,gBAAM,WAAW,aAAa,GAAG,uBAAuB;AACxD,gBAAM,mBAAmB,CAAC,QAA8B,UAAwB;AAC9E,kBAAM,QAAQ,UAAU,MAAM;AAC9B,gBAAI,CAAC,MAAO,MAAK,GAAG,KAAK,qDAAgD;AACzE,uBAAW,CAAC,IAAI,IAAI,KAAK,SAAS;AAChC,kBAAI,CAAC,MAAM,IAAI,EAAE,GAAG;AAClB;AAAA,kBACE,eAAe,EAAE,wCAAmC,KAAK;AAAA,gBAC3D;AAAA,cACF;AAIA,kBAAI,SAAS,WAAc,MAAM,IAAI,EAAE,KAAK,QAAQ,MAAM;AACxD;AAAA,kBACE,eAAe,EAAE,0DAAqD,KAAK,MAAM,IAAI,aAAQ,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC;AAAA,gBACpH;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,gBAAM,aAAa,GAAG,UAAU,8CAA8C;AAC9E,2BAAiB,GAAG,wBAAwB;AAC5C,gBAAM,QAAQ,MAAM,EAAE,OAAO;AAC7B,iBAAO,KAAK,KAAK;AACjB,gBAAM,aAAa,OAAO,UAAU,oDAAoD;AACxF,2BAAiB,OAAO,uBAAuB;AAC/C,cAAI,EAAE,gBAAgB;AACpB,kBAAM,SAAS,MAAM,EAAE,eAAe;AACtC,mBAAO,KAAK,MAAM;AAClB,kBAAM,aAAa,QAAQ,UAAU,yCAAyC;AAC9E,gBAAI,OAAO,SAAU,kBAAiB,QAAQ,iBAAiB;AAAA,UACjE;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AACV,qBAAW,SAAS,OAAQ,OAAM,QAAQ;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,OAAO,EAAE,eAAe,CAAC,KAAK;AACpC,cAAM,QAAgC,CAAC;AACvC,YAAI;AAGF,gBAAM,UAAkD,CAAC;AACzD,mBAAS,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG;AACzC,kBAAM,OAAO,MAAM,EAAE,OAAO;AAC5B,kBAAM,KAAK,IAAI;AACf,kBAAM,KAAK,WAAW,IAAI;AAC1B,gBAAI,CAAC,KAAK;AACR,qBAAO,KAAK,6EAAwE;AACtF,kBAAM,SAAS,IAAI,IAAI,KAAK,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC5D,kBAAM,EAAE,OAAO,IAAI;AACnB,mBAAO,EAAE,UAAU,eAAe;AAClC,kBAAM,QAAQ,IAAI;AAAA,cAChB,KAAK,SACF,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,EAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;AAAA,YAC9B;AACA,gBAAI,MAAM,SAAS,GAAG;AACpB;AAAA,gBACE;AAAA,cACF;AAAA,YACF;AACA,oBAAQ,KAAK,KAAK;AAAA,UACpB;AACA,gBAAM;AAAA,YACJ,UAAU,oBAAI,IAAgC;AAAA,YAC9C,WAAW,oBAAI,IAAgC;AAAA,UACjD,IAAI;AACJ,gBAAM,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,SAAS,IAAI,EAAE,CAAC;AAMlE,gBAAM,qBAAqB,CAAC,OAAwB;AAClD,kBAAM,OAAO,QAAQ,IAAI,EAAE,KAAK;AAChC,gBAAI,SAAS,MAAM,UAAU,SAAS,IAAI,EAAE,KAAK,IAAK,QAAO;AAC7D,kBAAM,UAAU,iBAAiB,IAAI;AACrC,mBAAO,YAAY,MAAM,iBAAiB,EAAE,EAAE,SAAS,OAAO;AAAA,UAChE;AACA,gBAAM,YAAY,OAAO,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;AAC/D,gBAAM,SAAS,CAAC,QAA0B,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;AAC9E,cAAI,UAAU,SAAS,GAAG;AACxB,mBAAO;AAAA,cACL,YAAY;AAAA,gBACV,4HAA4H,OAAO,SAAS,CAAC;AAAA,cAC/I;AAAA,YACF;AAAA,UACF;AACA,cAAI,OAAO,SAAS,GAAG;AACrB,mBAAO;AAAA,cACL,6GAA6G,OAAO,MAAM,CAAC;AAAA,YAC7H;AAAA,UACF;AAAA,QACF,UAAE;AACA,qBAAW,QAAQ,MAAO,MAAK,QAAQ;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,OAAO,EAAE,eAAe,CAAC,KAAK;AACpC,cAAM,SAAS,EAAE,UAAU;AAC3B,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACJ,YAAI;AACF,gBAAM,EAAE,WAAW,IAAI;AACvB,gBAAM,WAAW,EAAE;AACnB,cAAI,CAAC;AACH,mBAAO,KAAK,6EAAwE;AACtF,cAAI,CAAC,UAAU,QAAQ;AACrB,mBAAO,KAAK,4EAAuE;AACrF,kBAAQ,UAAU,iBAAiB;AACnC,cAAI,SAAS,OAAO,4BAA4B,MAAM;AACpD,iBAAK,mDAAmD;AAG1D,gBAAM,WAAW,IAAI,IAAI,SAAS,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACzD,gBAAM,EAAE,OAAO,CAAC;AAChB,gBAAM,OAAO;AACb,qBAAW,EAAE,GAAG,KAAK,SAAS,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,GAAG;AACvE,kBAAM,MAAM,SAAS,OAAO,EAAE;AAC9B,gBAAI,CAAC,YAAY,GAAG,GAAG;AACrB;AAAA,gBACE,oBAAoB,EAAE,8CAA8C,YAAY,GAAG,CAAC;AAAA,cACtF;AAAA,YACF;AAAA,UACF;AACA,gBAAM,aAAuB,CAAC;AAC9B,cAAI,EAAE,aAAa;AACjB,kBAAM,SAAS,QAAQ,UAAU,eAAe;AAChD,kBAAM,UAAU,MAAM,EAAE,YAAY,CAAC;AACrC,kBAAM,OAAO;AACb,kBAAM,MAAM,OAAO,IAAI,OAAO;AAC9B,gBAAI,QAAQ;AACV,mBAAK,yBAAyB,OAAO,yDAAyD;AAChG,kBAAM,MAAM,QAAQ,UAAU,cAAc,EAAE,IAAI,OAAO;AACzD,gBAAI,QAAQ;AACV,mBAAK,IAAI,OAAO,2DAA2D;AAC7E,gBAAI,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,GAAG;AACtC;AAAA,gBACE,oBAAoB,OAAO,2EAA2E,YAAY,GAAG,CAAC;AAAA,cACxH;AAAA,YACF;AAAA,UACF,OAAO;AACL,uBAAW,KAAK,4EAAuE;AAAA,UACzF;AACA,cAAI,EAAE,cAAc,QAAW;AAC7B,kBAAM,SAAS,QAAQ,UAAU,sBAAsB;AACvD,cAAE,aAAa,EAAE,SAAS;AAC1B,uBAAW,CAAC,IAAI,GAAG,KAAK,QAAQ,UAAU,oBAAoB,GAAG;AAC/D,kBAAI,CAAC,KAAK,KAAK,OAAO,IAAI,EAAE,CAAC,GAAG;AAC9B;AAAA,kBACE,oBAAoB,EAAE,6BAA6B,YAAY,OAAO,IAAI,EAAE,CAAC,CAAC,WAAM,YAAY,GAAG,CAAC;AAAA,gBACtG;AAAA,cACF;AAAA,YACF;AAAA,UACF,OAAO;AACL,uBAAW;AAAA,cACT;AAAA,YACF;AAAA,UACF;AACA,cAAI,EAAE,gBAAgB;AACpB,qBAAS,MAAM,EAAE,eAAe;AAChC,kBAAM,aAAa,QAAQ,MAAM,uCAAuC;AACxE,gBAAI,OAAO,YAAY,UAAU,OAAO,QAAQ,GAAG;AACjD,sBAAQ,OAAO,UAAU,+BAA+B;AACxD,kBAAI,OAAO,SAAS,OAAO,4BAA4B,MAAM;AAC3D,qBAAK,gEAAgE;AAAA,YACzE;AAAA,UACF;AACA,cAAI,WAAW,SAAS,EAAG,QAAO,KAAK,WAAW,KAAK,IAAI,CAAC;AAAA,QAC9D,UAAE;AACA,YAAE,QAAQ;AACV,kBAAQ,QAAQ;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,SAAS,EAAE,UAAU;AAC3B,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACJ,YAAI;AACF,cAAI,CAAC,iBAAiB,CAAC;AACrB,mBAAO,KAAK,+EAA0E;AACxF,uBAAa,GAAG,yBAAyB;AACzC,qBAAW,CAAC,OAAO,IAAI,KAAK,EAAE,eAAe,QAAQ,GAAG;AACtD,kBAAM,aAAa,GAAG,MAAM,6BAA6B,KAAK,aAAa;AAC3E,wCAA4B,GAAG,kCAAkC,KAAK,GAAG;AAAA,UAC3E;AAGA,gBAAM,aAAa,GAAG,EAAE,eAAe,CAAC,KAAK,IAAI,wCAAwC;AACzF,gBAAM,EAAE,OAAO,CAAC;AAChB,gBAAM,OAAO;AACb,gBAAM,SAAS,4BAA4B,GAAG,wCAAwC;AACtF,gBAAM,aAAuB,CAAC;AAC9B,cAAI,EAAE,cAAc,QAAW;AAC7B,cAAE,aAAa,EAAE,SAAS;AAC1B,kBAAM,SAAS,aAAa,GAAG,oBAAoB;AACnD,gBAAI,CAAC,KAAK,QAAQ,MAAM,GAAG;AACzB;AAAA,gBACE,0CAA0C,YAAY,MAAM,CAAC,WAAM,YAAY,MAAM,CAAC;AAAA,cACxF;AAAA,YACF;AAAA,UACF,OAAO;AACL,uBAAW;AAAA,cACT;AAAA,YACF;AAAA,UACF;AACA,cAAI,CAAC,EAAE,YAAY,CAAC,UAAU,EAAE,QAAQ,GAAG;AACzC,uBAAW;AAAA,cACT;AAAA,YACF;AAAA,UACF;AACA,cAAI,EAAE,gBAAgB;AACpB,qBAAS,MAAM,EAAE,eAAe;AAChC,gBAAI,iBAAiB,MAAM,GAAG;AAC5B,2BAAa,QAAQ,uCAAuC;AAC5D,oBAAM,aAAa,QAAQ,EAAE,eAAe,CAAC,KAAK,IAAI,uCAAuC;AAC7F,0CAA4B,QAAQ,+BAA+B;AAAA,YACrE;AAAA,UACF;AACA,cAAI,WAAW,SAAS,EAAG,QAAO,KAAK,WAAW,KAAK,IAAI,CAAC;AAAA,QAC9D,UAAE;AACA,YAAE,QAAQ;AACV,kBAAQ,QAAQ;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,qBAAW,YAAY,YAAY,CAAC,GAAG;AACrC,kBAAM,SAAS,IAAI,CAAC;AACpB,yBAAa,GAAG,SAAS,SAAS,IAAI,EAAE;AAAA,UAC1C;AACA,cAAI,EAAE,MAAM;AACV,kBAAM,EAAE,KAAK,CAAC;AACd,yBAAa,GAAG,eAAe;AAAA,UACjC;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,iBAAiB,QAAW;AAChC,iBAAO,KAAK,8EAAyE;AAAA,QACvF;AACA,YAAI,EAAE,aAAa,WAAW,EAAG;AACjC,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,kBAAkB,GAAG,GAAG,EAAE;AAAA,QAClC,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,iBAAiB,QAAW;AAChC,iBAAO,KAAK,qFAAgF;AAAA,QAC9F;AACA,YAAI,EAAE,aAAa,WAAW,EAAG;AACjC,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,OAAO,EAAE,eAAe,CAAC,KAAK;AACpC,gBAAM,EAAE,WAAW,IAAI;AACvB,gBAAM,aAAa,EAAE,WAAW;AAGhC,cAAI,EAAE,MAAM;AACV,kBAAM,EAAE,OAAO,CAAC;AAChB,mBAAO,EAAE,UAAU,eAAe;AAAA,UACpC;AACA,gBAAM,MAAM,EAAE,WAAW;AACzB,gBAAM,MAAM,UAAU,CAAC;AACvB,qBAAW,OAAO,EAAE,cAAc;AAChC,gBAAI,WAAW;AACf,kBAAM,EAAE,MAAM,IAAI,MAAM;AAAA,cAAa;AAAA,cAAG;AAAA,cAAG,MACzC,EAAE,WAAW,GAAG,EAAE;AAAA,gBAChB,MAAM;AAAA,gBACN,MAAM;AACJ,6BAAW;AAAA,gBACb;AAAA,cACF;AAAA,YACF;AACA,gBAAI,CAAC,SAAU,MAAK,sEAAiE;AACrF,gBAAI,QAAQ,EAAG,MAAK,0CAA0C;AAC9D,gBAAI,EAAE,WAAW,MAAM;AACrB,mBAAK,mFAA8E;AACrF,gBAAI,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,GAAG;AACnC;AAAA,gBACE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,cAAI,EAAE,MAAM;AACV,kBAAM,EAAE,KAAK,CAAC;AACd,gBAAI,EAAE,WAAW,MAAM,YAAY;AACjC;AAAA,gBACE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,EAAE,iBAAiB,QAAW;AAChC,iBAAO,KAAK,qFAAgF;AAAA,QAC9F;AACA,cAAM,MAAM,EAAE,aAAa,CAAC;AAC5B,YAAI,QAAQ,OAAW;AACvB,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,EAAE,eAAe,CAAC,KAAK,EAAE;AAC5C,gBAAM,EAAE,WAAW,GAAG,EAAE;AAAA,YACtB,MAAM,KAAK,sEAAiE;AAAA,YAC5E,MAAM;AAAA,UACR;AACA,gBAAM,OAAO,WAAW,CAAC;AACzB,gBAAM,EACH,WAAW,IAAI,EACf,MAAM,CAAC,MAAM,KAAK,2DAA2D,OAAO,CAAC,CAAC,EAAE,CAAC;AAC5F,cAAI,EAAE,WAAW,MAAM;AACrB,iBAAK,sEAAsE;AAC7E,gBAAM,SAAS,EAAE,WAAW;AAC5B,gBAAM,EAAE,MAAM,IAAI,MAAM,aAAa,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5D,cAAI,UAAU,EAAG,MAAK,4EAA4E;AAClG,cAAI,aAAa,GAAG,kDAAkD,MAAM,QAAQ;AAClF,iBAAK,gEAAgE;AAAA,UACvE;AACA,cAAI,EAAE,MAAM;AACV,kBAAM,EAAE,KAAK,CAAC;AACd,yBAAa,GAAG,+CAA+C;AAAA,UACjE;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,OAAO,EAAE,eAAe,CAAC,KAAK;AACpC,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,YAAI;AACF,gBAAM,EAAE,WAAW,IAAI;AAGvB,gBAAM,WAAW,aAAa,GAAG,mCAAmC;AACpE,gBAAM,UAAU,UAAU,CAAC;AAC3B,cAAI;AACJ,gBAAM,eAAe,YAA2B;AAC9C,gBAAI,aAAa,OAAW;AAC5B,kBAAM,QAAQ,mBAAmB,cAAc,QAAQ,CAAC;AACxD,kBAAM,aAAa,GAAG,MAAM,yBAAyB,KAAK,iBAAiB;AAC3E,kBAAM,MAAM,aAAa,GAAG,4BAA4B,KAAK,EAAE;AAC/D,gBAAI,QAAQ,YAAa,WAAW,CAAC,KAAK,SAAS,UAAU,CAAC,CAAC,GAAI;AACjE,mBAAK,yBAAyB,KAAK,wCAAwC;AAAA,YAC7E;AAAA,UACF;AACA,gBAAM,yBAAyB,YAA6B;AAC1D,kBAAM,EAAE,OAAO,CAAC;AAChB,mBAAO,EAAE,UAAU,eAAe;AAClC,kBAAM,MAAM,aAAa,GAAG,uBAAuB;AACnD,gBAAI,QAAQ,UAAU;AACpB;AAAA,gBACE,aAAa,SACT,kFACA,mCAAmC,cAAc,QAAQ,CAAC;AAAA,cAChE;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AACA,qBAAW,SAAS,SAAS,CAAC,GAAG;AAC/B,kBAAM,aAAa;AAEnB,kBAAM,MAAM,MAAM,uBAAuB;AACzC,kBAAM,MAAM,UAAU,CAAC;AACvB,kBAAM,OAAO,cAAc,cAAc,KAAK,CAAC;AAC/C,gBAAI,WAAW;AACf,kBAAM,EAAE,MAAM,IAAI,MAAM;AAAA,cAAa;AAAA,cAAG;AAAA,cAAG,MACzC,EAAE,WAAW,MAAM,IAAI,EAAE;AAAA,gBACvB,MAAM;AAAA,gBACN,MAAM;AACJ,6BAAW;AAAA,gBACb;AAAA,cACF;AAAA,YACF;AACA,gBAAI,UAAU;AACZ,kBAAI,QAAQ,EAAG,MAAK,cAAc,IAAI,2BAA2B,KAAK,QAAQ;AAC9E,kBAAI,aAAa,GAAG,oBAAoB,IAAI,EAAE,MAAM,KAAK;AACvD,qBAAK,cAAc,IAAI,uEAAkE;AAAA,cAC3F;AACA,kBAAI,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,GAAG;AACnC;AAAA,kBACE,cAAc,IAAI;AAAA,gBACpB;AAAA,cACF;AACA,kBAAI,EAAE,MAAM;AACV,sBAAM,EAAE,KAAK,CAAC;AACd,oBAAI,aAAa,GAAG,0CAA0C,IAAI,EAAE,MAAM,UAAU;AAClF;AAAA,oBACE,cAAc,IAAI;AAAA,kBACpB;AAAA,gBACF;AAAA,cACF;AAAA,YACF,OAAO;AACL,kBAAI,QAAQ;AACV,qBAAK,GAAG,IAAI,wCAAwC,KAAK,mCAA8B;AACzF,2BAAa,GAAG,SAAS,IAAI,gBAAgB;AAAA,YAC/C;AACA,uBAAW;AAAA,UACb;AACA,gBAAM,aAAa;AACnB,gBAAM,uBAAuB;AAAA,QAC/B,UAAE;AACA,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,YAAI,CAAC,EAAE,eAAgB,QAAO,KAAK,sEAAiE;AACpG,cAAM,IAAI,MAAM,EAAE,eAAe;AACjC,YAAI;AACF,cAAI,EAAE,KAAK,aAAa;AACtB,iBAAK,iEAAiE;AACxE,cAAI;AACF,kBAAM,QAAQ,EAAE,aAAa;AAC7B,gBAAI,UAAU,OAAW,cAAa,OAAO,uCAAuC;AAAA,UACtF,SAAS,GAAG;AACV,iBAAK,4DAA4D,OAAO,CAAC,CAAC,EAAE;AAAA,UAC9E;AACA,cAAI,QAAQ;AACZ,gBAAM,MAAM,EAAE,iBAAiB,MAAM;AACnC,qBAAS;AAAA,UACX,CAAC;AACD,cAAI;AACF,uBAAW,QAAQ,EAAE,gBAAgB;AACnC,oBAAM,EACH,WAAW,IAAI,EACf,MAAM,CAAC,MAAM,KAAK,yCAAyC,OAAO,CAAC,CAAC,EAAE,CAAC;AAC1E,kBAAI,aAAa,GAAG,eAAe,MAAM;AACvC,qBAAK,+CAA+C;AAAA,YACxD;AACA,kBAAM,MAAM,EAAE,WAAW;AACzB,kBAAM,MAAM,UAAU,CAAC;AACvB,gBAAI,EAAE,UAAU;AACd,oBAAM,UAAU,EAAE,SAAS,KAAK,EAAE,CAAC,GAAG;AACtC,kBAAI,YAAY,QAAW;AACzB,sBAAM,aAAyB,CAAC;AAChC,sBAAM,SAAS,EAAE,SAAS,YAAY,CAAC,MAAM,WAAW,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACpE,oBAAI,EAAE,SAAS,OAAO,OAAO,MAAM;AACjC,uBAAK,gDAAgD;AACvD,uBAAO,EAAE,UAAU,eAAe;AAClC,oBAAI,CAAC,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC;AAC7C,uBAAK,8DAA8D;AACrE,oBAAI,CAAC,EAAE,SAAS,UAAU,EAAE,SAAS,OAAO;AAC1C,uBAAK,2DAA2D;AAClE,uBAAO;AAAA,cACT;AACA,kBAAI,EAAE,SAAS,OAAO,4BAA4B,MAAM;AACtD,qBAAK,mDAAmD;AAAA,YAC5D;AACA,uBAAW,OAAO,EAAE,gBAAgB,CAAC,GAAG;AACtC,oBAAM,EAAE,WAAW,GAAG,EAAE;AAAA,gBACtB,MAAM,KAAK,kEAA6D;AAAA,gBACxE,MAAM;AAAA,cACR;AACA,kBAAI,EAAE,WAAW,MAAM,IAAK,MAAK,iDAAiD;AAClF,kBAAI,OAAO,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC;AAChC,qBAAK,0DAA0D;AAAA,YACnE;AACA,kBAAM,kBAAkB,GAAG,GAAG,eAAe;AAC7C,gBAAI,EAAE,cAAc,QAAW;AAC7B,oBAAM,OAAO,MAAM,kBAAkB,GAAG,CAAC;AACzC,oBAAM,SAAS,EAAE,aAAa;AAC9B,2BAAa,QAAQ,4BAA4B;AACjD,gBAAE,aAAa,EAAE,SAAS;AAC1B,oBAAM,UAAU,EAAE,aAAa;AAC/B,kBAAI,KAAK,SAAS,MAAM,EAAG,MAAK,yCAAyC;AACzE,oBAAM,EAAE,WAAW,IAAI;AACvB,kBAAI,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM;AAChC,qBAAK,qDAAqD;AAC5D,gBAAE,aAAa,OAAO;AACtB,kBAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;AACjC,qBAAK,+DAA+D;AAAA,YACxE;AACA,mBAAO,EAAE,UAAU,eAAe;AAClC,gBAAI,QAAQ;AACV,mBAAK,qCAAqC,KAAK,yCAAoC;AAAA,UACvF,UAAE;AACA,gBAAI;AAAA,UACN;AAAA,QACF,UAAE;AACA,YAAE,QAAQ;AACV,YAAE,QAAQ;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM,IAAI,GAAG;AACX,cAAM,IAAI,MAAM,EAAE,OAAO;AACzB,UAAE,QAAQ;AACV,UAAE,QAAQ;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAe,kBAAkB,GAAuB,GAAyB,KAA4B;AAC3G,aAAW,EAAE,MAAM,YAAY,KAAK,EAAE,gBAAgB,CAAC,GAAG;AACxD,QAAI,YAAY,WAAW,EAAG,MAAK,qEAAqE;AACxG,UAAM,EAAE,WAAW,IAAI;AACvB,UAAM,QAAQ,aAAa,GAAG,GAAG,GAAG,iDAAiD;AACrF,eAAW,YAAY,aAAa;AAClC,UAAI,CAAC,MAAM,SAAS,QAAQ;AAC1B,aAAK,GAAG,GAAG,yDAAoD,QAAQ,cAAc;AAAA,IACzF;AACA,UAAM,EAAE,WAAW,KAAK;AACxB,UAAM,SAAS,aAAa,GAAG,GAAG,GAAG,sDAAsD;AAC3F,QAAI,WAAW,MAAO,MAAK,GAAG,GAAG,0EAAqE;AAAA,EACxG;AACF;AAaO,SAAS,oBACd,SACA,MACA,UAA2B,CAAC,GACtB;AACN,QAAM,SACJ,QAAQ,WACP,CAAC,MAAc,WAAmB;AACjC,YAAQ,KAAK,qCAAqC,IAAI,YAAO,MAAM,EAAE;AAAA,EACvE;AACF,QAAM,aACJ,QAAQ,eACP,CAAC,MAAc,WAAmB;AACjC,YAAQ,KAAK,sCAAsC,IAAI,YAAO,MAAM,EAAE;AAAA,EACxE;AACF,aAAW,mBAAmB,iBAAiB,GAAG;AAChD,SAAK,gBAAgB,gBAAgB,IAAI,IAAI,YAAY;AACvD,YAAM,UAAU,MAAM,gBAAgB,IAAI,OAAO;AACjD,UAAI,SAAS,QAAS,QAAO,gBAAgB,MAAM,QAAQ,OAAO;AAClE,iBAAW,UAAU,SAAS,cAAc,CAAC,EAAG,YAAW,gBAAgB,MAAM,MAAM;AAAA,IACzF,CAAC;AAAA,EACH;AACF;","names":["opened"]}
package/dist/index.cjs CHANGED
@@ -24,7 +24,7 @@ __export(index_exports, {
24
24
  apiVersionsCompatible: () => apiVersionsCompatible
25
25
  });
26
26
  module.exports = __toCommonJS(index_exports);
27
- var MODELER_API_VERSION = "1.2.0";
27
+ var MODELER_API_VERSION = "1.3.0";
28
28
  function apiVersionsCompatible(a, b) {
29
29
  const [aMajor = "", aMinor = ""] = a.split(".");
30
30
  const [bMajor = "", bMinor = ""] = b.split(".");