clone

a browser-first diagram editor with live svg previews, local drafts and encrypted, accountless sharing

migrate Pikchr to dedicated Wasm Worker

Dami committed eb656be
commit
eb656be584a9d31063c2036a2f529b5755ce6e4b
parent
390604028f3ffe377440d8473b8334719e61a70a
author
Dami <dami.etoile@gmail.com>
21 files changed, +174 -18
Mdiagramzip-render/README.md9++--
Mdiagramzip-render/scripts/deploy-compatibility-units.mjs2+-
Mdiagramzip-render/scripts/deploy-worker-units.mjs2+-
Mdiagramzip-render/scripts/smoke-units.mjs9++++
Adiagramzip-render/src/adapters/edge/pikchr.ts65++++++++++++++++++++++++++++++
Mdiagramzip-render/src/catalog.ts7+++
Adiagramzip-render/src/units/pikchr.ts11+++++
Mdiagramzip-render/src/vendor.d.ts5++
Adiagramzip-render/src/vendor/pikchr-backend.js2+
Adiagramzip-render/src/vendor/pikchr-provenance.md8++++
Adiagramzip-render/src/vendor/pikchr.wasmbin
Mdiagramzip-render/test/catalog.test.ts6+++
Mdiagramzip-render/test/gateway.test.ts2+-
Adiagramzip-render/test/pikchr.test.ts27++++++++++++
Ddiagramzip-render/wrangler.compatibility/pikchr.jsonc1-
Adiagramzip-render/wrangler.units/pikchr.jsonc10+++++
Mdiagramzip/src/renderer-units.js2+-
Mdiagramzip/test/renderer-units.test.js2+-
Mdocs/refactor-engines.md18++++++---
Rserver/src/main/resources/web/diagramzip/assets/index-WmdMHtkV.js → server/src/main/resources/web/diagramzip/assets/index-584g8mpQ.js2+-
Mserver/src/main/resources/web/diagramzip/index.html2+-
M diagramzip-render/README.md +5 -4
@@ -60,18 +60,19 @@ catalog engine.
6060 | --- | --- |6161 | Worker JavaScript | Bytefield, Nomnoml, Vega family (Vega and Vega-Lite → Vega), WaveDrom |6262 | Worker Python | BlockDiag family (BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, RackDiag); WireViz → DOT → GraphViz |63-| Worker WebAssembly | GraphViz family (GraphViz and ERD → DOT → GraphViz) |63+| Worker WebAssembly | GraphViz family (GraphViz and ERD → DOT → GraphViz); Pikchr |6464 | Sandboxed browser unit | Mermaid, BPMN, Excalidraw |65-| Compatibility unit | 12 dependency units covering the remaining 13 engines |65+| Compatibility unit | 11 dependency units covering the remaining 12 engines |6666 67-The current split is 17/30 engines off Fly and 13/30 still dependent on it.67+The current split is 18/30 engines off Fly and 12/30 still dependent on it.6868 Compatibility units are extraction seams, not final runtimes or fallbacks for6969 an engine after cutover. DBML7070 currently proxies because its published package mixes module formats. GraphViz7171 uses a precompiled Worker module; ERD lowers its upstream-compatible source7272 language to DOT and reuses the same in-process GraphViz runtime. WireViz runs7373 its vendored upstream parser and DOT composer in a separate Python Worker, then74-calls that same GraphViz deployment through a service binding.74+calls that same GraphViz deployment through a service binding. Pikchr compiles75+the pinned upstream C source into a small, isolated precompiled Wasm unit.7576 7677 All returned SVG passes through the same sanitizer. Scripts, event handlers,7778 external resources, and active embedded HTML are removed. Mermaid's
M diagramzip-render/scripts/deploy-compatibility-units.mjs +1 -1
M diagramzip-render/scripts/deploy-worker-units.mjs +1 -1
M diagramzip-render/scripts/smoke-units.mjs +9 -0
A diagramzip-render/src/adapters/edge/pikchr.ts +65 -0
@@ -0,0 +1,65 @@
1+import initPikchrModule from '../../vendor/pikchr-backend.js'2+import wasmModule from '../../vendor/pikchr.wasm'3+import { RenderError } from '../../errors'4+import type { RendererAdapter } from '../../types'5+6+const VERSION = 'pikchr@85e65b9686/edge-wasm-1'7+const MAX_SOURCE = 256 * 10248+let modulePromise: Promise<any> | undefined9+let renderTail: Promise<void> = Promise.resolve()10+11+function pikchrModule(): Promise<any> {12+ modulePromise ??= initPikchrModule({13+ instantiateWasm(imports: WebAssembly.Imports, receive: (instance: WebAssembly.Instance) => void) {14+ const instance = new WebAssembly.Instance(wasmModule, imports)15+ receive(instance)16+ return instance.exports17+ },18+ })19+ return modulePromise!20+}21+22+async function withPikchrLock<T>(operation: () => T): Promise<T> {23+ const previous = renderTail24+ let release!: () => void25+ renderTail = new Promise(resolve => { release = resolve })26+ await previous27+ try { return operation() } finally { release() }28+}29+30+export const pikchrAdapter: RendererAdapter = {31+ id: 'pikchr', runtime: 'edge-wasm', version: VERSION,32+ async render(request, signal) {33+ if (signal.aborted) throw signal.reason34+ if (new TextEncoder().encode(request.source).byteLength > MAX_SOURCE) throw new RenderError(413, 'source_too_large', 'Pikchr source exceeds the 256 KiB limit.')35+ if (Object.keys(request.options).length > 0) throw new RenderError(400, 'unsupported_options', 'Pikchr options are not supported by the edge renderer.')36+ try {37+ const body = await withPikchrLock(async () => {38+ if (signal.aborted) throw signal.reason39+ const module = await pikchrModule()40+ const dimensions = module.ccall('malloc', 'number', ['number'], [8])41+ if (!dimensions) throw new RenderError(500, 'renderer_unavailable', 'Pikchr could not allocate render state.')42+ let pointer = 043+ try {44+ pointer = module.ccall('pikchr', 'number', ['string', 'string', 'number', 'number', 'number'], [request.source, 'pikchr', 1, dimensions, dimensions + 4])45+ if (!pointer) throw new RenderError(422, 'render_failed', 'Pikchr returned no SVG.')46+ const width = module.getValue(dimensions, 'i32')47+ const height = module.getValue(dimensions + 4, 'i32')48+ const body = module.UTF8ToString(pointer)49+ if (width < 0 || height < 0 || /<pre\b/i.test(body)) throw new RenderError(422, 'render_failed', body.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 500) || 'Pikchr could not parse the source.')50+ return body51+ } finally {52+ if (pointer) module.ccall('free', 'number', ['number'], [pointer])53+ module.ccall('free', 'number', ['number'], [dimensions])54+ }55+ })56+ if (signal.aborted) throw signal.reason57+ if (!body.includes('<svg')) throw new RenderError(422, 'render_failed', 'Pikchr could not parse the source.')58+ return { body, contentType: 'image/svg+xml', engineVersion: VERSION, runtime: 'edge-wasm' }59+ } catch (error) {60+ if (error instanceof RenderError) throw error61+ const message = error instanceof Error ? error.message : String(error)62+ throw new RenderError(422, 'render_failed', message.slice(0, 500) || 'Pikchr could not render this source.')63+ }64+ },65+}
M diagramzip-render/src/catalog.ts +7 -0
A diagramzip-render/src/units/pikchr.ts +11 -0
M diagramzip-render/src/vendor.d.ts +5 -0
A diagramzip-render/src/vendor/pikchr-backend.js +2 -0
@@ -0,0 +1,2 @@
1+async function initPikchrModule(moduleArg={}){var Module=moduleArg;var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var programArgs=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=import.meta.url;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{readAsync=async url=>{var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b)}function preRun(){var preRun=Module["preRun"];if(preRun){if(typeof preRun=="function")preRun=[preRun];onPreRuns.push(...preRun)}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["e"]()}function postRun(){var postRun=Module["postRun"];if(postRun){if(typeof postRun=="function")postRun=[postRun];onPostRuns.push(...postRun)}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){if(Module["locateFile"]){return locateFile("pikchr.wasm")}return new URL("pikchr.wasm",import.meta.url).href}function getBinarySync(file){if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();var instantiateWasm=Module["instantiateWasm"];if(instantiateWasm){return new Promise(resolve=>{instantiateWasm(info,inst=>resolve(receiveInstance(inst)))})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var onPreRuns=[];var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var HEAPU8;var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var ___assert_fail=(condition,filename,line,func)=>abort(`Assertion failed: ${UTF8ToString(condition)}, at: `+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"]);var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var getCFunc=ident=>{var func=Module["_"+ident];return func};var HEAP8;var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.codePointAt(i);if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(!stack)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func(...cArgs);function onDone(ret){if(stack)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var HEAP16;var HEAP32;var HEAPU32;var HEAPF32;var HEAPF64;var HEAP64;function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":return HEAP8[ptr];case"i8":return HEAP8[ptr];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP64[ptr>>3];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];case"*":return HEAPU32[ptr>>2];default:abort(`invalid type for getValue: ${type}`)}}{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["arguments"])programArgs=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var preInit=Module["preInit"];if(preInit){if(typeof preInit=="function")Module["preInit"]=preInit=[preInit];while(preInit.length>0){preInit.shift()()}}}Module["ccall"]=ccall;Module["getValue"]=getValue;Module["UTF8ToString"]=UTF8ToString;var _free,_malloc,_pikchr,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_free=Module["_free"]=wasmExports["f"];_malloc=Module["_malloc"]=wasmExports["g"];_pikchr=Module["_pikchr"]=wasmExports["h"];__emscripten_stack_restore=wasmExports["i"];__emscripten_stack_alloc=wasmExports["j"];_emscripten_stack_get_current=wasmExports["k"];memory=wasmMemory=wasmExports["d"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={a:___assert_fail,b:_emscripten_resize_heap,c:_exit};async function run(){preRun();var setStatus=Module["setStatus"];if(setStatus){setStatus("Running...");await new Promise(resolve=>setTimeout(resolve,1));setTimeout(setStatus,1,"")}if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}var wasmExports;wasmExports=await createWasm();await run();2+;return Module}export default initPikchrModule;
A diagramzip-render/src/vendor/pikchr-provenance.md +8 -0
A diagramzip-render/src/vendor/pikchr.wasm +0 -0

Binary file.

M diagramzip-render/test/catalog.test.ts +6 -0
M diagramzip-render/test/gateway.test.ts +1 -1
A diagramzip-render/test/pikchr.test.ts +27 -0
@@ -0,0 +1,27 @@
1+import { describe, expect, it } from 'vitest'2+import { pikchrAdapter } from '../src/adapters/edge/pikchr'3+import type { RenderRequest } from '../src/types'4+5+const request = (source: string, options: Record<string, string> = {}): RenderRequest => ({6+ engine: 'pikchr', source, format: 'svg', options,7+ metadata: { title: '', description: '' },8+ presentation: { background: '', padding: 0, frame: false },9+})10+11+describe('Pikchr edge-Wasm adapter', () => {12+ it('renders the pinned upstream fixture and preserves labels', async () => {13+ const result = await pikchrAdapter.render(request('D: diamond "Cardinal" "Points"\n dot ".n" above at D.n'), new AbortController().signal)14+ expect(result.runtime).toBe('edge-wasm')15+ expect(result.body).toContain('<svg')16+ expect(result.body).toContain('Cardinal')17+ })18+19+ it('returns bounded parser errors instead of invalid SVG', async () => {20+ await expect(pikchrAdapter.render(request('this is not pikchr {'), new AbortController().signal)).rejects.toMatchObject({ status: 422, code: 'render_failed' })21+ })22+23+ it('rejects options and oversized UTF-8 sources', async () => {24+ await expect(pikchrAdapter.render(request('box', { dark: 'true' }), new AbortController().signal)).rejects.toMatchObject({ status: 400, code: 'unsupported_options' })25+ await expect(pikchrAdapter.render(request('é'.repeat(140_000)), new AbortController().signal)).rejects.toMatchObject({ status: 413, code: 'source_too_large' })26+ })27+})
D diagramzip-render/wrangler.compatibility/pikchr.jsonc +0 -1
A diagramzip-render/wrangler.units/pikchr.jsonc +10 -0
M diagramzip/src/renderer-units.js +1 -1
M diagramzip/test/renderer-units.test.js +1 -1
M docs/refactor-engines.md +12 -6
@@ -408,7 +408,7 @@ The origin is a compatibility bridge, not the target architecture for standardiz
408408 | Excalidraw | Client | Browser-render/origin |409409 | GoAT | WebAssembly spike | Origin |410410 | Nomnoml | Edge JavaScript | Origin |411-| Pikchr | Edge WebAssembly | Origin |411+| Pikchr | Edge WebAssembly | None after cutover |412412 | Structurizr | TypeScript DSL-to-PlantUML compiler; browser PlantUML preview | Existing Structurizr/PlantUML path |413413 | Svgbob | Edge WebAssembly | Origin |414414 | Symbolator | Origin | Origin |
@@ -419,7 +419,7 @@ The origin is a compatibility bridge, not the target architecture for standardiz
419419 | WaveDrom | Edge JavaScript | Origin |420420 | WireViz | Upstream Python parser/model/DOT composer → GraphViz service binding | None after cutover |421421 422-The first coverage milestone puts all 30 catalog types behind one contract and keeps unsupported edge engines on the origin. Its first native cohort is Bytefield, Nomnoml, WaveDrom, Vega, and Vega-Lite. DBML remains on the origin because its published package mixes module formats. GraphViz now imports its WebAssembly as a precompiled Worker module, and ERD lowers into that same runtime. D2, Pikchr, and Svgbob move only after direct precompiled-Wasm adapters are proven. Seven engines can later move interactive preview into the browser: Mermaid, PlantUML, C4-PlantUML, BPMN, Excalidraw, diagrams.net, and UMLet.422+The first coverage milestone puts all 30 catalog types behind one contract and keeps unsupported edge engines on the origin. Its first native cohort is Bytefield, Nomnoml, WaveDrom, Vega, and Vega-Lite. DBML remains on the origin because its published package mixes module formats. GraphViz now imports its WebAssembly as a precompiled Worker module, ERD lowers into that same runtime, and Pikchr has a separate precompiled WebAssembly unit. D2 and Svgbob move only after direct precompiled-Wasm adapters are proven. Seven engines can later move interactive preview into the browser: Mermaid, PlantUML, C4-PlantUML, BPMN, Excalidraw, diagrams.net, and UMLet.423423 424424 The upstream-reuse milestone moves all six BlockDiag-family types into one Python Worker, moves ERD to an upstream-guided TypeScript/GraphViz implementation, and preserves WireViz coverage in a dependency-isolated Python translator that reuses GraphViz through a service binding. Structurizr remains a later PlantUML translation target.425425
@@ -559,13 +559,13 @@ Use production traffic and latency data to choose the remaining rewrites. WireVi
559559 560560 ## Implementation status — 2026-08-20561561 562-The coverage plane is implemented across dedicated renderer hostnames. Seventeen562+The coverage plane is implemented across dedicated renderer hostnames. Eighteen563563 of 30 catalog engines no longer depend on Fly: five execute in JavaScript564564 Workers, six share the `blockdiag-family` Python Worker, GraphViz and ERD share565-the `graphviz-family` WebAssembly Worker, and Mermaid, BPMN, and Excalidraw565+the `graphviz-family` WebAssembly Worker, Pikchr in its dedicated WebAssembly Worker, and Mermaid, BPMN, and Excalidraw566566 render in sandboxed browser units. WireViz preserves its upstream Python parser567567 and DOT composer, then calls GraphViz through an internal service binding. The568-remaining 13 engines use 12568+remaining 12 engines use 11569569 dependency-grouped compatibility units. Repository and production smokes require570570 structurally valid SVG; pixel comparison remains intentionally deferred.571571
@@ -581,13 +581,19 @@ under real workerd, including cache behavior, presentation, HTML labels and
581581 ports, malformed input, and unsafe image rejection. The family dry-run is about582582 1.19 MB uncompressed and 0.47 MB compressed.583583 584+The Pikchr unit compiles the pinned upstream C source revision into a dedicated585+precompiled Emscripten WebAssembly module. It calls the public `pikchr()` API,586+uses plaintext parser errors and bounded source input, rejects renderer options587+and assets, and frees all returned buffers. The browser fiddle's dynamic Wasm588+loader is not used; the module is statically imported by the Worker.589+584590 The WireViz unit vendors the actual `yuzutech/WireViz` v0.3.3 release source,585591 whose own runtime version is 0.3.2, and stops before external `dot` execution.586592 It rejects filesystem images and raw GraphViz tweaks, bounds YAML expansion,587593 and forwards generated DOT to `graphviz-family`. BOM, HTML, and PNG sidecars588594 remain outside the SVG rendering contract.589595 590-The same hard boundary now applies to all seventeen migrated engines: direct596+The same hard boundary now applies to all eighteen migrated engines: direct591597 unit or client-renderer failure is surfaced to the editor, the gateway rejects592598 their engine IDs before consulting its cache or origin adapter, and every593599 catalog fallback is `null`.
R server/src/main/resources/web/diagramzip/assets/index-WmdMHtkV.js → server/src/main/resources/web/diagramzip/assets/index-584g8mpQ.js +1 -1
@@ -1644,7 +1644,7 @@ Rel(bob, tandem, "Completes tasks")
16441644 \r -퟿-�𐀀-􏿿`,e.S=` \r16451645 `,e.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,e.NAME_CHAR=`-`+e.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,e.CHAR_RE=RegExp(`^[`+e.CHAR+`]$`,`u`),e.S_RE=RegExp(`^[`+e.S+`]+$`,`u`),e.NAME_START_CHAR_RE=RegExp(`^[`+e.NAME_START_CHAR+`]$`,`u`),e.NAME_CHAR_RE=RegExp(`^[`+e.NAME_CHAR+`]$`,`u`),e.NAME_RE=RegExp(`^[`+e.NAME_START_CHAR+`][`+e.NAME_CHAR+`]*$`,`u`),e.NMTOKEN_RE=RegExp(`^[`+e.NAME_CHAR+`]+$`,`u`);var t=9,n=10,r=13,i=32;e.S_LIST=[i,n,r,t];function a(e){return e>=i&&e<=55295||e===n||e===r||e===t||e>=57344&&e<=65533||e>=65536&&e<=1114111}e.isChar=a;function o(e){return e===i||e===n||e===r||e===t}e.isS=o;function s(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}e.isNameStartChar=s;function c(e){return s(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}e.isNameChar=c})),sw=e((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.CHAR=`-퟿-�𐀀-􏿿`,e.RESTRICTED_CHAR=`-\b\v\f--„†-Ÿ`,e.S=` \r16461646 `,e.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,e.NAME_CHAR=`-`+e.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,e.CHAR_RE=RegExp(`^[`+e.CHAR+`]$`,`u`),e.RESTRICTED_CHAR_RE=RegExp(`^[`+e.RESTRICTED_CHAR+`]$`,`u`),e.S_RE=RegExp(`^[`+e.S+`]+$`,`u`),e.NAME_START_CHAR_RE=RegExp(`^[`+e.NAME_START_CHAR+`]$`,`u`),e.NAME_CHAR_RE=RegExp(`^[`+e.NAME_CHAR+`]$`,`u`),e.NAME_RE=RegExp(`^[`+e.NAME_START_CHAR+`][`+e.NAME_CHAR+`]*$`,`u`),e.NMTOKEN_RE=RegExp(`^[`+e.NAME_CHAR+`]+$`,`u`);var t=9,n=10,r=13,i=32;e.S_LIST=[i,n,r,t];function a(e){return e>=1&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111}e.isChar=a;function o(e){return e>=1&&e<=8||e===11||e===12||e>=14&&e<=31||e>=127&&e<=132||e>=134&&e<=159}e.isRestrictedChar=o;function s(e){return e===9||e===10||e===13||e>31&&e<127||e===133||e>159&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111}e.isCharAndNotRestricted=s;function c(e){return e===i||e===n||e===r||e===t}e.isS=c;function l(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}e.isNameStartChar=l;function u(e){return l(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}e.isNameChar=u})),cw=e((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.NC_NAME_START_CHAR=`A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,e.NC_NAME_CHAR=`-`+e.NC_NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,e.NC_NAME_START_CHAR_RE=RegExp(`^[`+e.NC_NAME_START_CHAR+`]$`,`u`),e.NC_NAME_CHAR_RE=RegExp(`^[`+e.NC_NAME_CHAR+`]$`,`u`),e.NC_NAME_RE=RegExp(`^[`+e.NC_NAME_START_CHAR+`][`+e.NC_NAME_CHAR+`]*$`,`u`);function t(e){return e>=65&&e<=90||e===95||e>=97&&e<=122||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}e.isNCNameStartChar=t;function n(e){return t(e)||e===45||e===46||e>=48&&e<=57||e===183||e>=768&&e<=879||e>=8255&&e<=8256}e.isNCNameChar=n})),lw=e((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.SaxesParser=e.EVENTS=void 0;var t=ow(),n=sw(),r=cw(),i=t.isS,a=t.isChar,o=t.isNameStartChar,s=t.isNameChar,c=t.S_LIST,l=t.NAME_RE,u=n.isChar,d=r.isNCNameStartChar,f=r.isNCNameChar,p=r.NC_NAME_RE,m=`http://www.w3.org/XML/1998/namespace`,h=`http://www.w3.org/2000/xmlns/`,g={__proto__:null,xml:m,xmlns:h},_={__proto__:null,amp:`&`,gt:`>`,lt:`<`,quot:`"`,apos:`'`},v=-1,y=-2,ee=0,te=1,ne=2,re=3,b=4,ie=5,ae=6,x=7,oe=8,S=9,se=10,ce=11,le=12,C=13,w=14,ue=15,de=16,fe=17,pe=18,me=19,he=20,T=21,ge=22,_e=23,E=24,ve=25,ye=26,be=27,xe=28,Se=29,Ce=30,we=31,Te=32,Ee=33,De=34,Oe=35,ke=36,Ae=37,je=38,Me=39,Ne=40,Pe=41,Fe=42,Ie=43,Le=44,Re=9,ze=10,Be=13,Ve=32,He=33,Ue=34,We=38,D=39,O=45,Ge=47,Ke=59,qe=60,Je=61,k=62,A=63,Ye=91,Xe=93,j=133,Ze=8232,Qe=e=>e===Ue||e===D,$e=[Ue,D],et=[...$e,Ye,k],M=[...$e,qe,Xe],tt=[Je,A,...c],nt=[...c,k,We,qe];function rt(e,t,n){switch(t){case`xml`:n!==m&&e.fail(`xml prefix must be bound to ${m}.`);break;case`xmlns`:n!==h&&e.fail(`xmlns prefix must be bound to ${h}.`)}switch(n){case h:e.fail(t===``?`the default namespace may not be set to ${n}.`:`may not assign a prefix (even "xmlns") to the URI \1647-${h}.`);break;case m:switch(t){case`xml`:break;case``:e.fail(`the default namespace may not be set to ${n}.`);break;default:e.fail(`may not assign the xml namespace to another prefix.`)}}}function it(e,t){for(let n of Object.keys(t))rt(e,n,t[n])}var at=e=>p.test(e),ot=e=>l.test(e),N=0,st=1,ct=2;e.EVENTS=[`xmldecl`,`text`,`processinginstruction`,`doctype`,`comment`,`opentagstart`,`attribute`,`opentag`,`closetag`,`cdata`,`error`,`end`,`ready`];var lt={xmldecl:`xmldeclHandler`,text:`textHandler`,processinginstruction:`piHandler`,doctype:`doctypeHandler`,comment:`commentHandler`,opentagstart:`openTagStartHandler`,attribute:`attributeHandler`,opentag:`openTagHandler`,closetag:`closeTagHandler`,cdata:`cdataHandler`,error:`errorHandler`,end:`endHandler`,ready:`readyHandler`};e.SaxesParser=class{constructor(e){this.opt=e??{},this.fragmentOpt=!!this.opt.fragment;let t=this.xmlnsOpt=!!this.opt.xmlns;if(this.trackPosition=this.opt.position!==!1,this.fileName=this.opt.fileName,t){this.nameStartCheck=d,this.nameCheck=f,this.isName=at,this.processAttribs=this.processAttribsNS,this.pushAttrib=this.pushAttribNS,this.ns=Object.assign({__proto__:null},g);let e=this.opt.additionalNamespaces;e!=null&&(it(this,e),Object.assign(this.ns,e))}else this.nameStartCheck=o,this.nameCheck=s,this.isName=ot,this.processAttribs=this.processAttribsPlain,this.pushAttrib=this.pushAttribPlain;this.stateTable=[this.sBegin,this.sBeginWhitespace,this.sDoctype,this.sDoctypeQuote,this.sDTD,this.sDTDQuoted,this.sDTDOpenWaka,this.sDTDOpenWakaBang,this.sDTDComment,this.sDTDCommentEnding,this.sDTDCommentEnded,this.sDTDPI,this.sDTDPIEnding,this.sText,this.sEntity,this.sOpenWaka,this.sOpenWakaBang,this.sComment,this.sCommentEnding,this.sCommentEnded,this.sCData,this.sCDataEnding,this.sCDataEnding2,this.sPIFirstChar,this.sPIRest,this.sPIBody,this.sPIEnding,this.sXMLDeclNameStart,this.sXMLDeclName,this.sXMLDeclEq,this.sXMLDeclValueStart,this.sXMLDeclValue,this.sXMLDeclSeparator,this.sXMLDeclEnding,this.sOpenTag,this.sOpenTagSlash,this.sAttrib,this.sAttribName,this.sAttribNameSawWhite,this.sAttribValue,this.sAttribValueQuoted,this.sAttribValueClosed,this.sAttribValueUnquoted,this.sCloseTag,this.sCloseTagSawWhite],this._init()}get closed(){return this._closed}_init(){var e;this.openWakaBang=``,this.text=``,this.name=``,this.piTarget=``,this.entity=``,this.q=null,this.tags=[],this.tag=null,this.topNS=null,this.chunk=``,this.chunkPosition=0,this.i=0,this.prevI=0,this.carriedFromPrevious=void 0,this.forbiddenState=N,this.attribList=[];let{fragmentOpt:t}=this;this.state=t?C:ee,this.reportedTextBeforeRoot=this.reportedTextAfterRoot=this.closedRoot=this.sawRoot=t,this.xmlDeclPossible=!t,this.xmlDeclExpects=[`version`],this.entityReturnState=void 0;let{defaultXMLVersion:n}=this.opt;if(n===void 0){if(this.opt.forceXMLVersion===!0)throw Error(`forceXMLVersion set but defaultXMLVersion is not set`);n=`1.0`}this.setXMLVersion(n),this.positionAtNewLine=0,this.doctype=!1,this._closed=!1,this.xmlDecl={version:void 0,encoding:void 0,standalone:void 0},this.line=1,this.column=0,this.ENTITIES=Object.create(_),(e=this.readyHandler)==null||e.call(this)}get position(){return this.chunkPosition+this.i}get columnIndex(){return this.position-this.positionAtNewLine}on(e,t){this[lt[e]]=t}off(e){this[lt[e]]=void 0}makeError(e){let t=this.fileName??``;return this.trackPosition&&(t.length>0&&(t+=`:`),t+=`${this.line}:${this.column}`),t.length>0&&(t+=`: `),Error(t+e)}fail(e){let t=this.makeError(e),n=this.errorHandler;if(n===void 0)throw t;return n(t),this}write(e){if(this.closed)return this.fail(`cannot write after close; assign an onready handler.`);let t=!1;e===null?(t=!0,e=``):typeof e==`object`&&(e=e.toString()),this.carriedFromPrevious!==void 0&&(e=`${this.carriedFromPrevious}${e}`,this.carriedFromPrevious=void 0);let n=e.length,r=e.charCodeAt(n-1);!t&&(r===Be||r>=55296&&r<=56319)&&(this.carriedFromPrevious=e[n-1],n--,e=e.slice(0,n));let{stateTable:i}=this;for(this.chunk=e,this.i=0;this.i<n;)i[this.state].call(this);return this.chunkPosition+=n,t?this.end():this}close(){return this.write(null)}getCode10(){let{chunk:e,i:t}=this;if(this.prevI=t,this.i=t+1,t>=e.length)return v;let n=e.charCodeAt(t);if(this.column++,n<55296){if(n>=Ve||n===Re)return n;switch(n){case ze:return this.line++,this.column=0,this.positionAtNewLine=this.position,ze;case Be:return e.charCodeAt(t+1)===ze&&(this.i=t+2),this.line++,this.column=0,this.positionAtNewLine=this.position,y;default:return this.fail(`disallowed character.`),n}}if(n>56319)return n>=57344&&n<=65533||this.fail(`disallowed character.`),n;let r=65536+(n-55296)*1024+(e.charCodeAt(t+1)-56320);return this.i=t+2,r>1114111&&this.fail(`disallowed character.`),r}getCode11(){let{chunk:e,i:t}=this;if(this.prevI=t,this.i=t+1,t>=e.length)return v;let n=e.charCodeAt(t);if(this.column++,n<55296){if(n>31&&n<127||n>159&&n!==Ze||n===Re)return n;switch(n){case ze:return this.line++,this.column=0,this.positionAtNewLine=this.position,ze;case Be:{let n=e.charCodeAt(t+1);(n===ze||n===j)&&(this.i=t+2)}case j:case Ze:return this.line++,this.column=0,this.positionAtNewLine=this.position,y;default:return this.fail(`disallowed character.`),n}}if(n>56319)return n>=57344&&n<=65533||this.fail(`disallowed character.`),n;let r=65536+(n-55296)*1024+(e.charCodeAt(t+1)-56320);return this.i=t+2,r>1114111&&this.fail(`disallowed character.`),r}getCodeNorm(){let e=this.getCode();return e===y?ze:e}unget(){this.i=this.prevI,this.column--}captureTo(e){let{i:t}=this,{chunk:n}=this;for(;;){let r=this.getCode(),i=r===y,a=i?ze:r;if(a===v||e.includes(a))return this.text+=n.slice(t,this.prevI),a;i&&(this.text+=`${n.slice(t,this.prevI)}\n`,t=this.i)}}captureToChar(e){let{i:t}=this,{chunk:n}=this;for(;;){let r=this.getCode();switch(r){case y:this.text+=`${n.slice(t,this.prevI)}\n`,t=this.i,r=ze;break;case v:return this.text+=n.slice(t),!1}if(r===e)return this.text+=n.slice(t,this.prevI),!0}}captureNameChars(){let{chunk:e,i:t}=this;for(;;){let n=this.getCode();if(n===v)return this.name+=e.slice(t),v;if(!s(n))return this.name+=e.slice(t,this.prevI),n===y?ze:n}}skipSpaces(){for(;;){let e=this.getCodeNorm();if(e===v||!i(e))return e}}setXMLVersion(e){this.currentXMLVersion=e,e===`1.0`?(this.isChar=a,this.getCode=this.getCode10):(this.isChar=u,this.getCode=this.getCode11)}sBegin(){this.chunk.charCodeAt(0)===65279&&(this.i++,this.column++),this.state=te}sBeginWhitespace(){let e=this.i,t=this.skipSpaces();switch(this.prevI!==e&&(this.xmlDeclPossible=!1),t){case qe:if(this.state=ue,this.text.length!==0)throw Error(`no-empty text at start`);break;case v:break;default:this.unget(),this.state=C,this.xmlDeclPossible=!1}}sDoctype(){var e;let t=this.captureTo(et);switch(t){case k:(e=this.doctypeHandler)==null||e.call(this,this.text),this.text=``,this.state=C,this.doctype=!0;break;case v:break;default:this.text+=String.fromCodePoint(t),t===Ye?this.state=b:Qe(t)&&(this.state=re,this.q=t)}}sDoctypeQuote(){let e=this.q;this.captureToChar(e)&&(this.text+=String.fromCodePoint(e),this.q=null,this.state=ne)}sDTD(){let e=this.captureTo(M);e!==v&&(this.text+=String.fromCodePoint(e),e===Xe?this.state=ne:e===qe?this.state=ae:Qe(e)&&(this.state=ie,this.q=e))}sDTDQuoted(){let e=this.q;this.captureToChar(e)&&(this.text+=String.fromCodePoint(e),this.state=b,this.q=null)}sDTDOpenWaka(){let e=this.getCodeNorm();switch(this.text+=String.fromCodePoint(e),e){case He:this.state=x,this.openWakaBang=``;break;case A:this.state=ce;break;default:this.state=b}}sDTDOpenWakaBang(){let e=String.fromCodePoint(this.getCodeNorm()),t=this.openWakaBang+=e;this.text+=e,t!==`-`&&(this.state=t===`--`?oe:b,this.openWakaBang=``)}sDTDComment(){this.captureToChar(O)&&(this.text+=`-`,this.state=S)}sDTDCommentEnding(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),this.state=e===O?se:oe}sDTDCommentEnded(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),e===k?this.state=b:(this.fail(`malformed comment.`),this.state=oe)}sDTDPI(){this.captureToChar(A)&&(this.text+=`?`,this.state=le)}sDTDPIEnding(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),e===k&&(this.state=b)}sText(){this.tags.length===0?this.handleTextOutsideRoot():this.handleTextInRoot()}sEntity(){let{i:e}=this,{chunk:t}=this;loop:for(;;)switch(this.getCode()){case y:this.entity+=`${t.slice(e,this.prevI)}\n`,e=this.i;break;case Ke:{let{entityReturnState:n}=this,r=this.entity+t.slice(e,this.prevI);this.state=n;let i;r===``?(this.fail(`empty entity name.`),i=`&;`):(i=this.parseEntity(r),this.entity=``),(n!==C||this.textHandler!==void 0)&&(this.text+=i);break loop}case v:this.entity+=t.slice(e);break loop}}sOpenWaka(){let e=this.getCode();if(o(e))this.state=De,this.unget(),this.xmlDeclPossible=!1;else switch(e){case Ge:this.state=Ie,this.xmlDeclPossible=!1;break;case He:this.state=de,this.openWakaBang=``,this.xmlDeclPossible=!1;break;case A:this.state=_e;break;default:this.fail(`disallowed character in tag name`),this.state=C,this.xmlDeclPossible=!1}}sOpenWakaBang(){switch(this.openWakaBang+=String.fromCodePoint(this.getCodeNorm()),this.openWakaBang){case`[CDATA[`:!this.sawRoot&&!this.reportedTextBeforeRoot&&(this.fail(`text data outside of root node.`),this.reportedTextBeforeRoot=!0),this.closedRoot&&!this.reportedTextAfterRoot&&(this.fail(`text data outside of root node.`),this.reportedTextAfterRoot=!0),this.state=he,this.openWakaBang=``;break;case`--`:this.state=fe,this.openWakaBang=``;break;case`DOCTYPE`:this.state=ne,(this.doctype||this.sawRoot)&&this.fail(`inappropriately located doctype declaration.`),this.openWakaBang=``;break;default:this.openWakaBang.length>=7&&this.fail(`incorrect syntax.`)}}sComment(){this.captureToChar(O)&&(this.state=pe)}sCommentEnding(){var e;let t=this.getCodeNorm();t===O?(this.state=me,(e=this.commentHandler)==null||e.call(this,this.text),this.text=``):(this.text+=`-${String.fromCodePoint(t)}`,this.state=fe)}sCommentEnded(){let e=this.getCodeNorm();e===k?this.state=C:(this.fail(`malformed comment.`),this.text+=`--${String.fromCodePoint(e)}`,this.state=fe)}sCData(){this.captureToChar(Xe)&&(this.state=T)}sCDataEnding(){let e=this.getCodeNorm();e===Xe?this.state=ge:(this.text+=`]${String.fromCodePoint(e)}`,this.state=he)}sCDataEnding2(){var e;let t=this.getCodeNorm();switch(t){case k:(e=this.cdataHandler)==null||e.call(this,this.text),this.text=``,this.state=C;break;case Xe:this.text+=`]`;break;default:this.text+=`]]${String.fromCodePoint(t)}`,this.state=he}}sPIFirstChar(){let e=this.getCodeNorm();this.nameStartCheck(e)?(this.piTarget+=String.fromCodePoint(e),this.state=E):e===A||i(e)?(this.fail(`processing instruction without a target.`),this.state=e===A?ye:ve):(this.fail(`disallowed character in processing instruction name.`),this.piTarget+=String.fromCodePoint(e),this.state=E)}sPIRest(){let{chunk:e,i:t}=this;for(;;){let n=this.getCodeNorm();if(n===v){this.piTarget+=e.slice(t);return}if(!this.nameCheck(n)){this.piTarget+=e.slice(t,this.prevI);let r=n===A;r||i(n)?this.piTarget===`xml`?(this.xmlDeclPossible||this.fail(`an XML declaration must be at the start of the document.`),this.state=r?Ee:be):this.state=r?ye:ve:(this.fail(`disallowed character in processing instruction name.`),this.piTarget+=String.fromCodePoint(n));break}}}sPIBody(){if(this.text.length===0){let e=this.getCodeNorm();e===A?this.state=ye:i(e)||(this.text=String.fromCodePoint(e))}else this.captureToChar(A)&&(this.state=ye)}sPIEnding(){var e;let t=this.getCodeNorm();if(t===k){let{piTarget:t}=this;t.toLowerCase()===`xml`&&this.fail(`the XML declaration must appear at the start of the document.`),(e=this.piHandler)==null||e.call(this,{target:t,body:this.text}),this.piTarget=this.text=``,this.state=C}else t===A?this.text+=`?`:(this.text+=`?${String.fromCodePoint(t)}`,this.state=ve);this.xmlDeclPossible=!1}sXMLDeclNameStart(){let e=this.skipSpaces();if(e===A){this.state=Ee;return}e!==v&&(this.state=xe,this.name=String.fromCodePoint(e))}sXMLDeclName(){let e=this.captureTo(tt);if(e===A){this.state=Ee,this.name+=this.text,this.text=``,this.fail(`XML declaration is incomplete.`);return}if(i(e)||e===Je){if(this.name+=this.text,this.text=``,!this.xmlDeclExpects.includes(this.name))switch(this.name.length){case 0:this.fail(`did not expect any more name/value pairs.`);break;case 1:this.fail(`expected the name ${this.xmlDeclExpects[0]}.`);break;default:this.fail(`expected one of ${this.xmlDeclExpects.join(`, `)}`)}this.state=e===Je?Ce:Se}}sXMLDeclEq(){let e=this.getCodeNorm();if(e===A){this.state=Ee,this.fail(`XML declaration is incomplete.`);return}i(e)||(e!==Je&&this.fail(`value required.`),this.state=Ce)}sXMLDeclValueStart(){let e=this.getCodeNorm();if(e===A){this.state=Ee,this.fail(`XML declaration is incomplete.`);return}i(e)||(Qe(e)?this.q=e:(this.fail(`value must be quoted.`),this.q=Ve),this.state=we)}sXMLDeclValue(){let e=this.captureTo([this.q,A]);if(e===A){this.state=Ee,this.text=``,this.fail(`XML declaration is incomplete.`);return}if(e===v)return;let t=this.text;switch(this.text=``,this.name){case`version`:{this.xmlDeclExpects=[`encoding`,`standalone`];let e=t;this.xmlDecl.version=e,/^1\.[0-9]+$/.test(e)?this.opt.forceXMLVersion||this.setXMLVersion(e):this.fail(`version number must match /^1\\.[0-9]+$/.`);break}case`encoding`:/^[A-Za-z][A-Za-z0-9._-]*$/.test(t)||this.fail(`encoding value must match /^[A-Za-z0-9][A-Za-z0-9._-]*$/.`),this.xmlDeclExpects=[`standalone`],this.xmlDecl.encoding=t;break;case`standalone`:t!==`yes`&&t!==`no`&&this.fail(`standalone value must match "yes" or "no".`),this.xmlDeclExpects=[],this.xmlDecl.standalone=t}this.name=``,this.state=Te}sXMLDeclSeparator(){let e=this.getCodeNorm();if(e===A){this.state=Ee;return}i(e)||(this.fail(`whitespace required.`),this.unget()),this.state=be}sXMLDeclEnding(){var e;this.getCodeNorm()===k?(this.piTarget===`xml`?this.name!==`version`&&this.xmlDeclExpects.includes(`version`)&&this.fail(`XML declaration must contain a version.`):this.fail(`processing instructions are not allowed before root.`),(e=this.xmldeclHandler)==null||e.call(this,this.xmlDecl),this.name=``,this.piTarget=this.text=``,this.state=C):this.fail(`The character ? is disallowed anywhere in XML declarations.`),this.xmlDeclPossible=!1}sOpenTag(){var e;let t=this.captureNameChars();if(t===v)return;let n=this.tag={name:this.name,attributes:Object.create(null)};switch(this.name=``,this.xmlnsOpt&&(this.topNS=n.ns=Object.create(null)),(e=this.openTagStartHandler)==null||e.call(this,n),this.sawRoot=!0,!this.fragmentOpt&&this.closedRoot&&this.fail(`documents may contain only one root.`),t){case k:this.openTag();break;case Ge:this.state=Oe;break;default:i(t)||this.fail(`disallowed character in tag name.`),this.state=ke}}sOpenTagSlash(){this.getCode()===k?this.openSelfClosingTag():(this.fail(`forward-slash in opening tag not followed by >.`),this.state=ke)}sAttrib(){let e=this.skipSpaces();e!==v&&(o(e)?(this.unget(),this.state=Ae):e===k?this.openTag():e===Ge?this.state=Oe:this.fail(`disallowed character in attribute name.`))}sAttribName(){let e=this.captureNameChars();e===Je?this.state=Me:i(e)?this.state=je:e===k?(this.fail(`attribute without value.`),this.pushAttrib(this.name,this.name),this.name=this.text=``,this.openTag()):e!==v&&this.fail(`disallowed character in attribute name.`)}sAttribNameSawWhite(){let e=this.skipSpaces();switch(e){case v:return;case Je:this.state=Me;break;default:this.fail(`attribute without value.`),this.text=``,this.name=``,e===k?this.openTag():o(e)?(this.unget(),this.state=Ae):(this.fail(`disallowed character in attribute name.`),this.state=ke)}}sAttribValue(){let e=this.getCodeNorm();Qe(e)?(this.q=e,this.state=Ne):i(e)||(this.fail(`unquoted attribute value.`),this.state=Fe,this.unget())}sAttribValueQuoted(){let{q:e,chunk:t}=this,{i:n}=this;for(;;)switch(this.getCode()){case e:this.pushAttrib(this.name,this.text+t.slice(n,this.prevI)),this.name=this.text=``,this.q=null,this.state=Pe;return;case We:this.text+=t.slice(n,this.prevI),this.state=w,this.entityReturnState=Ne;return;case ze:case y:case Re:this.text+=`${t.slice(n,this.prevI)} `,n=this.i;break;case qe:this.text+=t.slice(n,this.prevI),this.fail(`disallowed character.`);return;case v:this.text+=t.slice(n);return}}sAttribValueClosed(){let e=this.getCodeNorm();i(e)?this.state=ke:e===k?this.openTag():e===Ge?this.state=Oe:o(e)?(this.fail(`no whitespace between attributes.`),this.unget(),this.state=Ae):this.fail(`disallowed character in attribute name.`)}sAttribValueUnquoted(){let e=this.captureTo(nt);switch(e){case We:this.state=w,this.entityReturnState=Fe;break;case qe:this.fail(`disallowed character.`);break;case v:break;default:this.text.includes(`]]>`)&&this.fail(`the string "]]>" is disallowed in char data.`),this.pushAttrib(this.name,this.text),this.name=this.text=``,e===k?this.openTag():this.state=ke}}sCloseTag(){let e=this.captureNameChars();e===k?this.closeTag():i(e)?this.state=Le:e!==v&&this.fail(`disallowed character in closing tag.`)}sCloseTagSawWhite(){switch(this.skipSpaces()){case k:this.closeTag();break;case v:break;default:this.fail(`disallowed character in closing tag.`)}}handleTextInRoot(){let{i:e,forbiddenState:t}=this,{chunk:n,textHandler:r}=this;scanLoop:for(;;)switch(this.getCode()){case qe:if(this.state=ue,r!==void 0){let{text:t}=this,i=n.slice(e,this.prevI);t.length===0?i.length!==0&&r(i):(r(t+i),this.text=``)}t=N;break scanLoop;case We:this.state=w,this.entityReturnState=C,r!==void 0&&(this.text+=n.slice(e,this.prevI)),t=N;break scanLoop;case Xe:switch(t){case N:t=st;break;case st:t=ct;break;case ct:break;default:throw Error(`impossible state`)}break;case k:t===ct&&this.fail(`the string "]]>" is disallowed in char data.`),t=N;break;case y:r!==void 0&&(this.text+=`${n.slice(e,this.prevI)}\n`),e=this.i,t=N;break;case v:r!==void 0&&(this.text+=n.slice(e));break scanLoop;default:t=N}this.forbiddenState=t}handleTextOutsideRoot(){let{i:e}=this,{chunk:t,textHandler:n}=this,r=!1;outRootLoop:for(;;){let a=this.getCode();switch(a){case qe:if(this.state=ue,n!==void 0){let{text:r}=this,i=t.slice(e,this.prevI);r.length===0?i.length!==0&&n(i):(n(r+i),this.text=``)}break outRootLoop;case We:this.state=w,this.entityReturnState=C,n!==void 0&&(this.text+=t.slice(e,this.prevI)),r=!0;break outRootLoop;case y:n!==void 0&&(this.text+=`${t.slice(e,this.prevI)}\n`),e=this.i;break;case v:n!==void 0&&(this.text+=t.slice(e));break outRootLoop;default:i(a)||(r=!0)}}r&&(!this.sawRoot&&!this.reportedTextBeforeRoot&&(this.fail(`text data outside of root node.`),this.reportedTextBeforeRoot=!0),this.closedRoot&&!this.reportedTextAfterRoot&&(this.fail(`text data outside of root node.`),this.reportedTextAfterRoot=!0))}pushAttribNS(e,t){var n;let{prefix:r,local:i}=this.qname(e),a={name:e,prefix:r,local:i,value:t};if(this.attribList.push(a),(n=this.attributeHandler)==null||n.call(this,a),r===`xmlns`){let e=t.trim();this.currentXMLVersion===`1.0`&&e===``&&this.fail(`invalid attempt to undefine prefix in XML 1.0`),this.topNS[i]=e,rt(this,i,e)}else if(e===`xmlns`){let e=t.trim();this.topNS[``]=e,rt(this,``,e)}}pushAttribPlain(e,t){var n;let r={name:e,value:t};this.attribList.push(r),(n=this.attributeHandler)==null||n.call(this,r)}end(){var e,t;this.sawRoot||this.fail(`document must contain a root element.`);let{tags:n}=this;for(;n.length>0;){let e=n.pop();this.fail(`unclosed tag: ${e.name}`)}this.state!==ee&&this.state!==C&&this.fail(`unexpected end.`);let{text:r}=this;return r.length!==0&&((e=this.textHandler)==null||e.call(this,r),this.text=``),this._closed=!0,(t=this.endHandler)==null||t.call(this),this._init(),this}resolve(e){var t;let n=this.topNS[e];if(n!==void 0)return n;let{tags:r}=this;for(let t=r.length-1;t>=0;t--)if(n=r[t].ns[e],n!==void 0)return n;return n=this.ns[e],n===void 0?(t=this.opt).resolvePrefix?.call(t,e):n}qname(e){let t=e.indexOf(`:`);if(t===-1)return{prefix:``,local:e};let n=e.slice(t+1),r=e.slice(0,t);return(r===``||n===``||n.includes(`:`))&&this.fail(`malformed name: ${e}.`),{prefix:r,local:n}}processAttribsNS(){let{attribList:e}=this,t=this.tag;{let{prefix:e,local:n}=this.qname(t.name);t.prefix=e,t.local=n;let r=t.uri=this.resolve(e)??``;e!==``&&(e===`xmlns`&&this.fail(`tags may not have "xmlns" as prefix.`),r===``&&(this.fail(`unbound namespace prefix: ${JSON.stringify(e)}.`),t.uri=e))}if(e.length===0)return;let{attributes:n}=t,r=new Set;for(let t of e){let{name:e,prefix:i,local:a}=t,o,s;i===``?(o=e===`xmlns`?h:``,s=e):(o=this.resolve(i),o===void 0&&(this.fail(`unbound namespace prefix: ${JSON.stringify(i)}.`),o=i),s=`{${o}}${a}`),r.has(s)&&this.fail(`duplicate attribute: ${s}.`),r.add(s),t.uri=o,n[e]=t}this.attribList=[]}processAttribsPlain(){let{attribList:e}=this,t=this.tag.attributes;for(let{name:n,value:r}of e)t[n]!==void 0&&this.fail(`duplicate attribute: ${n}.`),t[n]=r;this.attribList=[]}openTag(){var e;this.processAttribs();let{tags:t}=this,n=this.tag;n.isSelfClosing=!1,(e=this.openTagHandler)==null||e.call(this,n),t.push(n),this.state=C,this.name=``}openSelfClosingTag(){var e,t;this.processAttribs();let{tags:n}=this,r=this.tag;r.isSelfClosing=!0,(e=this.openTagHandler)==null||e.call(this,r),(t=this.closeTagHandler)==null||t.call(this,r),(this.tag=n[n.length-1]??null)===null&&(this.closedRoot=!0),this.state=C,this.name=``}closeTag(){let{tags:e,name:t}=this;if(this.state=C,this.name=``,t===``){this.fail(`weird empty close tag.`),this.text+=`</>`;return}let n=this.closeTagHandler,r=e.length;for(;r-->0;){let r=this.tag=e.pop();if(this.topNS=r.ns,n?.(r),r.name===t)break;this.fail(`unexpected close tag.`)}r===0?this.closedRoot=!0:r<0&&(this.fail(`unmatched closing tag: ${t}.`),this.text+=`</${t}>`)}parseEntity(e){if(e[0]!==`#`){let t=this.ENTITIES[e];return t===void 0?(this.fail(this.isName(e)?`undefined entity.`:`disallowed character in entity name.`),`&${e};`):t}let t=NaN;return e[1]===`x`&&/^#x[0-9a-f]+$/i.test(e)?t=parseInt(e.slice(2),16):/^#[0-9]+$/.test(e)&&(t=parseInt(e.slice(1),10)),this.isChar(t)?String.fromCodePoint(t):(this.fail(`malformed character entity.`),`&${e};`)}}}))(),uw=4194304,dw=new Set([`script`,`iframe`,`object`,`embed`,`audio`,`video`]),fw=new Set([`foreignobject`,`div`,`span`,`p`,`br`,`b`,`strong`,`i`,`em`,`small`,`sub`,`sup`,`code`,`ul`,`ol`,`li`,`a`]),pw=/^data:image\/(?:png|jpeg|gif|webp);base64,[a-z0-9+/=\s]+$/i,mw=/^data:(?:font\/(?:woff2?|opentype|truetype)|application\/(?:x-)?font-woff2?);base64,[a-z0-9+/=\s]+$/i,hw=class extends Error{constructor(e){super(e),this.name=`ClientSvgError`}};function gw(e){let t=e.trim();return t.startsWith(`#`)||pw.test(t)||mw.test(t)}function _w(e){if(/@import|expression\s*\(|javascript\s*:|data\s*:\s*text\/html|behavior\s*:|-moz-binding/i.test(e))return!0;let t=/url\s*\(\s*(['"]?)(.*?)\1\s*\)/gi;for(let n of e.matchAll(t))if(!gw(n[2]??``))return!0;return/url\s*\(/i.test(e.replace(t,``))}function vw(e){let t=e.trim();return t.startsWith(`#`)||pw.test(t)}function yw(e,t){let n=e.toLowerCase();return n.startsWith(`on`)?!1:n===`href`||n===`xlink:href`||n===`src`?vw(t):[`style`,`filter`,`fill`,`stroke`,`clip-path`,`mask`].includes(n)?!_w(t):n!==`xml:base`&&!/javascript\s*:/i.test(t)}function bw(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`)}function xw(e){return bw(e).replaceAll(`"`,`&quot;`)}function Sw(e){if(e.type===`text`)return bw(e.value);let t=[...e.attributes].map(([e,t])=>` ${e}="${xw(t)}"`).join(``);return`<${e.name}${t}>${e.children.map(Sw).join(``)}</${e.name}>`}function Cw(e){return e.name.toLowerCase().split(`:`).at(-1)??e.name.toLowerCase()}function ww(e){if(e===void 0||!/^-?\d+(?:\.\d+)?(?:px)?$/.test(e.trim()))return null;let t=Number.parseFloat(e);return Number.isFinite(t)&&t>0?t:null}function Tw(e){let t=e.attributes.get(`viewBox`)?.trim().split(/[\s,]+/).map(Number);if(t?.length===4&&t.every(Number.isFinite)&&t[2]>0&&t[3]>0)return t;let n=ww(e.attributes.get(`width`)),r=ww(e.attributes.get(`height`));return n!==null&&r!==null?[0,0,n,r]:null}function Ew(e,t){let n=e.attributes.get(`style`);if(!n)return null;for(let e of n.split(`;`)){let n=e.indexOf(`:`);if(n>=0&&e.slice(0,n).trim().toLowerCase()===t)return e.slice(n+1).trim()}return null}function Dw(e){let t=(e.attributes.get(`fill`)??Ew(e,`fill`)??``).replaceAll(` `,``).toLowerCase();return t===`white`||t===`#fff`||t===`#ffffff`||t===`rgb(255,255,255)`}function Ow(e){if(e===void 0||!/^-?\d+(?:\.\d+)?$/.test(e.trim()))return null;let t=Number(e);return Number.isFinite(t)?t:null}function kw(e,t){let n=e.attributes.get(`width`)?.trim(),r=e.attributes.get(`height`)?.trim();if(n===`100%`&&r===`100%`)return!0;let i=Ow(e.attributes.get(`x`)??`0`),a=Ow(e.attributes.get(`y`)??`0`),o=Ow(n),s=Ow(r);if([i,a,o,s].some(e=>e===null))return!1;let[c,l,u,d]=t,f=.01;return i<=c+f&&a<=l+f&&i+o>=c+u-f&&a+s>=l+d-f}function Aw(e,t,n){let r=Cw(e),i=new Set((e.attributes.get(`class`)??``).toLowerCase().split(/\s+/));return r===`rect`&&i.has(`backdrop`)||r===`rect`&&t!==null&&Dw(e)&&kw(e,t)?!0:n===`graphviz`&&r===`polygon`&&Dw(e)&&(e.attributes.get(`stroke`)??``).toLowerCase()===`none`}function jw(e,t,n){let r=Cw(e)===`svg`?Tw(e)??t:t;e.children=e.children.filter(e=>e.type===`text`||!Aw(e,r,n)&&(jw(e,r,n),!0))}function Mw(e,t){let n=(e.attributes.get(`style`)??``).split(`;`).map(e=>e.trim()).filter(Boolean).filter(e=>!/^background(?:-color)?\s*:/i.test(e));n.push(`background-color:${t}`),e.attributes.set(`style`,`${n.join(`;`)};`)}function Nw(e,t=[],n=[]){return{type:`element`,name:e,attributes:new Map(t),children:n}}function Pw(e,t,n,r){let i=[],a=null;t.title&&i.push(Nw(`title`,[],[{type:`text`,value:t.title}])),t.description&&i.push(Nw(`desc`,[],[{type:`text`,value:t.description}]));let o=Tw(e);if((n.padding||n.background||n.frame)&&o===null)throw new hw(`Renderer output has no usable SVG dimensions for presentation settings.`);if(o!==null){let[t,r,s,c]=o,l=n.padding,u=[t-l,r-l,s+l*2,c+l*2];e.attributes.set(`viewBox`,u.join(` `)),e.attributes.has(`width`)&&e.attributes.set(`width`,String(u[2])),e.attributes.has(`height`)&&e.attributes.set(`height`,String(u[3])),n.background&&i.push(Nw(`rect`,[[`x`,String(u[0])],[`y`,String(u[1])],[`width`,String(u[2])],[`height`,String(u[3])],[`fill`,n.background]])),n.frame&&(a=Nw(`rect`,[[`x`,String(u[0]+.5)],[`y`,String(u[1]+.5)],[`width`,String(Math.max(0,u[2]-1))],[`height`,String(Math.max(0,u[3]-1))],[`fill`,`none`],[`stroke`,`#000000`],[`stroke-width`,`1`],[`vector-effect`,`non-scaling-stroke`]]))}n.background&&(jw(e,o,r),Mw(e,n.background)),e.children.unshift(...i),a&&e.children.push(a)}function Fw(e,t,n,r){if(e.length>uw)throw new hw(`Rendered SVG is too large.`);let i=null,a=[],o=0,s=null,c=new lw.SaxesParser({xmlns:!0});c.on(`doctype`,e=>{e.includes(`[`)&&(s=Error(`Internal DOCTYPE subsets are not allowed`))}),c.on(`opentag`,e=>{let t=e.local.toLowerCase(),n=t===`foreignobject`||a.some(e=>Cw(e)===`foreignobject`);if(o>0||dw.has(t)||n&&!fw.has(t)){o++;return}let r=Nw(e.name);for(let t of Object.values(e.attributes))yw(t.name,t.value)&&r.attributes.set(t.name,t.value);let c=a.at(-1);c?c.children.push(r):i===null?i=r:s=Error(`Multiple root elements`),a.push(r)});let l=e=>{if(o>0||e===``)return;let t=a.at(-1);if(t){if(Cw(t)===`style`&&_w(e))throw new hw(`Renderer output contains unsafe CSS.`);t.children.push({type:`text`,value:e})}else e.trim()!==``&&(s=Error(`Text outside root element`))};c.on(`text`,l),c.on(`cdata`,l),c.on(`closetag`,()=>{o>0?o--:a.pop()}),c.on(`error`,e=>{s=e});try{c.write(e).close()}catch(e){if(e instanceof hw)throw e;s=e}if(s!==null||i===null||Cw(i)!==`svg`)throw new hw(`Renderer returned invalid SVG.`);return Pw(i,t,n,r),Sw(i)}var Iw=Object.freeze({plantuml:`https://plantuml.render.diagram.zip/v1/svg`,graphviz:`https://graphviz.render.diagram.zip/v1/svg`,d2:`https://d2.render.diagram.zip/v1/svg`,c4plantuml:`https://c4plantuml.render.diagram.zip/v1/svg`,blockdiag:`https://blockdiag.render.diagram.zip/v1/svg`,seqdiag:`https://seqdiag.render.diagram.zip/v1/svg`,actdiag:`https://actdiag.render.diagram.zip/v1/svg`,nwdiag:`https://nwdiag.render.diagram.zip/v1/svg`,packetdiag:`https://packetdiag.render.diagram.zip/v1/svg`,rackdiag:`https://rackdiag.render.diagram.zip/v1/svg`,bytefield:`https://bytefield.render.diagram.zip/v1/svg`,dbml:`https://dbml.render.diagram.zip/v1/svg`,diagramsnet:`https://diagramsnet.render.diagram.zip/v1/svg`,ditaa:`https://ditaa.render.diagram.zip/v1/svg`,erd:`https://erd.render.diagram.zip/v1/svg`,goat:`https://goat.render.diagram.zip/v1/svg`,nomnoml:`https://nomnoml.render.diagram.zip/v1/svg`,pikchr:`https://pikchr.render.diagram.zip/v1/svg`,structurizr:`https://structurizr.render.diagram.zip/v1/svg`,svgbob:`https://svgbob.render.diagram.zip/v1/svg`,symbolator:`https://symbolator.render.diagram.zip/v1/svg`,tikz:`https://tikz.render.diagram.zip/v1/svg`,umlet:`https://umlet.render.diagram.zip/v1/svg`,vega:`https://vega.render.diagram.zip/v1/svg`,vegalite:`https://vegalite.render.diagram.zip/v1/svg`,wavedrom:`https://wavedrom.render.diagram.zip/v1/svg`,wireviz:`https://wireviz.render.diagram.zip/v1/svg`}),Lw=Object.freeze([`mermaid`,`bpmn`,`excalidraw`,`bytefield`,`nomnoml`,`vega`,`vegalite`,`wavedrom`,`blockdiag`,`seqdiag`,`actdiag`,`nwdiag`,`packetdiag`,`rackdiag`]);function Rw(e){return Lw.includes(e)}function zw(e){return Iw[e]??null}function Bw(e,t,n){return Math.min(Math.max(e,t),n)}var Vw=class{constructor({stage:e,image:t,status:n,minimap:r,minimapImage:i,minimapViewport:a}){this.stage=e,this.image=t,this.status=n,this.minimap=r,this.minimapImage=i,this.minimapViewport=a,this.scale=1,this.x=0,this.y=0,this.objectUrl=null,this.abortController=null,this.requestNumber=0,this.pendingRender=null,this.renderLoop=null,this.latestRenderKey=null,this.latestSvgBlob=null,this.latestRendererIdentity=null,this.imageFallbackUrl=null,this.activeImageUrl=null,this.drag=null,this.image.addEventListener(`load`,()=>{this.image.src===this.activeImageUrl&&(this.imageFallbackUrl=null,this.setStatus(`Rendered`,`ready`),this.fit())}),this.image.addEventListener(`error`,()=>this.retryBlockedImage()),this.stage.addEventListener(`pointerdown`,e=>this.startPan(e)),this.stage.addEventListener(`pointermove`,e=>this.pan(e)),this.stage.addEventListener(`pointerup`,e=>this.endPan(e)),this.stage.addEventListener(`pointercancel`,e=>this.endPan(e)),this.stage.addEventListener(`wheel`,e=>this.wheelZoom(e),{passive:!1}),this.minimap.addEventListener(`pointerdown`,e=>this.moveFromMinimap(e)),new ResizeObserver(()=>this.updateTransform()).observe(this.stage)}render({type:e,source:t,options:n={},meta:r={},presentation:i={}}){if(!t.trim()){this.requestNumber++,this.pendingRender=null,this.abortController?.abort(),this.setStatus(`Write something to render.`,`idle`);return}let a=JSON.stringify({type:e,source:t,options:n,meta:r,presentation:i});return this.latestRenderKey===a&&this.latestSvgBlob?Promise.resolve():(this.pendingRender={type:e,source:t,options:n,meta:r,presentation:i,renderKey:a,requestNumber:++this.requestNumber},this.abortController?.abort(),this.renderLoop||=this.drainRenderQueue(),this.renderLoop)}async drainRenderQueue(){try{for(;this.pendingRender;){let e=this.pendingRender;this.pendingRender=null,await this.performRender(e)}}finally{this.renderLoop=null,this.pendingRender&&(this.renderLoop=this.drainRenderQueue())}}async performRender({type:e,source:t,options:n,meta:r,presentation:i,renderKey:a,requestNumber:o}){let s=new AbortController;this.abortController=s,this.setStatus(`Rendering…`,`loading`),this.stage.style.setProperty(`--render-background`,`var(--preview-bg)`);try{let c=aw(e),l;if(c)try{let a=await c.render({type:e,source:t,options:n},s.signal);l={body:Fw(a.body,r,i,e),identity:{unit:e,build:a.build||a.version,pipeline:Array.isArray(a.pipeline)?a.pipeline:[e]}},this.status.dataset.cache=`browser`,this.status.dataset.renderer=e}catch(a){if(a.name===`AbortError`||Rw(e))throw a;l=await this.renderThroughGateway({type:e,source:t,options:n,meta:r,presentation:i},s.signal)}else l=await this.renderThroughGateway({type:e,source:t,options:n,meta:r,presentation:i},s.signal);if(o!==this.requestNumber)return;let{blob:u,background:d}=this.normalizedSvgBlob(l.body);this.latestRenderKey=a,this.latestSvgBlob=u,this.latestRendererIdentity=l.identity,this.imageFallbackUrl=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(await u.text())}`,this.stage.style.setProperty(`--render-background`,d);let f=URL.createObjectURL(u),p=this.objectUrl;this.objectUrl=f,this.activeImageUrl=f,this.image.src=f,this.minimapImage.src=f,this.image.hidden=!1,this.setStatus(`Loading image…`,`loading`),p&&URL.revokeObjectURL(p)}catch(e){if(e.name===`AbortError`)return;this.setStatus(e.message||`Could not render this diagram.`,`error`)}finally{this.abortController===s&&(this.abortController=null)}}async renderThroughGateway({type:e,source:t,options:n,meta:r,presentation:i},a){let o=zw(e);if(o){try{let s=await this.renderRequest(o,{source:t,format:`svg`,options:n,metadata:r,presentation:i},a);if(s.ok||s.status<500)return await this.renderResponse(s,e);await s.body?.cancel()}catch(t){if(t.name===`AbortError`||Rw(e))throw t}if(Rw(e))throw Error(`The ${e} renderer unit is unavailable.`)}let s=await this.renderRequest(`/render/v1/svg`,{engine:e,source:t,format:`svg`,options:n,metadata:r,presentation:i},a);return this.renderResponse(s,e)}renderRequest(e,t,n){return fetch(e,{method:`POST`,headers:{Accept:`image/svg+xml`,"Content-Type":`application/json`},body:JSON.stringify(t),signal:n})}async renderResponse(e,t){if(!e.ok)throw Error(await this.errorMessage(e));this.status.dataset.cache=e.headers.get(`X-Diagram-Cache`)?.toLowerCase()??`miss`,this.status.dataset.renderer=e.headers.get(`X-Diagram-Unit`)?.toLowerCase()??e.headers.get(`X-Diagram-Renderer`)?.toLowerCase()??`gateway`;let n=e.headers.get(`X-Diagram-Unit`)?.toLowerCase()??e.headers.get(`X-Diagram-Engine`)?.toLowerCase()??t,r=e.headers.get(`X-Renderer-Build`)??e.headers.get(`X-Diagram-Engine-Version`)??`${n}-unknown`,i=(e.headers.get(`X-Diagram-Pipeline`)??n).split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean);return{body:await e.text(),identity:{unit:n,build:r,pipeline:i}}}retryBlockedImage(){if(this.image.src===this.activeImageUrl){if(this.imageFallbackUrl&&this.activeImageUrl.startsWith(`blob:`)){let e=this.imageFallbackUrl;this.imageFallbackUrl=null,this.objectUrl&&URL.revokeObjectURL(this.objectUrl),this.objectUrl=null,this.activeImageUrl=e,this.image.src=e,this.minimapImage.src=e;return}this.setStatus(`The rendered image was blocked or invalid.`,`error`)}}svgBlobFor(e){let{type:t,source:n,options:r={},meta:i={},presentation:a={}}=e,o=JSON.stringify({type:t,source:n,options:r,meta:i,presentation:a});return this.latestRenderKey===o?this.latestSvgBlob:null}rendererIdentityFor(e){let{type:t,source:n,options:r={},meta:i={},presentation:a={}}=e,o=JSON.stringify({type:t,source:n,options:r,meta:i,presentation:a});return this.latestRenderKey===o?this.latestRendererIdentity:null}async errorMessage(e){let t=await e.text();if(e.headers.get(`Content-Type`)?.includes(`application/json`))try{let e=JSON.parse(t);if(typeof e?.error?.message==`string`)return e.error.message}catch{}return new DOMParser().parseFromString(t,`text/html`).body.textContent.trim().replace(/\s+/g,` `)||`Render failed with HTTP ${e.status}.`}normalizedSvgBlob(e){let t=new DOMParser().parseFromString(e,`image/svg+xml`).documentElement,n=t.getAttribute(`viewBox`)?.trim().split(/[\s,]+/).map(Number);t.nodeName===`svg`&&n?.length===4&&n.every(Number.isFinite)&&(t.hasAttribute(`width`)||t.setAttribute(`width`,String(n[2])),t.hasAttribute(`height`)||t.setAttribute(`height`,String(n[3])),e=new XMLSerializer().serializeToString(t));let r=t.style.backgroundColor||t.style.background,i=r&&r!==`transparent`?r:`#ffffff`;return{blob:new Blob([e],{type:`image/svg+xml`}),background:i}}setStatus(e,t){this.status.textContent=e,this.status.dataset.state=t}zoom(e){if(this.image.hidden)return;let t=this.stage.getBoundingClientRect();this.zoomAt(e,t.width/2,t.height/2)}zoomAt(e,t,n){let r=Bw(this.scale*e,.1,8),i=(t-this.x)/this.scale,a=(n-this.y)/this.scale;this.x=t-i*r,this.y=n-a*r,this.scale=r,this.updateTransform()}wheelZoom(e){if(this.image.hidden||e.target.closest(`.preview-toolbar, .minimap`))return;e.preventDefault();let t=this.stage.getBoundingClientRect(),n=e.deltaY*(e.deltaMode===WheelEvent.DOM_DELTA_LINE?16:e.deltaMode===WheelEvent.DOM_DELTA_PAGE?t.height:1);this.zoomAt(Math.exp(-Bw(n,-240,240)*.002),e.clientX-t.left,e.clientY-t.top)}oneToOne(){if(this.image.hidden)return;let e=this.stage.getBoundingClientRect();this.scale=1,this.x=(e.width-this.image.naturalWidth)/2,this.y=(e.height-this.image.naturalHeight)/2,this.updateTransform()}fit(){if(!this.image.naturalWidth||!this.image.naturalHeight)return;let e=this.stage.getBoundingClientRect(),t=Math.min(64,e.width*.12);this.scale=Bw(Math.min((e.width-t*2)/this.image.naturalWidth,(e.height-t*2)/this.image.naturalHeight),.1,2),this.x=(e.width-this.image.naturalWidth*this.scale)/2,this.y=(e.height-this.image.naturalHeight*this.scale)/2,this.updateTransform()}updateTransform(){this.image.style.transform=`translate(${this.x}px, ${this.y}px) scale(${this.scale})`,this.updateMinimap()}startPan(e){this.image.hidden||e.button!==0||e.target.closest(`.preview-toolbar, .minimap`)||(this.drag={pointerId:e.pointerId,x:e.clientX,y:e.clientY,originX:this.x,originY:this.y},this.stage.setPointerCapture(e.pointerId),this.stage.dataset.dragging=`true`)}pan(e){!this.drag||e.pointerId!==this.drag.pointerId||(this.x=this.drag.originX+e.clientX-this.drag.x,this.y=this.drag.originY+e.clientY-this.drag.y,this.updateTransform())}endPan(e){!this.drag||e.pointerId!==this.drag.pointerId||(this.drag=null,delete this.stage.dataset.dragging)}moveFromMinimap(e){if(!this.image.naturalWidth||!this.image.naturalHeight)return;let t=this.minimap.getBoundingClientRect(),n=Math.min(t.width/this.image.naturalWidth,t.height/this.image.naturalHeight),r=(t.width-this.image.naturalWidth*n)/2,i=(t.height-this.image.naturalHeight*n)/2,a=(e.clientX-t.left-r)/n,o=(e.clientY-t.top-i)/n,s=this.stage.getBoundingClientRect();this.x=s.width/2-a*this.scale,this.y=s.height/2-o*this.scale,this.updateTransform()}updateMinimap(){if(!this.image.naturalWidth||!this.image.naturalHeight)return;let e=this.stage.getBoundingClientRect(),t=this.image.naturalWidth*this.scale,n=this.image.naturalHeight*this.scale,r=this.x>=0&&this.y>=0&&this.x+t<=e.width&&this.y+n<=e.height;if(this.minimap.hidden=r,r)return;let i=this.minimap.getBoundingClientRect(),a=Math.min(i.width/this.image.naturalWidth,i.height/this.image.naturalHeight),o=(i.width-this.image.naturalWidth*a)/2,s=(i.height-this.image.naturalHeight*a)/2,c=Bw(-this.x/this.scale,0,this.image.naturalWidth),l=Bw(-this.y/this.scale,0,this.image.naturalHeight),u=Bw((e.width-this.x)/this.scale,0,this.image.naturalWidth),d=Bw((e.height-this.y)/this.scale,0,this.image.naturalHeight);this.minimapViewport.style.left=`${o+c*a}px`,this.minimapViewport.style.top=`${s+l*a}px`,this.minimapViewport.style.width=`${Math.max(4,(u-c)*a)}px`,this.minimapViewport.style.height=`${Math.max(4,(d-l)*a)}px`}},Hw=`diagram.zip:draft:local:v2`,Uw=`diagram.zip:draft:alias:v1:`,Ww=`diagram.zip:write:v1:`,Gw=new ke,Kw=new kC,qw,Jw=!1,Yw,Xw=!1,Zw=``,Q={aliasId:null,contentId:null,renderId:null,revision:null,mode:`open`,savedMode:null,writeCapability:null,savedState:null,savedSnapshot:null,bundleKey:null,keyEnvelope:null,encryptedContent:null,encryptedMetadata:null,keyEnvelopeDirty:!1,dirty:!0},Qw=new Map;document.querySelector(`#app`).innerHTML=`1647+${h}.`);break;case m:switch(t){case`xml`:break;case``:e.fail(`the default namespace may not be set to ${n}.`);break;default:e.fail(`may not assign the xml namespace to another prefix.`)}}}function it(e,t){for(let n of Object.keys(t))rt(e,n,t[n])}var at=e=>p.test(e),ot=e=>l.test(e),N=0,st=1,ct=2;e.EVENTS=[`xmldecl`,`text`,`processinginstruction`,`doctype`,`comment`,`opentagstart`,`attribute`,`opentag`,`closetag`,`cdata`,`error`,`end`,`ready`];var lt={xmldecl:`xmldeclHandler`,text:`textHandler`,processinginstruction:`piHandler`,doctype:`doctypeHandler`,comment:`commentHandler`,opentagstart:`openTagStartHandler`,attribute:`attributeHandler`,opentag:`openTagHandler`,closetag:`closeTagHandler`,cdata:`cdataHandler`,error:`errorHandler`,end:`endHandler`,ready:`readyHandler`};e.SaxesParser=class{constructor(e){this.opt=e??{},this.fragmentOpt=!!this.opt.fragment;let t=this.xmlnsOpt=!!this.opt.xmlns;if(this.trackPosition=this.opt.position!==!1,this.fileName=this.opt.fileName,t){this.nameStartCheck=d,this.nameCheck=f,this.isName=at,this.processAttribs=this.processAttribsNS,this.pushAttrib=this.pushAttribNS,this.ns=Object.assign({__proto__:null},g);let e=this.opt.additionalNamespaces;e!=null&&(it(this,e),Object.assign(this.ns,e))}else this.nameStartCheck=o,this.nameCheck=s,this.isName=ot,this.processAttribs=this.processAttribsPlain,this.pushAttrib=this.pushAttribPlain;this.stateTable=[this.sBegin,this.sBeginWhitespace,this.sDoctype,this.sDoctypeQuote,this.sDTD,this.sDTDQuoted,this.sDTDOpenWaka,this.sDTDOpenWakaBang,this.sDTDComment,this.sDTDCommentEnding,this.sDTDCommentEnded,this.sDTDPI,this.sDTDPIEnding,this.sText,this.sEntity,this.sOpenWaka,this.sOpenWakaBang,this.sComment,this.sCommentEnding,this.sCommentEnded,this.sCData,this.sCDataEnding,this.sCDataEnding2,this.sPIFirstChar,this.sPIRest,this.sPIBody,this.sPIEnding,this.sXMLDeclNameStart,this.sXMLDeclName,this.sXMLDeclEq,this.sXMLDeclValueStart,this.sXMLDeclValue,this.sXMLDeclSeparator,this.sXMLDeclEnding,this.sOpenTag,this.sOpenTagSlash,this.sAttrib,this.sAttribName,this.sAttribNameSawWhite,this.sAttribValue,this.sAttribValueQuoted,this.sAttribValueClosed,this.sAttribValueUnquoted,this.sCloseTag,this.sCloseTagSawWhite],this._init()}get closed(){return this._closed}_init(){var e;this.openWakaBang=``,this.text=``,this.name=``,this.piTarget=``,this.entity=``,this.q=null,this.tags=[],this.tag=null,this.topNS=null,this.chunk=``,this.chunkPosition=0,this.i=0,this.prevI=0,this.carriedFromPrevious=void 0,this.forbiddenState=N,this.attribList=[];let{fragmentOpt:t}=this;this.state=t?C:ee,this.reportedTextBeforeRoot=this.reportedTextAfterRoot=this.closedRoot=this.sawRoot=t,this.xmlDeclPossible=!t,this.xmlDeclExpects=[`version`],this.entityReturnState=void 0;let{defaultXMLVersion:n}=this.opt;if(n===void 0){if(this.opt.forceXMLVersion===!0)throw Error(`forceXMLVersion set but defaultXMLVersion is not set`);n=`1.0`}this.setXMLVersion(n),this.positionAtNewLine=0,this.doctype=!1,this._closed=!1,this.xmlDecl={version:void 0,encoding:void 0,standalone:void 0},this.line=1,this.column=0,this.ENTITIES=Object.create(_),(e=this.readyHandler)==null||e.call(this)}get position(){return this.chunkPosition+this.i}get columnIndex(){return this.position-this.positionAtNewLine}on(e,t){this[lt[e]]=t}off(e){this[lt[e]]=void 0}makeError(e){let t=this.fileName??``;return this.trackPosition&&(t.length>0&&(t+=`:`),t+=`${this.line}:${this.column}`),t.length>0&&(t+=`: `),Error(t+e)}fail(e){let t=this.makeError(e),n=this.errorHandler;if(n===void 0)throw t;return n(t),this}write(e){if(this.closed)return this.fail(`cannot write after close; assign an onready handler.`);let t=!1;e===null?(t=!0,e=``):typeof e==`object`&&(e=e.toString()),this.carriedFromPrevious!==void 0&&(e=`${this.carriedFromPrevious}${e}`,this.carriedFromPrevious=void 0);let n=e.length,r=e.charCodeAt(n-1);!t&&(r===Be||r>=55296&&r<=56319)&&(this.carriedFromPrevious=e[n-1],n--,e=e.slice(0,n));let{stateTable:i}=this;for(this.chunk=e,this.i=0;this.i<n;)i[this.state].call(this);return this.chunkPosition+=n,t?this.end():this}close(){return this.write(null)}getCode10(){let{chunk:e,i:t}=this;if(this.prevI=t,this.i=t+1,t>=e.length)return v;let n=e.charCodeAt(t);if(this.column++,n<55296){if(n>=Ve||n===Re)return n;switch(n){case ze:return this.line++,this.column=0,this.positionAtNewLine=this.position,ze;case Be:return e.charCodeAt(t+1)===ze&&(this.i=t+2),this.line++,this.column=0,this.positionAtNewLine=this.position,y;default:return this.fail(`disallowed character.`),n}}if(n>56319)return n>=57344&&n<=65533||this.fail(`disallowed character.`),n;let r=65536+(n-55296)*1024+(e.charCodeAt(t+1)-56320);return this.i=t+2,r>1114111&&this.fail(`disallowed character.`),r}getCode11(){let{chunk:e,i:t}=this;if(this.prevI=t,this.i=t+1,t>=e.length)return v;let n=e.charCodeAt(t);if(this.column++,n<55296){if(n>31&&n<127||n>159&&n!==Ze||n===Re)return n;switch(n){case ze:return this.line++,this.column=0,this.positionAtNewLine=this.position,ze;case Be:{let n=e.charCodeAt(t+1);(n===ze||n===j)&&(this.i=t+2)}case j:case Ze:return this.line++,this.column=0,this.positionAtNewLine=this.position,y;default:return this.fail(`disallowed character.`),n}}if(n>56319)return n>=57344&&n<=65533||this.fail(`disallowed character.`),n;let r=65536+(n-55296)*1024+(e.charCodeAt(t+1)-56320);return this.i=t+2,r>1114111&&this.fail(`disallowed character.`),r}getCodeNorm(){let e=this.getCode();return e===y?ze:e}unget(){this.i=this.prevI,this.column--}captureTo(e){let{i:t}=this,{chunk:n}=this;for(;;){let r=this.getCode(),i=r===y,a=i?ze:r;if(a===v||e.includes(a))return this.text+=n.slice(t,this.prevI),a;i&&(this.text+=`${n.slice(t,this.prevI)}\n`,t=this.i)}}captureToChar(e){let{i:t}=this,{chunk:n}=this;for(;;){let r=this.getCode();switch(r){case y:this.text+=`${n.slice(t,this.prevI)}\n`,t=this.i,r=ze;break;case v:return this.text+=n.slice(t),!1}if(r===e)return this.text+=n.slice(t,this.prevI),!0}}captureNameChars(){let{chunk:e,i:t}=this;for(;;){let n=this.getCode();if(n===v)return this.name+=e.slice(t),v;if(!s(n))return this.name+=e.slice(t,this.prevI),n===y?ze:n}}skipSpaces(){for(;;){let e=this.getCodeNorm();if(e===v||!i(e))return e}}setXMLVersion(e){this.currentXMLVersion=e,e===`1.0`?(this.isChar=a,this.getCode=this.getCode10):(this.isChar=u,this.getCode=this.getCode11)}sBegin(){this.chunk.charCodeAt(0)===65279&&(this.i++,this.column++),this.state=te}sBeginWhitespace(){let e=this.i,t=this.skipSpaces();switch(this.prevI!==e&&(this.xmlDeclPossible=!1),t){case qe:if(this.state=ue,this.text.length!==0)throw Error(`no-empty text at start`);break;case v:break;default:this.unget(),this.state=C,this.xmlDeclPossible=!1}}sDoctype(){var e;let t=this.captureTo(et);switch(t){case k:(e=this.doctypeHandler)==null||e.call(this,this.text),this.text=``,this.state=C,this.doctype=!0;break;case v:break;default:this.text+=String.fromCodePoint(t),t===Ye?this.state=b:Qe(t)&&(this.state=re,this.q=t)}}sDoctypeQuote(){let e=this.q;this.captureToChar(e)&&(this.text+=String.fromCodePoint(e),this.q=null,this.state=ne)}sDTD(){let e=this.captureTo(M);e!==v&&(this.text+=String.fromCodePoint(e),e===Xe?this.state=ne:e===qe?this.state=ae:Qe(e)&&(this.state=ie,this.q=e))}sDTDQuoted(){let e=this.q;this.captureToChar(e)&&(this.text+=String.fromCodePoint(e),this.state=b,this.q=null)}sDTDOpenWaka(){let e=this.getCodeNorm();switch(this.text+=String.fromCodePoint(e),e){case He:this.state=x,this.openWakaBang=``;break;case A:this.state=ce;break;default:this.state=b}}sDTDOpenWakaBang(){let e=String.fromCodePoint(this.getCodeNorm()),t=this.openWakaBang+=e;this.text+=e,t!==`-`&&(this.state=t===`--`?oe:b,this.openWakaBang=``)}sDTDComment(){this.captureToChar(O)&&(this.text+=`-`,this.state=S)}sDTDCommentEnding(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),this.state=e===O?se:oe}sDTDCommentEnded(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),e===k?this.state=b:(this.fail(`malformed comment.`),this.state=oe)}sDTDPI(){this.captureToChar(A)&&(this.text+=`?`,this.state=le)}sDTDPIEnding(){let e=this.getCodeNorm();this.text+=String.fromCodePoint(e),e===k&&(this.state=b)}sText(){this.tags.length===0?this.handleTextOutsideRoot():this.handleTextInRoot()}sEntity(){let{i:e}=this,{chunk:t}=this;loop:for(;;)switch(this.getCode()){case y:this.entity+=`${t.slice(e,this.prevI)}\n`,e=this.i;break;case Ke:{let{entityReturnState:n}=this,r=this.entity+t.slice(e,this.prevI);this.state=n;let i;r===``?(this.fail(`empty entity name.`),i=`&;`):(i=this.parseEntity(r),this.entity=``),(n!==C||this.textHandler!==void 0)&&(this.text+=i);break loop}case v:this.entity+=t.slice(e);break loop}}sOpenWaka(){let e=this.getCode();if(o(e))this.state=De,this.unget(),this.xmlDeclPossible=!1;else switch(e){case Ge:this.state=Ie,this.xmlDeclPossible=!1;break;case He:this.state=de,this.openWakaBang=``,this.xmlDeclPossible=!1;break;case A:this.state=_e;break;default:this.fail(`disallowed character in tag name`),this.state=C,this.xmlDeclPossible=!1}}sOpenWakaBang(){switch(this.openWakaBang+=String.fromCodePoint(this.getCodeNorm()),this.openWakaBang){case`[CDATA[`:!this.sawRoot&&!this.reportedTextBeforeRoot&&(this.fail(`text data outside of root node.`),this.reportedTextBeforeRoot=!0),this.closedRoot&&!this.reportedTextAfterRoot&&(this.fail(`text data outside of root node.`),this.reportedTextAfterRoot=!0),this.state=he,this.openWakaBang=``;break;case`--`:this.state=fe,this.openWakaBang=``;break;case`DOCTYPE`:this.state=ne,(this.doctype||this.sawRoot)&&this.fail(`inappropriately located doctype declaration.`),this.openWakaBang=``;break;default:this.openWakaBang.length>=7&&this.fail(`incorrect syntax.`)}}sComment(){this.captureToChar(O)&&(this.state=pe)}sCommentEnding(){var e;let t=this.getCodeNorm();t===O?(this.state=me,(e=this.commentHandler)==null||e.call(this,this.text),this.text=``):(this.text+=`-${String.fromCodePoint(t)}`,this.state=fe)}sCommentEnded(){let e=this.getCodeNorm();e===k?this.state=C:(this.fail(`malformed comment.`),this.text+=`--${String.fromCodePoint(e)}`,this.state=fe)}sCData(){this.captureToChar(Xe)&&(this.state=T)}sCDataEnding(){let e=this.getCodeNorm();e===Xe?this.state=ge:(this.text+=`]${String.fromCodePoint(e)}`,this.state=he)}sCDataEnding2(){var e;let t=this.getCodeNorm();switch(t){case k:(e=this.cdataHandler)==null||e.call(this,this.text),this.text=``,this.state=C;break;case Xe:this.text+=`]`;break;default:this.text+=`]]${String.fromCodePoint(t)}`,this.state=he}}sPIFirstChar(){let e=this.getCodeNorm();this.nameStartCheck(e)?(this.piTarget+=String.fromCodePoint(e),this.state=E):e===A||i(e)?(this.fail(`processing instruction without a target.`),this.state=e===A?ye:ve):(this.fail(`disallowed character in processing instruction name.`),this.piTarget+=String.fromCodePoint(e),this.state=E)}sPIRest(){let{chunk:e,i:t}=this;for(;;){let n=this.getCodeNorm();if(n===v){this.piTarget+=e.slice(t);return}if(!this.nameCheck(n)){this.piTarget+=e.slice(t,this.prevI);let r=n===A;r||i(n)?this.piTarget===`xml`?(this.xmlDeclPossible||this.fail(`an XML declaration must be at the start of the document.`),this.state=r?Ee:be):this.state=r?ye:ve:(this.fail(`disallowed character in processing instruction name.`),this.piTarget+=String.fromCodePoint(n));break}}}sPIBody(){if(this.text.length===0){let e=this.getCodeNorm();e===A?this.state=ye:i(e)||(this.text=String.fromCodePoint(e))}else this.captureToChar(A)&&(this.state=ye)}sPIEnding(){var e;let t=this.getCodeNorm();if(t===k){let{piTarget:t}=this;t.toLowerCase()===`xml`&&this.fail(`the XML declaration must appear at the start of the document.`),(e=this.piHandler)==null||e.call(this,{target:t,body:this.text}),this.piTarget=this.text=``,this.state=C}else t===A?this.text+=`?`:(this.text+=`?${String.fromCodePoint(t)}`,this.state=ve);this.xmlDeclPossible=!1}sXMLDeclNameStart(){let e=this.skipSpaces();if(e===A){this.state=Ee;return}e!==v&&(this.state=xe,this.name=String.fromCodePoint(e))}sXMLDeclName(){let e=this.captureTo(tt);if(e===A){this.state=Ee,this.name+=this.text,this.text=``,this.fail(`XML declaration is incomplete.`);return}if(i(e)||e===Je){if(this.name+=this.text,this.text=``,!this.xmlDeclExpects.includes(this.name))switch(this.name.length){case 0:this.fail(`did not expect any more name/value pairs.`);break;case 1:this.fail(`expected the name ${this.xmlDeclExpects[0]}.`);break;default:this.fail(`expected one of ${this.xmlDeclExpects.join(`, `)}`)}this.state=e===Je?Ce:Se}}sXMLDeclEq(){let e=this.getCodeNorm();if(e===A){this.state=Ee,this.fail(`XML declaration is incomplete.`);return}i(e)||(e!==Je&&this.fail(`value required.`),this.state=Ce)}sXMLDeclValueStart(){let e=this.getCodeNorm();if(e===A){this.state=Ee,this.fail(`XML declaration is incomplete.`);return}i(e)||(Qe(e)?this.q=e:(this.fail(`value must be quoted.`),this.q=Ve),this.state=we)}sXMLDeclValue(){let e=this.captureTo([this.q,A]);if(e===A){this.state=Ee,this.text=``,this.fail(`XML declaration is incomplete.`);return}if(e===v)return;let t=this.text;switch(this.text=``,this.name){case`version`:{this.xmlDeclExpects=[`encoding`,`standalone`];let e=t;this.xmlDecl.version=e,/^1\.[0-9]+$/.test(e)?this.opt.forceXMLVersion||this.setXMLVersion(e):this.fail(`version number must match /^1\\.[0-9]+$/.`);break}case`encoding`:/^[A-Za-z][A-Za-z0-9._-]*$/.test(t)||this.fail(`encoding value must match /^[A-Za-z0-9][A-Za-z0-9._-]*$/.`),this.xmlDeclExpects=[`standalone`],this.xmlDecl.encoding=t;break;case`standalone`:t!==`yes`&&t!==`no`&&this.fail(`standalone value must match "yes" or "no".`),this.xmlDeclExpects=[],this.xmlDecl.standalone=t}this.name=``,this.state=Te}sXMLDeclSeparator(){let e=this.getCodeNorm();if(e===A){this.state=Ee;return}i(e)||(this.fail(`whitespace required.`),this.unget()),this.state=be}sXMLDeclEnding(){var e;this.getCodeNorm()===k?(this.piTarget===`xml`?this.name!==`version`&&this.xmlDeclExpects.includes(`version`)&&this.fail(`XML declaration must contain a version.`):this.fail(`processing instructions are not allowed before root.`),(e=this.xmldeclHandler)==null||e.call(this,this.xmlDecl),this.name=``,this.piTarget=this.text=``,this.state=C):this.fail(`The character ? is disallowed anywhere in XML declarations.`),this.xmlDeclPossible=!1}sOpenTag(){var e;let t=this.captureNameChars();if(t===v)return;let n=this.tag={name:this.name,attributes:Object.create(null)};switch(this.name=``,this.xmlnsOpt&&(this.topNS=n.ns=Object.create(null)),(e=this.openTagStartHandler)==null||e.call(this,n),this.sawRoot=!0,!this.fragmentOpt&&this.closedRoot&&this.fail(`documents may contain only one root.`),t){case k:this.openTag();break;case Ge:this.state=Oe;break;default:i(t)||this.fail(`disallowed character in tag name.`),this.state=ke}}sOpenTagSlash(){this.getCode()===k?this.openSelfClosingTag():(this.fail(`forward-slash in opening tag not followed by >.`),this.state=ke)}sAttrib(){let e=this.skipSpaces();e!==v&&(o(e)?(this.unget(),this.state=Ae):e===k?this.openTag():e===Ge?this.state=Oe:this.fail(`disallowed character in attribute name.`))}sAttribName(){let e=this.captureNameChars();e===Je?this.state=Me:i(e)?this.state=je:e===k?(this.fail(`attribute without value.`),this.pushAttrib(this.name,this.name),this.name=this.text=``,this.openTag()):e!==v&&this.fail(`disallowed character in attribute name.`)}sAttribNameSawWhite(){let e=this.skipSpaces();switch(e){case v:return;case Je:this.state=Me;break;default:this.fail(`attribute without value.`),this.text=``,this.name=``,e===k?this.openTag():o(e)?(this.unget(),this.state=Ae):(this.fail(`disallowed character in attribute name.`),this.state=ke)}}sAttribValue(){let e=this.getCodeNorm();Qe(e)?(this.q=e,this.state=Ne):i(e)||(this.fail(`unquoted attribute value.`),this.state=Fe,this.unget())}sAttribValueQuoted(){let{q:e,chunk:t}=this,{i:n}=this;for(;;)switch(this.getCode()){case e:this.pushAttrib(this.name,this.text+t.slice(n,this.prevI)),this.name=this.text=``,this.q=null,this.state=Pe;return;case We:this.text+=t.slice(n,this.prevI),this.state=w,this.entityReturnState=Ne;return;case ze:case y:case Re:this.text+=`${t.slice(n,this.prevI)} `,n=this.i;break;case qe:this.text+=t.slice(n,this.prevI),this.fail(`disallowed character.`);return;case v:this.text+=t.slice(n);return}}sAttribValueClosed(){let e=this.getCodeNorm();i(e)?this.state=ke:e===k?this.openTag():e===Ge?this.state=Oe:o(e)?(this.fail(`no whitespace between attributes.`),this.unget(),this.state=Ae):this.fail(`disallowed character in attribute name.`)}sAttribValueUnquoted(){let e=this.captureTo(nt);switch(e){case We:this.state=w,this.entityReturnState=Fe;break;case qe:this.fail(`disallowed character.`);break;case v:break;default:this.text.includes(`]]>`)&&this.fail(`the string "]]>" is disallowed in char data.`),this.pushAttrib(this.name,this.text),this.name=this.text=``,e===k?this.openTag():this.state=ke}}sCloseTag(){let e=this.captureNameChars();e===k?this.closeTag():i(e)?this.state=Le:e!==v&&this.fail(`disallowed character in closing tag.`)}sCloseTagSawWhite(){switch(this.skipSpaces()){case k:this.closeTag();break;case v:break;default:this.fail(`disallowed character in closing tag.`)}}handleTextInRoot(){let{i:e,forbiddenState:t}=this,{chunk:n,textHandler:r}=this;scanLoop:for(;;)switch(this.getCode()){case qe:if(this.state=ue,r!==void 0){let{text:t}=this,i=n.slice(e,this.prevI);t.length===0?i.length!==0&&r(i):(r(t+i),this.text=``)}t=N;break scanLoop;case We:this.state=w,this.entityReturnState=C,r!==void 0&&(this.text+=n.slice(e,this.prevI)),t=N;break scanLoop;case Xe:switch(t){case N:t=st;break;case st:t=ct;break;case ct:break;default:throw Error(`impossible state`)}break;case k:t===ct&&this.fail(`the string "]]>" is disallowed in char data.`),t=N;break;case y:r!==void 0&&(this.text+=`${n.slice(e,this.prevI)}\n`),e=this.i,t=N;break;case v:r!==void 0&&(this.text+=n.slice(e));break scanLoop;default:t=N}this.forbiddenState=t}handleTextOutsideRoot(){let{i:e}=this,{chunk:t,textHandler:n}=this,r=!1;outRootLoop:for(;;){let a=this.getCode();switch(a){case qe:if(this.state=ue,n!==void 0){let{text:r}=this,i=t.slice(e,this.prevI);r.length===0?i.length!==0&&n(i):(n(r+i),this.text=``)}break outRootLoop;case We:this.state=w,this.entityReturnState=C,n!==void 0&&(this.text+=t.slice(e,this.prevI)),r=!0;break outRootLoop;case y:n!==void 0&&(this.text+=`${t.slice(e,this.prevI)}\n`),e=this.i;break;case v:n!==void 0&&(this.text+=t.slice(e));break outRootLoop;default:i(a)||(r=!0)}}r&&(!this.sawRoot&&!this.reportedTextBeforeRoot&&(this.fail(`text data outside of root node.`),this.reportedTextBeforeRoot=!0),this.closedRoot&&!this.reportedTextAfterRoot&&(this.fail(`text data outside of root node.`),this.reportedTextAfterRoot=!0))}pushAttribNS(e,t){var n;let{prefix:r,local:i}=this.qname(e),a={name:e,prefix:r,local:i,value:t};if(this.attribList.push(a),(n=this.attributeHandler)==null||n.call(this,a),r===`xmlns`){let e=t.trim();this.currentXMLVersion===`1.0`&&e===``&&this.fail(`invalid attempt to undefine prefix in XML 1.0`),this.topNS[i]=e,rt(this,i,e)}else if(e===`xmlns`){let e=t.trim();this.topNS[``]=e,rt(this,``,e)}}pushAttribPlain(e,t){var n;let r={name:e,value:t};this.attribList.push(r),(n=this.attributeHandler)==null||n.call(this,r)}end(){var e,t;this.sawRoot||this.fail(`document must contain a root element.`);let{tags:n}=this;for(;n.length>0;){let e=n.pop();this.fail(`unclosed tag: ${e.name}`)}this.state!==ee&&this.state!==C&&this.fail(`unexpected end.`);let{text:r}=this;return r.length!==0&&((e=this.textHandler)==null||e.call(this,r),this.text=``),this._closed=!0,(t=this.endHandler)==null||t.call(this),this._init(),this}resolve(e){var t;let n=this.topNS[e];if(n!==void 0)return n;let{tags:r}=this;for(let t=r.length-1;t>=0;t--)if(n=r[t].ns[e],n!==void 0)return n;return n=this.ns[e],n===void 0?(t=this.opt).resolvePrefix?.call(t,e):n}qname(e){let t=e.indexOf(`:`);if(t===-1)return{prefix:``,local:e};let n=e.slice(t+1),r=e.slice(0,t);return(r===``||n===``||n.includes(`:`))&&this.fail(`malformed name: ${e}.`),{prefix:r,local:n}}processAttribsNS(){let{attribList:e}=this,t=this.tag;{let{prefix:e,local:n}=this.qname(t.name);t.prefix=e,t.local=n;let r=t.uri=this.resolve(e)??``;e!==``&&(e===`xmlns`&&this.fail(`tags may not have "xmlns" as prefix.`),r===``&&(this.fail(`unbound namespace prefix: ${JSON.stringify(e)}.`),t.uri=e))}if(e.length===0)return;let{attributes:n}=t,r=new Set;for(let t of e){let{name:e,prefix:i,local:a}=t,o,s;i===``?(o=e===`xmlns`?h:``,s=e):(o=this.resolve(i),o===void 0&&(this.fail(`unbound namespace prefix: ${JSON.stringify(i)}.`),o=i),s=`{${o}}${a}`),r.has(s)&&this.fail(`duplicate attribute: ${s}.`),r.add(s),t.uri=o,n[e]=t}this.attribList=[]}processAttribsPlain(){let{attribList:e}=this,t=this.tag.attributes;for(let{name:n,value:r}of e)t[n]!==void 0&&this.fail(`duplicate attribute: ${n}.`),t[n]=r;this.attribList=[]}openTag(){var e;this.processAttribs();let{tags:t}=this,n=this.tag;n.isSelfClosing=!1,(e=this.openTagHandler)==null||e.call(this,n),t.push(n),this.state=C,this.name=``}openSelfClosingTag(){var e,t;this.processAttribs();let{tags:n}=this,r=this.tag;r.isSelfClosing=!0,(e=this.openTagHandler)==null||e.call(this,r),(t=this.closeTagHandler)==null||t.call(this,r),(this.tag=n[n.length-1]??null)===null&&(this.closedRoot=!0),this.state=C,this.name=``}closeTag(){let{tags:e,name:t}=this;if(this.state=C,this.name=``,t===``){this.fail(`weird empty close tag.`),this.text+=`</>`;return}let n=this.closeTagHandler,r=e.length;for(;r-->0;){let r=this.tag=e.pop();if(this.topNS=r.ns,n?.(r),r.name===t)break;this.fail(`unexpected close tag.`)}r===0?this.closedRoot=!0:r<0&&(this.fail(`unmatched closing tag: ${t}.`),this.text+=`</${t}>`)}parseEntity(e){if(e[0]!==`#`){let t=this.ENTITIES[e];return t===void 0?(this.fail(this.isName(e)?`undefined entity.`:`disallowed character in entity name.`),`&${e};`):t}let t=NaN;return e[1]===`x`&&/^#x[0-9a-f]+$/i.test(e)?t=parseInt(e.slice(2),16):/^#[0-9]+$/.test(e)&&(t=parseInt(e.slice(1),10)),this.isChar(t)?String.fromCodePoint(t):(this.fail(`malformed character entity.`),`&${e};`)}}}))(),uw=4194304,dw=new Set([`script`,`iframe`,`object`,`embed`,`audio`,`video`]),fw=new Set([`foreignobject`,`div`,`span`,`p`,`br`,`b`,`strong`,`i`,`em`,`small`,`sub`,`sup`,`code`,`ul`,`ol`,`li`,`a`]),pw=/^data:image\/(?:png|jpeg|gif|webp);base64,[a-z0-9+/=\s]+$/i,mw=/^data:(?:font\/(?:woff2?|opentype|truetype)|application\/(?:x-)?font-woff2?);base64,[a-z0-9+/=\s]+$/i,hw=class extends Error{constructor(e){super(e),this.name=`ClientSvgError`}};function gw(e){let t=e.trim();return t.startsWith(`#`)||pw.test(t)||mw.test(t)}function _w(e){if(/@import|expression\s*\(|javascript\s*:|data\s*:\s*text\/html|behavior\s*:|-moz-binding/i.test(e))return!0;let t=/url\s*\(\s*(['"]?)(.*?)\1\s*\)/gi;for(let n of e.matchAll(t))if(!gw(n[2]??``))return!0;return/url\s*\(/i.test(e.replace(t,``))}function vw(e){let t=e.trim();return t.startsWith(`#`)||pw.test(t)}function yw(e,t){let n=e.toLowerCase();return n.startsWith(`on`)?!1:n===`href`||n===`xlink:href`||n===`src`?vw(t):[`style`,`filter`,`fill`,`stroke`,`clip-path`,`mask`].includes(n)?!_w(t):n!==`xml:base`&&!/javascript\s*:/i.test(t)}function bw(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`)}function xw(e){return bw(e).replaceAll(`"`,`&quot;`)}function Sw(e){if(e.type===`text`)return bw(e.value);let t=[...e.attributes].map(([e,t])=>` ${e}="${xw(t)}"`).join(``);return`<${e.name}${t}>${e.children.map(Sw).join(``)}</${e.name}>`}function Cw(e){return e.name.toLowerCase().split(`:`).at(-1)??e.name.toLowerCase()}function ww(e){if(e===void 0||!/^-?\d+(?:\.\d+)?(?:px)?$/.test(e.trim()))return null;let t=Number.parseFloat(e);return Number.isFinite(t)&&t>0?t:null}function Tw(e){let t=e.attributes.get(`viewBox`)?.trim().split(/[\s,]+/).map(Number);if(t?.length===4&&t.every(Number.isFinite)&&t[2]>0&&t[3]>0)return t;let n=ww(e.attributes.get(`width`)),r=ww(e.attributes.get(`height`));return n!==null&&r!==null?[0,0,n,r]:null}function Ew(e,t){let n=e.attributes.get(`style`);if(!n)return null;for(let e of n.split(`;`)){let n=e.indexOf(`:`);if(n>=0&&e.slice(0,n).trim().toLowerCase()===t)return e.slice(n+1).trim()}return null}function Dw(e){let t=(e.attributes.get(`fill`)??Ew(e,`fill`)??``).replaceAll(` `,``).toLowerCase();return t===`white`||t===`#fff`||t===`#ffffff`||t===`rgb(255,255,255)`}function Ow(e){if(e===void 0||!/^-?\d+(?:\.\d+)?$/.test(e.trim()))return null;let t=Number(e);return Number.isFinite(t)?t:null}function kw(e,t){let n=e.attributes.get(`width`)?.trim(),r=e.attributes.get(`height`)?.trim();if(n===`100%`&&r===`100%`)return!0;let i=Ow(e.attributes.get(`x`)??`0`),a=Ow(e.attributes.get(`y`)??`0`),o=Ow(n),s=Ow(r);if([i,a,o,s].some(e=>e===null))return!1;let[c,l,u,d]=t,f=.01;return i<=c+f&&a<=l+f&&i+o>=c+u-f&&a+s>=l+d-f}function Aw(e,t,n){let r=Cw(e),i=new Set((e.attributes.get(`class`)??``).toLowerCase().split(/\s+/));return r===`rect`&&i.has(`backdrop`)||r===`rect`&&t!==null&&Dw(e)&&kw(e,t)?!0:n===`graphviz`&&r===`polygon`&&Dw(e)&&(e.attributes.get(`stroke`)??``).toLowerCase()===`none`}function jw(e,t,n){let r=Cw(e)===`svg`?Tw(e)??t:t;e.children=e.children.filter(e=>e.type===`text`||!Aw(e,r,n)&&(jw(e,r,n),!0))}function Mw(e,t){let n=(e.attributes.get(`style`)??``).split(`;`).map(e=>e.trim()).filter(Boolean).filter(e=>!/^background(?:-color)?\s*:/i.test(e));n.push(`background-color:${t}`),e.attributes.set(`style`,`${n.join(`;`)};`)}function Nw(e,t=[],n=[]){return{type:`element`,name:e,attributes:new Map(t),children:n}}function Pw(e,t,n,r){let i=[],a=null;t.title&&i.push(Nw(`title`,[],[{type:`text`,value:t.title}])),t.description&&i.push(Nw(`desc`,[],[{type:`text`,value:t.description}]));let o=Tw(e);if((n.padding||n.background||n.frame)&&o===null)throw new hw(`Renderer output has no usable SVG dimensions for presentation settings.`);if(o!==null){let[t,r,s,c]=o,l=n.padding,u=[t-l,r-l,s+l*2,c+l*2];e.attributes.set(`viewBox`,u.join(` `)),e.attributes.has(`width`)&&e.attributes.set(`width`,String(u[2])),e.attributes.has(`height`)&&e.attributes.set(`height`,String(u[3])),n.background&&i.push(Nw(`rect`,[[`x`,String(u[0])],[`y`,String(u[1])],[`width`,String(u[2])],[`height`,String(u[3])],[`fill`,n.background]])),n.frame&&(a=Nw(`rect`,[[`x`,String(u[0]+.5)],[`y`,String(u[1]+.5)],[`width`,String(Math.max(0,u[2]-1))],[`height`,String(Math.max(0,u[3]-1))],[`fill`,`none`],[`stroke`,`#000000`],[`stroke-width`,`1`],[`vector-effect`,`non-scaling-stroke`]]))}n.background&&(jw(e,o,r),Mw(e,n.background)),e.children.unshift(...i),a&&e.children.push(a)}function Fw(e,t,n,r){if(e.length>uw)throw new hw(`Rendered SVG is too large.`);let i=null,a=[],o=0,s=null,c=new lw.SaxesParser({xmlns:!0});c.on(`doctype`,e=>{e.includes(`[`)&&(s=Error(`Internal DOCTYPE subsets are not allowed`))}),c.on(`opentag`,e=>{let t=e.local.toLowerCase(),n=t===`foreignobject`||a.some(e=>Cw(e)===`foreignobject`);if(o>0||dw.has(t)||n&&!fw.has(t)){o++;return}let r=Nw(e.name);for(let t of Object.values(e.attributes))yw(t.name,t.value)&&r.attributes.set(t.name,t.value);let c=a.at(-1);c?c.children.push(r):i===null?i=r:s=Error(`Multiple root elements`),a.push(r)});let l=e=>{if(o>0||e===``)return;let t=a.at(-1);if(t){if(Cw(t)===`style`&&_w(e))throw new hw(`Renderer output contains unsafe CSS.`);t.children.push({type:`text`,value:e})}else e.trim()!==``&&(s=Error(`Text outside root element`))};c.on(`text`,l),c.on(`cdata`,l),c.on(`closetag`,()=>{o>0?o--:a.pop()}),c.on(`error`,e=>{s=e});try{c.write(e).close()}catch(e){if(e instanceof hw)throw e;s=e}if(s!==null||i===null||Cw(i)!==`svg`)throw new hw(`Renderer returned invalid SVG.`);return Pw(i,t,n,r),Sw(i)}var Iw=Object.freeze({plantuml:`https://plantuml.render.diagram.zip/v1/svg`,graphviz:`https://graphviz.render.diagram.zip/v1/svg`,d2:`https://d2.render.diagram.zip/v1/svg`,c4plantuml:`https://c4plantuml.render.diagram.zip/v1/svg`,blockdiag:`https://blockdiag.render.diagram.zip/v1/svg`,seqdiag:`https://seqdiag.render.diagram.zip/v1/svg`,actdiag:`https://actdiag.render.diagram.zip/v1/svg`,nwdiag:`https://nwdiag.render.diagram.zip/v1/svg`,packetdiag:`https://packetdiag.render.diagram.zip/v1/svg`,rackdiag:`https://rackdiag.render.diagram.zip/v1/svg`,bytefield:`https://bytefield.render.diagram.zip/v1/svg`,dbml:`https://dbml.render.diagram.zip/v1/svg`,diagramsnet:`https://diagramsnet.render.diagram.zip/v1/svg`,ditaa:`https://ditaa.render.diagram.zip/v1/svg`,erd:`https://erd.render.diagram.zip/v1/svg`,goat:`https://goat.render.diagram.zip/v1/svg`,nomnoml:`https://nomnoml.render.diagram.zip/v1/svg`,pikchr:`https://pikchr.render.diagram.zip/v1/svg`,structurizr:`https://structurizr.render.diagram.zip/v1/svg`,svgbob:`https://svgbob.render.diagram.zip/v1/svg`,symbolator:`https://symbolator.render.diagram.zip/v1/svg`,tikz:`https://tikz.render.diagram.zip/v1/svg`,umlet:`https://umlet.render.diagram.zip/v1/svg`,vega:`https://vega.render.diagram.zip/v1/svg`,vegalite:`https://vegalite.render.diagram.zip/v1/svg`,wavedrom:`https://wavedrom.render.diagram.zip/v1/svg`,wireviz:`https://wireviz.render.diagram.zip/v1/svg`}),Lw=Object.freeze([`mermaid`,`bpmn`,`excalidraw`,`bytefield`,`nomnoml`,`vega`,`vegalite`,`wavedrom`,`blockdiag`,`seqdiag`,`actdiag`,`nwdiag`,`packetdiag`,`rackdiag`,`graphviz`,`erd`,`pikchr`,`wireviz`]);function Rw(e){return Lw.includes(e)}function zw(e){return Iw[e]??null}function Bw(e,t,n){return Math.min(Math.max(e,t),n)}var Vw=class{constructor({stage:e,image:t,status:n,minimap:r,minimapImage:i,minimapViewport:a}){this.stage=e,this.image=t,this.status=n,this.minimap=r,this.minimapImage=i,this.minimapViewport=a,this.scale=1,this.x=0,this.y=0,this.objectUrl=null,this.abortController=null,this.requestNumber=0,this.pendingRender=null,this.renderLoop=null,this.latestRenderKey=null,this.latestSvgBlob=null,this.latestRendererIdentity=null,this.imageFallbackUrl=null,this.activeImageUrl=null,this.drag=null,this.image.addEventListener(`load`,()=>{this.image.src===this.activeImageUrl&&(this.imageFallbackUrl=null,this.setStatus(`Rendered`,`ready`),this.fit())}),this.image.addEventListener(`error`,()=>this.retryBlockedImage()),this.stage.addEventListener(`pointerdown`,e=>this.startPan(e)),this.stage.addEventListener(`pointermove`,e=>this.pan(e)),this.stage.addEventListener(`pointerup`,e=>this.endPan(e)),this.stage.addEventListener(`pointercancel`,e=>this.endPan(e)),this.stage.addEventListener(`wheel`,e=>this.wheelZoom(e),{passive:!1}),this.minimap.addEventListener(`pointerdown`,e=>this.moveFromMinimap(e)),new ResizeObserver(()=>this.updateTransform()).observe(this.stage)}render({type:e,source:t,options:n={},meta:r={},presentation:i={}}){if(!t.trim()){this.requestNumber++,this.pendingRender=null,this.abortController?.abort(),this.setStatus(`Write something to render.`,`idle`);return}let a=JSON.stringify({type:e,source:t,options:n,meta:r,presentation:i});return this.latestRenderKey===a&&this.latestSvgBlob?Promise.resolve():(this.pendingRender={type:e,source:t,options:n,meta:r,presentation:i,renderKey:a,requestNumber:++this.requestNumber},this.abortController?.abort(),this.renderLoop||=this.drainRenderQueue(),this.renderLoop)}async drainRenderQueue(){try{for(;this.pendingRender;){let e=this.pendingRender;this.pendingRender=null,await this.performRender(e)}}finally{this.renderLoop=null,this.pendingRender&&(this.renderLoop=this.drainRenderQueue())}}async performRender({type:e,source:t,options:n,meta:r,presentation:i,renderKey:a,requestNumber:o}){let s=new AbortController;this.abortController=s,this.setStatus(`Rendering…`,`loading`),this.stage.style.setProperty(`--render-background`,`var(--preview-bg)`);try{let c=aw(e),l;if(c)try{let a=await c.render({type:e,source:t,options:n},s.signal);l={body:Fw(a.body,r,i,e),identity:{unit:e,build:a.build||a.version,pipeline:Array.isArray(a.pipeline)?a.pipeline:[e]}},this.status.dataset.cache=`browser`,this.status.dataset.renderer=e}catch(a){if(a.name===`AbortError`||Rw(e))throw a;l=await this.renderThroughGateway({type:e,source:t,options:n,meta:r,presentation:i},s.signal)}else l=await this.renderThroughGateway({type:e,source:t,options:n,meta:r,presentation:i},s.signal);if(o!==this.requestNumber)return;let{blob:u,background:d}=this.normalizedSvgBlob(l.body);this.latestRenderKey=a,this.latestSvgBlob=u,this.latestRendererIdentity=l.identity,this.imageFallbackUrl=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(await u.text())}`,this.stage.style.setProperty(`--render-background`,d);let f=URL.createObjectURL(u),p=this.objectUrl;this.objectUrl=f,this.activeImageUrl=f,this.image.src=f,this.minimapImage.src=f,this.image.hidden=!1,this.setStatus(`Loading image…`,`loading`),p&&URL.revokeObjectURL(p)}catch(e){if(e.name===`AbortError`)return;this.setStatus(e.message||`Could not render this diagram.`,`error`)}finally{this.abortController===s&&(this.abortController=null)}}async renderThroughGateway({type:e,source:t,options:n,meta:r,presentation:i},a){let o=zw(e);if(o){try{let s=await this.renderRequest(o,{source:t,format:`svg`,options:n,metadata:r,presentation:i},a);if(s.ok||s.status<500)return await this.renderResponse(s,e);await s.body?.cancel()}catch(t){if(t.name===`AbortError`||Rw(e))throw t}if(Rw(e))throw Error(`The ${e} renderer unit is unavailable.`)}let s=await this.renderRequest(`/render/v1/svg`,{engine:e,source:t,format:`svg`,options:n,metadata:r,presentation:i},a);return this.renderResponse(s,e)}renderRequest(e,t,n){return fetch(e,{method:`POST`,headers:{Accept:`image/svg+xml`,"Content-Type":`application/json`},body:JSON.stringify(t),signal:n})}async renderResponse(e,t){if(!e.ok)throw Error(await this.errorMessage(e));this.status.dataset.cache=e.headers.get(`X-Diagram-Cache`)?.toLowerCase()??`miss`,this.status.dataset.renderer=e.headers.get(`X-Diagram-Unit`)?.toLowerCase()??e.headers.get(`X-Diagram-Renderer`)?.toLowerCase()??`gateway`;let n=e.headers.get(`X-Diagram-Unit`)?.toLowerCase()??e.headers.get(`X-Diagram-Engine`)?.toLowerCase()??t,r=e.headers.get(`X-Renderer-Build`)??e.headers.get(`X-Diagram-Engine-Version`)??`${n}-unknown`,i=(e.headers.get(`X-Diagram-Pipeline`)??n).split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean);return{body:await e.text(),identity:{unit:n,build:r,pipeline:i}}}retryBlockedImage(){if(this.image.src===this.activeImageUrl){if(this.imageFallbackUrl&&this.activeImageUrl.startsWith(`blob:`)){let e=this.imageFallbackUrl;this.imageFallbackUrl=null,this.objectUrl&&URL.revokeObjectURL(this.objectUrl),this.objectUrl=null,this.activeImageUrl=e,this.image.src=e,this.minimapImage.src=e;return}this.setStatus(`The rendered image was blocked or invalid.`,`error`)}}svgBlobFor(e){let{type:t,source:n,options:r={},meta:i={},presentation:a={}}=e,o=JSON.stringify({type:t,source:n,options:r,meta:i,presentation:a});return this.latestRenderKey===o?this.latestSvgBlob:null}rendererIdentityFor(e){let{type:t,source:n,options:r={},meta:i={},presentation:a={}}=e,o=JSON.stringify({type:t,source:n,options:r,meta:i,presentation:a});return this.latestRenderKey===o?this.latestRendererIdentity:null}async errorMessage(e){let t=await e.text();if(e.headers.get(`Content-Type`)?.includes(`application/json`))try{let e=JSON.parse(t);if(typeof e?.error?.message==`string`)return e.error.message}catch{}return new DOMParser().parseFromString(t,`text/html`).body.textContent.trim().replace(/\s+/g,` `)||`Render failed with HTTP ${e.status}.`}normalizedSvgBlob(e){let t=new DOMParser().parseFromString(e,`image/svg+xml`).documentElement,n=t.getAttribute(`viewBox`)?.trim().split(/[\s,]+/).map(Number);t.nodeName===`svg`&&n?.length===4&&n.every(Number.isFinite)&&(t.hasAttribute(`width`)||t.setAttribute(`width`,String(n[2])),t.hasAttribute(`height`)||t.setAttribute(`height`,String(n[3])),e=new XMLSerializer().serializeToString(t));let r=t.style.backgroundColor||t.style.background,i=r&&r!==`transparent`?r:`#ffffff`;return{blob:new Blob([e],{type:`image/svg+xml`}),background:i}}setStatus(e,t){this.status.textContent=e,this.status.dataset.state=t}zoom(e){if(this.image.hidden)return;let t=this.stage.getBoundingClientRect();this.zoomAt(e,t.width/2,t.height/2)}zoomAt(e,t,n){let r=Bw(this.scale*e,.1,8),i=(t-this.x)/this.scale,a=(n-this.y)/this.scale;this.x=t-i*r,this.y=n-a*r,this.scale=r,this.updateTransform()}wheelZoom(e){if(this.image.hidden||e.target.closest(`.preview-toolbar, .minimap`))return;e.preventDefault();let t=this.stage.getBoundingClientRect(),n=e.deltaY*(e.deltaMode===WheelEvent.DOM_DELTA_LINE?16:e.deltaMode===WheelEvent.DOM_DELTA_PAGE?t.height:1);this.zoomAt(Math.exp(-Bw(n,-240,240)*.002),e.clientX-t.left,e.clientY-t.top)}oneToOne(){if(this.image.hidden)return;let e=this.stage.getBoundingClientRect();this.scale=1,this.x=(e.width-this.image.naturalWidth)/2,this.y=(e.height-this.image.naturalHeight)/2,this.updateTransform()}fit(){if(!this.image.naturalWidth||!this.image.naturalHeight)return;let e=this.stage.getBoundingClientRect(),t=Math.min(64,e.width*.12);this.scale=Bw(Math.min((e.width-t*2)/this.image.naturalWidth,(e.height-t*2)/this.image.naturalHeight),.1,2),this.x=(e.width-this.image.naturalWidth*this.scale)/2,this.y=(e.height-this.image.naturalHeight*this.scale)/2,this.updateTransform()}updateTransform(){this.image.style.transform=`translate(${this.x}px, ${this.y}px) scale(${this.scale})`,this.updateMinimap()}startPan(e){this.image.hidden||e.button!==0||e.target.closest(`.preview-toolbar, .minimap`)||(this.drag={pointerId:e.pointerId,x:e.clientX,y:e.clientY,originX:this.x,originY:this.y},this.stage.setPointerCapture(e.pointerId),this.stage.dataset.dragging=`true`)}pan(e){!this.drag||e.pointerId!==this.drag.pointerId||(this.x=this.drag.originX+e.clientX-this.drag.x,this.y=this.drag.originY+e.clientY-this.drag.y,this.updateTransform())}endPan(e){!this.drag||e.pointerId!==this.drag.pointerId||(this.drag=null,delete this.stage.dataset.dragging)}moveFromMinimap(e){if(!this.image.naturalWidth||!this.image.naturalHeight)return;let t=this.minimap.getBoundingClientRect(),n=Math.min(t.width/this.image.naturalWidth,t.height/this.image.naturalHeight),r=(t.width-this.image.naturalWidth*n)/2,i=(t.height-this.image.naturalHeight*n)/2,a=(e.clientX-t.left-r)/n,o=(e.clientY-t.top-i)/n,s=this.stage.getBoundingClientRect();this.x=s.width/2-a*this.scale,this.y=s.height/2-o*this.scale,this.updateTransform()}updateMinimap(){if(!this.image.naturalWidth||!this.image.naturalHeight)return;let e=this.stage.getBoundingClientRect(),t=this.image.naturalWidth*this.scale,n=this.image.naturalHeight*this.scale,r=this.x>=0&&this.y>=0&&this.x+t<=e.width&&this.y+n<=e.height;if(this.minimap.hidden=r,r)return;let i=this.minimap.getBoundingClientRect(),a=Math.min(i.width/this.image.naturalWidth,i.height/this.image.naturalHeight),o=(i.width-this.image.naturalWidth*a)/2,s=(i.height-this.image.naturalHeight*a)/2,c=Bw(-this.x/this.scale,0,this.image.naturalWidth),l=Bw(-this.y/this.scale,0,this.image.naturalHeight),u=Bw((e.width-this.x)/this.scale,0,this.image.naturalWidth),d=Bw((e.height-this.y)/this.scale,0,this.image.naturalHeight);this.minimapViewport.style.left=`${o+c*a}px`,this.minimapViewport.style.top=`${s+l*a}px`,this.minimapViewport.style.width=`${Math.max(4,(u-c)*a)}px`,this.minimapViewport.style.height=`${Math.max(4,(d-l)*a)}px`}},Hw=`diagram.zip:draft:local:v2`,Uw=`diagram.zip:draft:alias:v1:`,Ww=`diagram.zip:write:v1:`,Gw=new ke,Kw=new kC,qw,Jw=!1,Yw,Xw=!1,Zw=``,Q={aliasId:null,contentId:null,renderId:null,revision:null,mode:`open`,savedMode:null,writeCapability:null,savedState:null,savedSnapshot:null,bundleKey:null,keyEnvelope:null,encryptedContent:null,encryptedMetadata:null,keyEnvelopeDirty:!1,dirty:!0},Qw=new Map;document.querySelector(`#app`).innerHTML=`16481648 <main class="app-shell">16491649 <header class="app-header">16501650 <a class="brand" href="/" aria-label="New diagram"><img class="brand-mark" src="/diagram.zip/icon.svg" alt=""><span>diagram.zip</span></a>
M server/src/main/resources/web/diagramzip/index.html +1 -1