@phin-tech/dottie 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /*! dottie.js 0.11.0 | Apache-2.0 | https://github.com/phin-tech/dottie */
1
+ /*! dottie.js 0.11.1 | Apache-2.0 | https://github.com/phin-tech/dottie */
2
2
  "use strict";(()=>{var Rn=Object.defineProperty;var An=(e,t,n)=>t in e?Rn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var _=(e,t,n)=>An(e,typeof t!="symbol"?t+"":t,n);var Ne=.5522847498307936,st=class e{constructor(){_(this,"segments",[])}get isEmpty(){return this.segments.length===0}moveTo(t){return this.segments.push({op:"M",p:t}),this}lineTo(t){return this.segments.push({op:"L",p:t}),this}quadTo(t,n){return this.segments.push({op:"Q",c:n,p:t}),this}curveTo(t,n,r){return this.segments.push({op:"C",c1:n,c2:r,p:t}),this}close(){return this.segments.push({op:"Z"}),this}addPath(t){return this.segments.push(...t.segments),this}addLines(t){return t.forEach((n,r)=>r===0?this.moveTo(n):this.lineTo(n)),this}static rect(t){return new e().addLines([{x:t.x,y:t.y},{x:t.x+t.width,y:t.y},{x:t.x+t.width,y:t.y+t.height},{x:t.x,y:t.y+t.height}]).close()}addEllipse(t){let n=t.x+t.width/2,r=t.y+t.height/2,o=t.width/2,s=t.height/2,i=o*Ne,l=s*Ne;return this.moveTo({x:n+o,y:r}),this.curveTo({x:n,y:r+s},{x:n+o,y:r+l},{x:n+i,y:r+s}),this.curveTo({x:n-o,y:r},{x:n-i,y:r+s},{x:n-o,y:r+l}),this.curveTo({x:n,y:r-s},{x:n-o,y:r-l},{x:n-i,y:r-s}),this.curveTo({x:n+o,y:r},{x:n+i,y:r-s},{x:n+o,y:r-l}),this.close()}static ellipse(t){return new e().addEllipse(t)}translated(t,n){let r=s=>({x:s.x+t,y:s.y+n}),o=new e;return o.segments=this.segments.map(s=>{switch(s.op){case"M":case"L":return{op:s.op,p:r(s.p)};case"Q":return{op:"Q",c:r(s.c),p:r(s.p)};case"C":return{op:"C",c1:r(s.c1),c2:r(s.c2),p:r(s.p)};case"Z":return s}}),o}contours(){let t=[],n=[],r={x:0,y:0};for(let o of this.segments){let s=n.length?n[n.length-1]:r;switch(o.op){case"M":n.length>1&&t.push(n),r=o.p,n=[o.p];break;case"L":n.push(o.p);break;case"Q":for(let i=1;i<=12;i++){let l=i/12,a=1-l;n.push({x:a*a*s.x+2*a*l*o.c.x+l*l*o.p.x,y:a*a*s.y+2*a*l*o.c.y+l*l*o.p.y})}break;case"C":for(let i=1;i<=16;i++){let l=i/16,a=1-l;n.push({x:a*a*a*s.x+3*a*a*l*o.c1.x+3*a*l*l*o.c2.x+l*l*l*o.p.x,y:a*a*a*s.y+3*a*a*l*o.c1.y+3*a*l*l*o.c2.y+l*l*l*o.p.y})}break;case"Z":n.push(r),n.length>1&&t.push(n),n=[r];break}}return n.length>1&&t.push(n),t}trimmed(t){let n=this.contours().map(s=>new kt(s)),r=Math.min(Math.max(t,0),1)*n.reduce((s,i)=>s+i.length,0),o=new e;for(let s of n){if(!(r>0))break;o.moveTo(s.points[0]);for(let i=1;i<s.points.length;i++){let l=s.lengths[i]-s.lengths[i-1];if(l<=r){o.lineTo(s.points[i]),r-=l;continue}let a=s.points[i-1],c=s.points[i],u=r/l;o.lineTo({x:a.x+(c.x-a.x)*u,y:a.y+(c.y-a.y)*u}),r=0;break}}return o}data(){let t=[];for(let n of this.segments)switch(n.op){case"M":t.push(`M${ut(n.p.x)} ${ut(n.p.y)}`);break;case"L":t.push(`L${ut(n.p.x)} ${ut(n.p.y)}`);break;case"Q":t.push(`Q${ut(n.c.x)} ${ut(n.c.y)} ${ut(n.p.x)} ${ut(n.p.y)}`);break;case"C":t.push(`C${ut(n.c1.x)} ${ut(n.c1.y)} ${ut(n.c2.x)} ${ut(n.c2.y)} ${ut(n.p.x)} ${ut(n.p.y)}`);break;case"Z":t.push("Z");break}return t.join(" ")}};function Fe(e){return e<0?-Math.round(-e):Math.round(e)}function ut(e){let t=Fe(e*100)/100;return Number.isInteger(t)?String(t===0?0:t):String(t)}var kt=class{constructor(t){_(this,"points");_(this,"lengths");this.points=t;let n=0;this.lengths=t.map((r,o)=>(o>0&&(n+=Math.hypot(r.x-t[o-1].x,r.y-t[o-1].y)),n))}get length(){return this.lengths.length?this.lengths[this.lengths.length-1]:0}point(t){if(this.points.length<=1||!(this.length>0))return this.points[0]??{x:0,y:0};let n=Math.min(Math.max(t,0),1)*this.length,r=1;for(;r<this.lengths.length-1&&this.lengths[r]<n;)r++;let o=this.lengths[r]-this.lengths[r-1],s=o>0?(n-this.lengths[r-1])/o:0,i=this.points[r-1],l=this.points[r];return{x:i.x+(l.x-i.x)*s,y:i.y+(l.y-i.y)*s}}},At=e=>e.x+e.width/2,St=e=>e.y+e.height/2,xt=e=>e.x+e.width,bt=e=>e.y+e.height;function ee(e,t,n){if(n===0)return e;let r=e.x-t.x,o=e.y-t.y;return{x:t.x+r*Math.cos(n)-o*Math.sin(n),y:t.y+r*Math.sin(n)+o*Math.cos(n)}}function De(e,t){let n=1-t;return{x:e[0].x*(n*n*n)+e[1].x*(3*t*n*n)+e[2].x*(3*t*t*n)+e[3].x*(t*t*t),y:e[0].y*(n*n*n)+e[1].y*(3*t*n*n)+e[2].y*(3*t*t*n)+e[3].y*(t*t*t)}}var Sn=["throughput","load","delay","backlog","depth","inFlight","transit","backup"],Ge={min:null,max:null,abs:1,floor:1,ceil:1,round:1,clamp:3},In=64,It=e=>typeof e=="boolean"?e:e!==0&&!Number.isNaN(e),_t=e=>typeof e=="boolean"?e?1:0:e,Ut=new Map;function re(e){let t=Ut.get(e);if(t!==void 0)return t;let n=new ne(e),r=n.or();return r&&!n.atEnd()&&(r=null),Ut.size>4096&&Ut.clear(),Ut.set(e,r),r}function pt(e,t,n=null){switch(e.k){case"lit":return e.v;case"name":return t[e.name]??!1;case"metric":return n?.(e.metric,e.target)??NaN;case"not":return!It(pt(e.e,t,n));case"neg":return-_t(pt(e.e,t,n));case"call":{let r=e.args.map(s=>_t(pt(s,t,n))),o=s=>{if(r.some(Number.isNaN))return NaN;let i=r[0];for(let l of r.slice(1))s(l,i)&&(i=l);return i};switch(e.fn){case"min":return o((s,i)=>s<i);case"max":return o((s,i)=>s>i);case"abs":return Math.abs(r[0]);case"floor":return Math.floor(r[0]);case"ceil":return Math.ceil(r[0]);case"round":return Math.floor(r[0]+.5);default:return r.some(Number.isNaN)?NaN:r[0]<r[1]?r[1]:r[0]>r[2]?r[2]:r[0]}}case"bin":{if(e.op==="&&")return It(pt(e.l,t,n))&&It(pt(e.r,t,n));if(e.op==="||")return It(pt(e.l,t,n))||It(pt(e.r,t,n));let r=pt(e.l,t,n),o=pt(e.r,t,n),s=_t(r),i=_t(o);switch(e.op){case"+":return s+i;case"-":return s-i;case"*":return s*i;case"/":return s/i;case"%":return s%i}if(Number.isNaN(s)||Number.isNaN(i))return!1;switch(e.op){case"<":return s<i;case"<=":return s<=i;case">":return s>i;case">=":return s>=i;case"==":return typeof r=="boolean"&&typeof o=="boolean"?r===o:s===i;default:return typeof r=="boolean"&&typeof o=="boolean"?r!==o:s!==i}}}}function Le(e){let t=[],n=r=>{switch(r.k){case"metric":t.push({metric:r.metric,target:r.target});break;case"not":case"neg":n(r.e);break;case"bin":n(r.l),n(r.r);break;case"call":r.args.forEach(n);break}};return n(e),t}var Ft=e=>e!==void 0&&e>="0"&&e<="9",ve=e=>e!==void 0&&(e==="_"||e>="a"&&e<="z"||e>="A"&&e<="Z"),ne=class{constructor(t){_(this,"s");_(this,"i",0);this.s=[...t]}atEnd(){return this.skip(),this.i===this.s.length}skip(){for(;this.i<this.s.length&&`
3
3
  \r`.includes(this.s[this.i]);)this.i++}eat(t){this.skip();let n=[...t];if(this.i+n.length>this.s.length)return!1;for(let r=0;r<n.length;r++)if(this.s[this.i+r]!==n[r])return!1;return n.length===1&&this.s[this.i+1]==="="&&"<>!=".includes(n[0])?!1:(this.i+=n.length,!0)}or(){let t=this.and();if(!t)return null;for(;this.eat("||");){let n=this.and();if(!n)return null;t={k:"bin",op:"||",l:t,r:n}}return t}and(){let t=this.compare();if(!t)return null;for(;this.eat("&&");){let n=this.compare();if(!n)return null;t={k:"bin",op:"&&",l:t,r:n}}return t}compare(){let t=this.sum();if(!t)return null;for(let n of["<=",">=","==","!=","<",">"])if(this.eat(n)){let r=this.sum();return r?{k:"bin",op:n,l:t,r}:null}return t}sum(){let t=this.product();if(!t)return null;for(;;){let n=this.eat("+")?"+":this.eat("-")?"-":null;if(!n)return t;let r=this.product();if(!r)return null;t={k:"bin",op:n,l:t,r}}}product(){let t=this.unary();if(!t)return null;for(;;){let n=["*","/","%"].find(o=>this.eat(o));if(!n)return t;let r=this.unary();if(!r)return null;t={k:"bin",op:n,l:t,r}}}unary(){if(this.eat("!")){let t=this.unary();return t?{k:"not",e:t}:null}if(this.eat("-")){let t=this.unary();return t?{k:"neg",e:t}:null}return this.primary()}primary(){if(this.skip(),this.i>=this.s.length)return null;if(this.eat("(")){let l=this.or();return l&&this.eat(")")?l:null}let t=this.s,n=t[this.i];if(Ft(n)){let l=this.i;for(;Ft(t[this.i]);)this.i++;if(t[this.i]==="."&&Ft(t[this.i+1]))for(this.i++;Ft(t[this.i]);)this.i++;return{k:"lit",v:Number(t.slice(l,this.i).join(""))}}if(!ve(n))return null;let r=this.i;for(;ve(t[this.i])||Ft(t[this.i]);)this.i++;let o=t.slice(r,this.i).join("");if(o.length>In)return null;let s=this.i;for(;t[s]===" "||t[s]===" ";)s++;let i=t[s]==="(";if(Sn.includes(o)){if(!i)return{k:"metric",metric:o,target:""};this.eat("(");let l=this.i;for(;this.i<t.length&&t[this.i]!==")"&&t[this.i]!=="(";)this.i++;if(t[this.i]!==")")return null;let a=t.slice(l,this.i).join("").replace(/^[ \t]+|[ \t]+$/g,"");return this.i++,{k:"metric",metric:o,target:a}}if(o in Ge){if(!i||!this.eat("("))return null;let l=[];if(!this.eat(")")){do{let c=this.or();if(!c)return null;l.push(c)}while(this.eat(","));if(!this.eat(")"))return null}let a=Ge[o];return(a!==null?l.length!==a:l.length===0)?null:{k:"call",fn:o,args:l}}return i?null:o==="true"?{k:"lit",v:!0}:o==="false"?{k:"lit",v:!1}:{k:"name",name:o}}};var dt=(e,t,n)=>({r:e,g:t,b:n,a:1});function Tn(e){let t=parseInt(e.slice(1),16);return{r:(t>>16&255)/255,g:(t>>8&255)/255,b:(t&255)/255,a:1}}var On=["accent","muted","danger","warning","success","info"],le=e=>On.map((t,n)=>({name:t,color:Tn(e[n])})),ie=le(["#2563eb","#6b7280","#dc2626","#d97706","#16a34a","#0891b2"]),oe=le(["#93c5fd","#cbd5e1","#fca5a5","#fcd34d","#86efac","#67e8f9"]),Cn=[{id:"paper",name:"Paper",background:dt(.984,.98,.965),ink:dt(.12,.12,.13),palette:ie},{id:"white",name:"White",background:dt(1,1,1),ink:dt(.12,.12,.13),palette:ie},{id:"sepia",name:"Sepia",background:dt(.953,.914,.824),ink:dt(.23,.18,.13),palette:le(["#9a3412","#78716c","#b91c1c","#b45309","#4d7c0f","#0e7490"])},{id:"blueprint",name:"Blueprint",background:dt(.106,.227,.361),ink:dt(.91,.945,.984),palette:oe},{id:"chalkboard",name:"Chalkboard",background:dt(.169,.227,.2),ink:dt(.945,.945,.918),palette:oe},{id:"midnight",name:"Midnight",background:dt(.082,.086,.102),ink:dt(.925,.925,.94),palette:oe}];function Nn(e){return Cn.find(t=>t.id===e)??null}function Fn(e){let t=e.customTheme;return t?{id:"custom",name:t.name,background:t.background,ink:t.ink,palette:t.palette}:Nn(e.theme)}function se(e,t){let n=t.trim().toLowerCase();return(Fn(e)?.palette??ie).find(r=>r.name.toLowerCase()===n)?.color??null}function Be(e){let t=r=>!!r.style.named;if(!e.elements.some(t)&&!(e.symbols??[]).some(r=>r.elements.some(t)))return e;let n=r=>{let o=r.style.named;if(!o)return r;let s={...r.style},i=o.fill!==null?se(e,o.fill):null,l=o.stroke!==null?se(e,o.stroke):null,a=o.textColor!==null?se(e,o.textColor):null;return i&&(s.fill={...i}),l&&(s.stroke={...l}),a&&(s.textColor={...a}),{...r,style:s}};return{...e,elements:e.elements.map(n),symbols:e.symbols?e.symbols.map(r=>({...r,elements:r.elements.map(n)})):e.symbols}}var Ve=3,Dn=["rectangle","ellipse","diamond","text","connector","freehand","path","note","image","symbol"],Gn=["linear","easeIn","easeOut","easeInOut","hold","spring","bounce","elastic"],vn={file:["version","pages","images"],page:["id","name","layers","elements","theme","customTheme","logic","guidesX","guidesY","guidesLocked","timeline","symbols","variables","flows"],flow:["id","from","to","every","speed","color","size","when","spread","volume","overrides"],flowOverride:["when","volume"],symbol:["id","name","width","height","layers","elements","timeline","button","params"],layer:["id","name","visible","locked"],rgba:["r","g","b","a"],style:["stroke","fill","fillStyle","strokeWidth","dash","roughness","bowing","fontSize","font","gridSize","opacity","dashOffset","textColor","named"],colorNames:["fill","stroke","textColor"],customTheme:["name","background","ink","palette","base"],paletteColor:["name","color"],element:["id","kind","x","y","width","height","style","seed","layerID","text","connector","groupID","points","path","subpaths","evenOdd","rotation","link","url","anchor","click","hover","when","overrides","symbol","playback","offset","args","image","reveal","ports","labelRect","extension","capacity","delay","queue","gauge","containerID","container"],container:["fixed","lanes"],gauge:["metric","of","max","warn","alarm","style","label"],strokePoint:["x","y"],subpath:["closed","coords"],inlineImage:["data","format"],endpoint:["elementID","port","portIndex","x","y"],extensionRef:["id","shape","version","params"],normalizedPoint:["x","y"],normalizedRect:["x","y","width","height"],connector:["start","end","routing","startHead","endHead","waypoints","hops","avoid","cost"],waypoint:["x","y"],timeline:["fps","duration","boil","settle","poster","tracks","camera","markers"],track:["element","keys","boil","follow","repeats","march"],keyframe:["t","x","y","width","height","rotation","strokeWidth","stroke","fill","visible","reveal","opacity","ease"],follow:["path","start","end","ease","reverse","orient","laps"],repeat:["start","end","count"],cameraKey:["t","x","y","width","height","ease"],marker:["t","name","loop"],click:["scene","url","set","toggle","reset","run"],hover:["stroke","fill","opacity"],override:["when","stroke","fill","textColor","opacity","strokeWidth","dash","text","reroute","offline","cost","capacity","delay"]},Gt=3600,_e=1e4,Ln=e=>e===void 0||!Number.isFinite(e)||e===0?null:Math.min(Math.max(e,-_e),_e);var Bn={r:.12,g:.12,b:.13,a:1},Vn={r:0,g:0,b:0,a:0};var Mt=class extends Error{},M=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),g=e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,w=e=>typeof e=="string"?e:void 0,Ue=e=>M(e)&&Object.values(e).every(t=>typeof t=="string")?{...e}:null,mt=e=>typeof e=="boolean"?e:void 0,je="00000000-0000-0000-0000-000000000000",Dt=/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/,ft=e=>typeof e=="string"?e.toUpperCase():void 0;function ue(e){return Number.isFinite(e)?Math.min(Math.max(e,0),Gt):e===1/0?Gt:0}function He(e){return Number.isFinite(e)?Math.min(Math.max(e,1),60):12}function _n(e){let t=e.trim();return!/^(https?:\/\/|mailto:)/i.test(t)||[...t].length<=7||/[\u0000-\u001f\u007f-\u009f]/.test(t)?null:t}function ct(e){if(!M(e))return;let t=g(e.r),n=g(e.g),r=g(e.b);if(!(t===void 0||n===void 0||r===void 0))return{r:t,g:n,b:r,a:g(e.a)??1}}var ce=class{constructor(){_(this,"warnings",[]);_(this,"seen",new Set)}warn(t){this.seen.has(t)||(this.seen.add(t),this.warnings.push(t))}fields(t,n){let r=vn[n];for(let o of Object.keys(t))r.includes(o)||this.warn(`Unknown field "${o}" on ${n}, ignored`)}style(t){let n=M(t)?t:{};this.fields(n,"style");let r=w(n.fillStyle)??"solid",o=w(n.dash)??"solid";return["solid","hachure","crossHatch","grid"].includes(r)||this.warn(`Unknown fill style "${r}", drawn solid`),["solid","dashed","dotted"].includes(o)||this.warn(`Unknown dash "${o}", drawn solid`),{stroke:ct(n.stroke)??{...Bn},fill:ct(n.fill)??{...Vn},fillStyle:["solid","hachure","crossHatch","grid"].includes(r)?r:"solid",strokeWidth:g(n.strokeWidth)??2,dash:["solid","dashed","dotted"].includes(o)?o:"solid",roughness:g(n.roughness)??1,bowing:g(n.bowing)??1,fontSize:g(n.fontSize)??18,font:w(n.font)||null,gridSize:g(n.gridSize)??null,opacity:g(n.opacity)??null,dashOffset:g(n.dashOffset)??null,textColor:ct(n.textColor)??null,named:this.colorNames(n.named)}}container(t){return M(t)?(this.fields(t,"container"),{fixed:t.fixed===!0?!0:null,lanes:t.lanes==="rows"||t.lanes==="columns"?t.lanes:null}):null}colorNames(t){if(!M(t))return null;this.fields(t,"colorNames");let n={fill:w(t.fill)??null,stroke:w(t.stroke)??null,textColor:w(t.textColor)??null};return n.fill===null&&n.stroke===null&&n.textColor===null?null:n}customTheme(t){if(!M(t))return null;this.fields(t,"customTheme");let n=ct(t.background),r=ct(t.ink);if(!n||!r)return this.warn("A custom theme needs a background and an ink; drawn without it"),null;let o=(Array.isArray(t.palette)?t.palette:[]).filter(M).flatMap(s=>{this.fields(s,"paletteColor");let i=w(s.name),l=ct(s.color);return i&&l?[{name:i,color:l}]:[]});return{name:w(t.name)??"Custom",background:n,ink:r,palette:o,base:w(t.base)??null}}endpoint(t){let n=M(t)?t:{},r=w(n.port),o=g(n.portIndex);return{elementID:ft(n.elementID)??null,port:r&&["top","right","bottom","left"].includes(r)?r:null,portIndex:o!==void 0&&Number.isInteger(o)&&o>=0?o:null,x:g(n.x)??0,y:g(n.y)??0}}connector(t){if(!M(t))return null;this.fields(t,"connector");let n=(o,s)=>{let i=w(o);return i&&["none","arrow","triangle","dot","bar"].includes(i)?i:s},r=w(t.routing);return{start:this.endpoint(t.start),end:this.endpoint(t.end),routing:r&&["straight","curved","elbow"].includes(r)?r:"straight",startHead:n(t.startHead,"none"),endHead:n(t.endHead,"arrow"),waypoints:Array.isArray(t.waypoints)?t.waypoints.filter(M).map(o=>(this.fields(o,"waypoint"),{x:g(o.x)??0,y:g(o.y)??0})):null,hops:typeof t.hops=="boolean"?t.hops:null,avoid:typeof t.avoid=="boolean"?t.avoid:null,cost:typeof t.cost=="number"&&Number.isFinite(t.cost)?t.cost:null}}image(t,n){if(!M(t))return null;let r=w(t.ref);if(r!==void 0)return n[r]??{data:"",format:"png"};let o=w(t.data);return o===void 0?null:this.picture(o,w(t.format))}picture(t,n){return Un.test(t)?{data:t.replace(/\s+/g,""),format:n==="jpeg"?"jpeg":"png"}:(this.warn("Skipped a picture whose data isn't base64"),{data:"",format:"png"})}element(t,n){if(!M(t))return null;this.fields(t,"element");let r=ft(t.id),o=w(t.kind),s=ft(t.layerID);if(!r||!o||!s)return this.warn("Skipped an element without an id, kind or layer"),null;Dn.includes(o)||this.warn(`Unknown element kind "${o}", drawn as a placeholder`);let i=Array.isArray(t.subpaths)?t.subpaths.filter(M).map(l=>({closed:mt(l.closed)??!1,coords:Array.isArray(l.coords)?l.coords.filter(a=>typeof a=="number"):[]})):null;return{id:r,kind:o,layerID:s,x:g(t.x)??0,y:g(t.y)??0,width:g(t.width)??0,height:g(t.height)??0,style:this.style(t.style),seed:(g(t.seed)??1)>>>0,text:w(t.text)??null,connector:this.connector(t.connector),groupID:ft(t.groupID)??null,points:Array.isArray(t.points)?t.points.filter(M).map(l=>({x:g(l.x)??0,y:g(l.y)??0})):null,path:Array.isArray(t.path)?t.path.filter(l=>typeof l=="number"):null,subpaths:i,evenOdd:mt(t.evenOdd)??null,rotation:g(t.rotation)??null,link:ft(t.link)??null,url:w(t.url)??null,anchor:w(t.anchor)??null,click:this.click(t.click),hover:this.hover(t.hover),when:w(t.when)??null,overrides:this.overrides(t.overrides),symbol:ft(t.symbol)??null,playback:this.playback(t.playback),offset:g(t.offset)??null,args:Ue(t.args),image:this.image(t.image,n),reveal:g(t.reveal)??null,ports:Array.isArray(t.ports)?t.ports.map(l=>{let a=M(l)?l:{};return{x:g(a.x)??0,y:g(a.y)??0}}):null,labelRect:this.labelRect(t.labelRect),extension:this.extension(t.extension),capacity:g(t.capacity)??null,delay:g(t.delay)??null,queue:t.queue===!0?!0:null,gauge:this.gauge(t.gauge),containerID:ft(t.containerID)??null,container:this.container(t.container)}}gauge(t){if(!M(t))return null;this.fields(t,"gauge");let n=o=>typeof o=="number"&&Number.isFinite(o)?o:null,r=w(t.style);return{metric:w(t.metric)??"",of:typeof t.of=="string"&&Dt.test(t.of)?t.of.toUpperCase():je,max:n(t.max),warn:n(t.warn),alarm:n(t.alarm),style:r==="number"||r==="bar"||r==="dial"?r:null,label:w(t.label)??null}}labelRect(t){return M(t)?(this.fields(t,"normalizedRect"),{x:g(t.x)??0,y:g(t.y)??0,width:g(t.width)??0,height:g(t.height)??0}):null}extension(t){if(!M(t))return null;this.fields(t,"extensionRef");let n=w(t.id),r=w(t.shape),o=w(t.version);if(n===void 0||r===void 0||o===void 0)return this.warn("Skipped an extension without an id, shape or version"),null;let s={};if(M(t.params))for(let[i,l]of Object.entries(t.params))(typeof l=="number"||typeof l=="boolean"||typeof l=="string")&&(s[i]=l);return{id:n,shape:r,version:o,params:s}}variables(t){if(!M(t))return null;let n={};for(let[r,o]of Object.entries(t))(typeof o=="boolean"||typeof o=="number"&&Number.isFinite(o))&&(n[r]=o);return Object.keys(n).length>0?n:null}click(t){if(!M(t))return null;this.fields(t,"click");let n=w(t.url),r=n===void 0?null:_n(n);n!==void 0&&r===null&&this.warn("Skipped a click link that isn't http, https or mailto");let o=null;if(M(t.set)){o={};for(let[a,c]of Object.entries(t.set))jt(a)&&(typeof c=="boolean"||typeof c=="string"||typeof c=="number"&&Number.isFinite(c))&&(o[a]=c);Object.keys(o).length===0&&(o=null)}let s=typeof t.toggle=="string"?[t.toggle]:Array.isArray(t.toggle)&&t.toggle.every(a=>typeof a=="string")?t.toggle:null,i=s?s.filter(jt):null,l=w(t.run);return{scene:w(t.scene)??null,url:r,set:o,toggle:i&&i.length>0?i:null,reset:t.reset===!0?!0:null,run:l!==void 0&&jt(l)?l:null}}playback(t){let n=w(t);return n===void 0?null:["loop","once","still","click"].includes(n)?n:"loop"}symbol(t,n){if(!M(t))return null;this.fields(t,"symbol");let r=ft(t.id);if(!r)return this.warn("Skipped a symbol without an id"),null;let o=i=>{let l=g(i);return Math.max(1,l??100)},s=(Array.isArray(t.layers)?t.layers:[]).filter(M).flatMap(i=>{let l=ft(i.id);return l?[{id:l,name:w(i.name)??"",visible:mt(i.visible)??!0,locked:mt(i.locked)??!1}]:[]});return s.length===0&&s.push({id:`${r}-LAYER`,name:"Layer 1",visible:!0,locked:!1}),{id:r,name:w(t.name)??"Symbol",width:o(t.width),height:o(t.height),layers:s,elements:(Array.isArray(t.elements)?t.elements:[]).map(i=>this.element(i,n)).filter(i=>i!==null),timeline:this.timeline(t.timeline),button:mt(t.button)??null,params:Ue(t.params)}}overrides(t){return Array.isArray(t)?t.filter(M).map(n=>{this.fields(n,"override");let r=w(n.dash),o=null;if(M(n.reroute)&&Object.values(n.reroute).every(s=>typeof s=="string"&&Dt.test(s))){o={};for(let[s,i]of Object.entries(n.reroute))Dt.test(s)&&(o[s.toUpperCase()]=i.toUpperCase());Object.keys(o).length===0&&(o=null)}return{when:w(n.when)??"",stroke:ct(n.stroke)??null,fill:ct(n.fill)??null,textColor:ct(n.textColor)??null,opacity:g(n.opacity)??null,strokeWidth:g(n.strokeWidth)??null,dash:r!==void 0&&["solid","dashed","dotted"].includes(r)?r:null,text:w(n.text)??null,reroute:o,offline:n.offline===!0?!0:null,cost:typeof n.cost=="number"&&Number.isFinite(n.cost)?n.cost:null,capacity:typeof n.capacity=="number"&&Number.isFinite(n.capacity)?n.capacity:null,delay:typeof n.delay=="number"&&Number.isFinite(n.delay)?n.delay:null}}):null}hover(t){return M(t)?(this.fields(t,"hover"),{stroke:ct(t.stroke)??null,fill:ct(t.fill)??null,opacity:g(t.opacity)??null}):null}ease(t){let n=w(t);return n===void 0?null:Gn.includes(n)?n:(this.warn(`Unknown ease "${n}", played linear`),null)}keyframe(t){if(!M(t))return null;this.fields(t,"keyframe");let n=g(t.t);if(n===void 0)return null;let r={t:n};for(let a of["x","y","width","height","rotation","strokeWidth","reveal","opacity"]){let c=g(t[a]);c!==void 0&&(r[a]=c)}let o=ct(t.stroke),s=ct(t.fill),i=mt(t.visible),l=this.ease(t.ease);return o&&(r.stroke=o),s&&(r.fill=s),i!==void 0&&(r.visible=i),l&&(r.ease=l),r}track(t){if(!M(t))return null;this.fields(t,"track");let n=ft(t.element);if(!n)return null;let r=(Array.isArray(t.keys)?t.keys:[]).map(i=>this.keyframe(i)).filter(i=>i!==null&&i.t>=0&&i.t<=Gt);ae(r,i=>i.t);let o=Array.isArray(t.follow)?t.follow.filter(M).flatMap(i=>{let l=ft(i.path),a=g(i.start),c=g(i.end);return!l||a===void 0||c===void 0||a<0||c>Gt?[]:[{path:l,start:a,end:c,ease:this.ease(i.ease),reverse:mt(i.reverse)??null,orient:mt(i.orient)??null,laps:g(i.laps)??null}]}):null,s=Array.isArray(t.repeats)?t.repeats.filter(M).flatMap(i=>{let l=g(i.start),a=g(i.end);if(l===void 0||a===void 0)return[];let c=g(i.count),u={start:l,end:a,count:c===void 0?null:Math.trunc(c)};return We(u)?[u]:[]}):null;return{element:n,keys:r,boil:mt(t.boil)??null,follow:o,repeats:s,march:Ln(g(t.march))}}timeline(t){if(!M(t))return null;this.fields(t,"timeline");let n=g(t.boil),r=Array.isArray(t.camera)?t.camera.filter(M).flatMap(i=>{let l=g(i.t),a=g(i.x),c=g(i.y),u=g(i.width),p=g(i.height);return l===void 0||a===void 0||c===void 0||u===void 0||p===void 0?[]:u>1&&p>1&&l>=0?[{t:l,x:a,y:c,width:u,height:p,ease:this.ease(i.ease)}]:[]}):null;r&&ae(r,i=>i.t);let o=Array.isArray(t.markers)?t.markers.filter(M).flatMap(i=>{let l=g(i.t);return l!==void 0&&l>=0?[{t:l,name:w(i.name)??"",loop:mt(i.loop)??null}]:[]}):null;o&&ae(o,i=>i.t);let s=g(t.poster);return{fps:He(g(t.fps)??12),duration:ue(g(t.duration)??0),boil:n!==void 0&&Number.isInteger(n)&&n>0?Math.min(n,1e4):null,settle:mt(t.settle)??null,poster:s===void 0?null:ue(s),tracks:(Array.isArray(t.tracks)?t.tracks:[]).map(i=>this.track(i)).filter(i=>i!==null),camera:r,markers:o}}page(t,n,r){if(!M(t))throw new Mt(`Page ${r} is not an object`);this.fields(t,"page");let o=(Array.isArray(t.layers)?t.layers:[]).filter(M).flatMap(s=>{let i=ft(s.id);return i?[{id:i,name:w(s.name)??"",visible:mt(s.visible)??!0,locked:mt(s.locked)??!1}]:[]});return o.length===0&&(this.warn(`Page ${r} has no layers`),o.push({id:"LAYER",name:"Layer 1",visible:!0,locked:!1})),{id:ft(t.id)??`PAGE-${r}`,name:w(t.name)??`Page ${r}`,layers:o,elements:(Array.isArray(t.elements)?t.elements:[]).map(s=>this.element(s,n)).filter(s=>s!==null),theme:w(t.theme)??null,customTheme:this.customTheme(t.customTheme),logic:typeof t.logic=="string"&&t.logic.length>0?t.logic:null,timeline:this.timeline(t.timeline),symbols:Array.isArray(t.symbols)?t.symbols.map(s=>this.symbol(s,n)).filter(s=>s!==null):null,variables:this.variables(t.variables),flows:Array.isArray(t.flows)?t.flows.filter(M).map(s=>this.flow(s)):null}}flow(t){this.fields(t,"flow");let n=o=>typeof o=="string"&&Dt.test(o)?o.toUpperCase():je,r=o=>{let s=g(o);return s!==void 0&&Number.isFinite(s)?s:null};return{id:n(t.id),from:n(t.from),to:Array.isArray(t.to)&&t.to.every(o=>typeof o=="string")?t.to.filter(o=>Dt.test(o)).map(o=>o.toUpperCase()):[],every:r(t.every),speed:r(t.speed),size:r(t.size),color:M(t.color)&&["r","g","b","a"].every(o=>typeof t.color[o]=="number")?ct(t.color)??null:null,when:w(t.when)??null,spread:t.spread===!0?!0:null,volume:r(t.volume),overrides:Array.isArray(t.overrides)&&t.overrides.length>0?t.overrides.filter(M).map(o=>(this.fields(o,"flowOverride"),{when:w(o.when)??"",volume:r(o.volume)})):null}}},Un=/^[A-Za-z0-9+/=\s]*$/;function We(e){return Number.isFinite(e.start)&&Number.isFinite(e.end)&&e.start>=0&&e.end-e.start>.001&&e.end<=Gt&&(e.count===null||e.count>=1&&e.count<=1e4)}function ae(e,t){let n=e.map((r,o)=>[r,o]);n.sort((r,o)=>t(r[0])-t(o[0])||r[1]-o[1]);for(let r=0;r<e.length;r++)e[r]=n[r][0]}function ze(e){let t=e;if(typeof e=="string")try{t=JSON.parse(e)}catch(i){throw new Mt(`Not JSON: ${i.message}`)}if(!M(t))throw new Mt("Not a Dottie drawing");let n=g(t.version);if(n===void 0)throw new Mt("Not a Dottie drawing (no version)");if(!Array.isArray(t.pages)||t.pages.length===0)throw new Mt("A drawing needs at least one page");let r=new ce;r.fields(t,"file"),n>Ve&&r.warn(`File version ${n} is newer than this player knows (${Ve}); some things may not show`);let o={};if(M(t.images))for(let[i,l]of Object.entries(t.images))M(l)&&typeof l.data=="string"&&(o[i]=r.picture(l.data,w(l.format)));let s=t.pages.map((i,l)=>Be(r.page(i,o,l+1)));if(new Set(s.map(i=>i.id)).size!==s.length)throw new Mt("Two pages share an id");return{version:n,pages:s,warnings:r.warnings}}function Ht(e){return{...e,style:{...e.style,stroke:{...e.style.stroke},fill:{...e.style.fill},textColor:e.style.textColor?{...e.style.textColor}:null,named:e.style.named?{...e.style.named}:e.style.named},connector:e.connector?{...e.connector,start:{...e.connector.start},end:{...e.connector.end},waypoints:e.connector.waypoints?.map(t=>({...t}))??null}:null,gauge:e.gauge?{...e.gauge}:e.gauge}}var jn=64;function jt(e){return e.length<=jn&&/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)}function he(e){let t=re(e);return t!==null&&Le(t).length>0}function Wt(e,t,n=null){let r=re(e);return r?It(pt(r,t,n?(o,s)=>n({metric:o,target:s,op:"",value:0}):null)):!1}function me(e){return{...e,reroute:null,offline:null,cost:null,capacity:null,delay:null}}function fe(e,t){let n=Ht(t);if(e.stroke&&(n.style.stroke={...e.stroke}),e.fill&&(n.style.fill={...e.fill}),e.textColor&&(n.style.textColor={...e.textColor}),e.strokeWidth!==null&&(n.style.strokeWidth=Math.max(0,e.strokeWidth)),e.dash!==null&&(n.style.dash=e.dash),e.text!==null&&(n.text=e.text),e.cost!==null&&n.connector&&(n.connector.cost=Math.min(Math.max(e.cost,0),1e6)),e.capacity!==null&&(n.capacity=Math.max(e.capacity,0)),e.delay!==null&&n.kind!=="connector"&&(n.delay=Math.max(e.delay,0)),e.opacity!==null){let r=Math.min(Math.max(e.opacity,0),1)*(n.style.opacity??1);n.style.opacity=r>=1?null:r}return n}var Pt=e=>({x:e.x,y:e.y,width:e.width,height:e.height}),Ot=e=>e.rotation??0,vt=e=>({x:e.x+e.width/2,y:e.y+e.height/2}),Et=(e,t)=>ee(t,vt(e),Ot(e)),$e=(e,t)=>ee(t,vt(e),-Ot(e));function Ke(e){let t=Pt(e);if(Ot(e)===0)return t;let n=[{x:t.x,y:t.y},{x:xt(t),y:t.y},{x:xt(t),y:bt(t)},{x:t.x,y:bt(t)}].map(l=>Et(e,l)),r=n.map(l=>l.x),o=n.map(l=>l.y),s=Math.min(...r),i=Math.min(...o);return{x:s,y:i,width:Math.max(...r)-s,height:Math.max(...o)-i}}function Lt(e){if(e.kind!=="path"||!e.subpaths)return[];let t=[];for(let n of e.subpaths){if(n.coords.length<8||(n.coords.length-2)%6!==0)continue;let r=[];for(let o=0;o<n.coords.length;o+=2)r.push({x:e.x+n.coords[o]*e.width,y:e.y+n.coords[o+1]*e.height});t.push({closed:n.closed,points:r})}return t}function Ye(e){let t=new st;for(let n of Lt(e)){t.moveTo(n.points[0]);for(let r=0;r<(n.points.length-1)/3;r++)t.curveTo(n.points[3*r+3],n.points[3*r+1],n.points[3*r+2]);n.closed&&t.close()}return t}var zt=16,Hn=24,Xe=24,Wn=48;function zn(e){if(e.kind==="connector"||e.kind==="text"||e.kind==="freehand"||e.kind==="path"&&!e.extension||e.style.opacity!==null&&e.style.opacity<=0)return null;let t=Ke(e);return t.width<Xe||t.height<Xe?null:t}function de(e,t){let n=t.x+t.width,r=t.y+t.height;for(let o=1;o<e.length;o++){let s=e[o-1],i=e[o];if(s.y===i.y){if(t.y<s.y&&s.y<r&&Math.min(s.x,i.x)<n&&Math.max(s.x,i.x)>t.x)return!0}else if(s.x===i.x&&t.x<s.x&&s.x<n&&Math.min(s.y,i.y)<r&&Math.max(s.y,i.y)>t.y)return!0}return!1}var pe=e=>({x:e.x-zt,y:e.y-zt,width:e.width+2*zt,height:e.height+2*zt}),Ze=(e,t)=>t.x<e.x&&e.x<t.x+t.width&&t.y<e.y&&e.y<t.y+t.height,$t=new Map;function Je(e,t,n,r,o,s,i){let l=m=>!Ze(t,pe(m))&&!Ze(n,pe(m)),a=[],c=!1;for(let m of s){if(i.has(m.id))continue;let y=zn(m);!y||!l(y)||(a.push(y),!c&&de(e,y)&&(c=!0))}if(!c)return e;let u=JSON.stringify([t.x,t.y,n.x,n.y,r,o,a.map(m=>[m.x,m.y,m.width,m.height])]),p=$t.get(u);if(p)return p;let f=$n(e,t,n,r,o,a);return $t.size>=512&&$t.clear(),$t.set(u,f),f}function $n(e,t,n,r,o,s){let i=s.map((l,a)=>a).filter(l=>de(e,s[l]));if(i.length===0)return e;for(let l=0;l<4;l++){if(i.length>Wn)return e;let a=Kn(t,n,r,o,i.map(u=>pe(s[u])));if(!a)return e;let c=s.map((u,p)=>p).filter(u=>!i.includes(u)&&de(a,s[u]));if(c.length===0)return a;i=[...i,...c].sort((u,p)=>u-p)}return e}function Kn(e,t,n,r,o){let s=[e.x,t.x,(e.x+t.x)/2],i=[e.y,t.y,(e.y+t.y)/2];for(let k of o)s.push(k.x,k.x+k.width),i.push(k.y,k.y+k.height);s=[...new Set(s)].sort((k,v)=>k-v),i=[...new Set(i)].sort((k,v)=>k-v);let l=s.length,a=i.length,c=s.indexOf(e.x),u=i.indexOf(e.y),p=s.indexOf(t.x),f=i.indexOf(t.y);if(c<0||u<0||p<0||f<0)return null;let m=new Map(s.map((k,v)=>[k,v])),y=new Map(i.map((k,v)=>[k,v])),O=new Uint8Array(l*a),G=new Uint8Array(l*a),X=new Uint8Array(l*a);for(let k of o){let v=m.get(k.x),h=m.get(k.x+k.width),d=y.get(k.y),E=y.get(k.y+k.height);if(!(v===void 0||h===void 0||d===void 0||E===void 0))for(let R=v;R<h;R++)for(let b=d;b<E;b++)b>d&&(G[R*a+b]=1),R>v&&(X[R*a+b]=1),R>v&&b>d&&(O[R*a+b]=1)}let q=(k,v)=>O[k*a+v]===1,it=(k,v,h)=>G[Math.min(k,v)*a+h]===1,nt=(k,v,h)=>X[h*a+Math.min(k,v)]===1,x=l*a*2,P=new Array(x).fill(1/0),U=new Array(x).fill(-1),B=new Array(x).fill(!1),W=new ye,ht=(c*a+u)*2+(n?1:0);P[ht]=0,W.push(0,ht);let Q=(p*a+f)*2+(r?1:0);for(let k=W.pop();k;k=W.pop()){let[v,h]=k;if(B[h])continue;if(B[h]=!0,h===Q)break;let d=Math.floor(h/2),E=h%2,R=Math.floor(d/a),b=d%a;for(let[S,z]of[[1,0],[-1,0],[0,1],[0,-1]]){let tt=R+S,L=b+z;if(tt<0||tt>=l||L<0||L>=a||q(tt,L))continue;let lt=S!==0?0:1;if(S!==0?it(R,tt,b):nt(b,L,R))continue;let C=Math.abs(s[tt]-s[R])+Math.abs(i[L]-i[b]),Z=v+C+(lt!==E?Hn:0),at=(tt*a+L)*2+lt;Z<P[at]&&(P[at]=Z,U[at]=h,W.push(Z,at))}}if(!B[Q])return null;let wt=[];for(let k=Q;k>=0;k=U[k]){let v=Math.floor(k/2);wt.push({x:s[Math.floor(v/a)],y:i[v%a]})}return wt.reverse()}var ye=class{constructor(){_(this,"heap",[]);_(this,"next",0)}less(t,n){let r=this.heap[t],o=this.heap[n];return r[0]<o[0]||r[0]===o[0]&&r[1]<o[1]}push(t,n){this.heap.push([t,this.next++,n]);for(let r=this.heap.length-1;r>0;){let o=r-1>>1;if(!this.less(r,o))break;[this.heap[r],this.heap[o]]=[this.heap[o],this.heap[r]],r=o}}pop(){if(this.heap.length===0)return null;let t=this.heap[0],n=this.heap.pop();if(this.heap.length>0){this.heap[0]=n;for(let r=0;;){let o=2*r+1,s=o+1,i=r;if(o<this.heap.length&&this.less(o,i)&&(i=o),s<this.heap.length&&this.less(s,i)&&(i=s),i===r)break;[this.heap[r],this.heap[i]]=[this.heap[i],this.heap[r]],r=i}}return[t[0],t[2]]}};function Yn(e,t){let n=Pt(e),r=t==="top"?{x:At(n),y:n.y}:t==="right"?{x:xt(n),y:St(n)}:t==="bottom"?{x:At(n),y:bt(n)}:{x:n.x,y:St(n)};return Et(e,r)}function Xn(e){let t=[];for(let n=0;n+3<e.length;n+=3){let r=e.slice(n,n+4);for(let o=0;o<16;o++)t.push(De(r,o/16))}return t.push(e[e.length-1]),t}function Zn(e,t,n){let r=null,o=null;for(let i of Lt(e)){let l=Xn(i.points),a=l.length,c=i.closed?a:a-1;for(let u=0;u<c;u++){let p=l[u],f=l[(u+1)%a],m={x:f.x-p.x,y:f.y-p.y},y={x:p.x-t.x,y:p.y-t.y},O=m.x*n.y-n.x*m.y;if(O===0)continue;let G=(m.x*y.y-m.y*y.x)/O,X=(n.x*y.y-n.y*y.x)/O;G>0&&X>=0&&X<=1&&((r===null||G<r)&&(r=G),G<=1&&(o===null||G>o)&&(o=G))}}let s=o??r;return s===null?null:{x:t.x+n.x*s,y:t.y+n.y*s}}function Jn(e,t){let n=Pt(e),r=vt(e),o=$e(e,t),s=o.x-r.x,i=o.y-r.y;if(!((s!==0||i!==0)&&n.width>0&&n.height>0))return r;if(e.kind==="path"){let u=Zn(e,r,{x:s,y:i});if(u)return Et(e,u)}let l=n.width/2,a=n.height/2,c;return e.kind==="ellipse"?c=1/Math.sqrt(s*s/(l*l)+i*i/(a*a)):e.kind==="diamond"?c=1/(Math.abs(s)/l+Math.abs(i)/a):c=Math.min(s!==0?l/Math.abs(s):1/0,i!==0?a/Math.abs(i):1/0),Et(e,{x:r.x+s*c,y:r.y+i*c})}function qe(e,t){let n=e.elementID?t.get(e.elementID):void 0;return n?vt(n):{x:e.x,y:e.y}}function qn(e,t){let n=Pt(e);return Et(e,{x:n.x+t.x*n.width,y:n.y+t.y*n.height})}function Qe(e,t,n){let r=e.elementID?n.get(e.elementID):void 0;if(!r)return{x:e.x,y:e.y};let o=e.portIndex,s=r.ports??[];return typeof o=="number"&&Number.isInteger(o)&&o>=0&&o<s.length?qn(r,s[o]):e.port?Yn(r,e.port):Jn(r,t)}function en(e,t){let n=e.connector;if(!n)return[{x:0,y:0},{x:0,y:0}];let r=n.waypoints??[];return[Qe(n.start,r.length>0?r[0]:qe(n.end,t),t),Qe(n.end,r.length>0?r[r.length-1]:qe(n.start,t),t)]}function nn(e){if(e.kind==="polyline")return e.points;let t=[],n=e.points;for(let r=0;r<Math.floor((n.length-1)/3);r++){let o=n[3*r],s=n[3*r+1],i=n[3*r+2],l=n[3*r+3];for(let a=r===0?0:1;a<=24;a++){let c=a/24,u=1-c;t.push({x:u*u*u*o.x+3*u*u*c*s.x+3*u*c*c*i.x+c*c*c*l.x,y:u*u*u*o.y+3*u*u*c*s.y+3*u*c*c*i.y+c*c*c*l.y})}}return t}var Kt=e=>e===null?null:e==="top"||e==="bottom";function rn(e){let t=[];for(let n of e){let r=t[t.length-1];if(!(r&&Math.abs(r.x-n.x)<.5&&Math.abs(r.y-n.y)<.5)){if(t.length>=2){let o=t[t.length-2],s=t[t.length-1];if(Math.abs(o.x-s.x)<.5&&Math.abs(s.x-n.x)<.5||Math.abs(o.y-s.y)<.5&&Math.abs(s.y-n.y)<.5){t[t.length-1]=n;continue}}t.push(n)}}return t.length>=2?t:e}function Qn(e,t){switch(t.routing){case"straight":return{kind:"polyline",points:e};case"curved":{let n=[e[0]];for(let r=0;r<e.length-1;r++){let o=e[Math.max(r-1,0)],s=e[r],i=e[r+1],l=e[Math.min(r+2,e.length-1)];n.push({x:s.x+(i.x-o.x)/6,y:s.y+(i.y-o.y)/6}),n.push({x:i.x-(l.x-s.x)/6,y:i.y-(l.y-s.y)/6}),n.push(i)}return{kind:"curve",points:n}}case"elbow":{let n=e[0],r=e[1],o=Kt(t.start.port)??Math.abs(r.y-n.y)>Math.abs(r.x-n.x),s=Kt(t.end.port),i=[n];for(let l=1;l<e.length;l++){let a=e[l],c=i[i.length-1],u=Math.abs(c.x-a.x)<.5,p=Math.abs(c.y-a.y)<.5;if(u||p){i.push(a),u!==p&&(o=!u);continue}let f=l===e.length-1&&s!==null?!s:o;i.push(f?{x:c.x,y:a.y}:{x:a.x,y:c.y},a),o=f}return{kind:"polyline",points:rn(i)}}}}function on(e,t){let n=e.connector;if(!n)return{kind:"polyline",points:[]};let[r,o]=en(e,t);if(n.waypoints&&n.waypoints.length>0)return Qn([r,...n.waypoints.map(a=>({x:a.x,y:a.y})),o],n);let s=o.x-r.x,i=o.y-r.y,l=Math.abs(s)>=Math.abs(i);switch(n.routing){case"straight":return{kind:"polyline",points:[r,o]};case"curved":return l?{kind:"curve",points:[r,{x:r.x+s/2,y:r.y},{x:o.x-s/2,y:o.y},o]}:{kind:"curve",points:[r,{x:r.x,y:r.y+i/2},{x:o.x,y:o.y-i/2},o]};case"elbow":{let a=Kt(n.start.port)??!l,c=Kt(n.end.port)??!l,u;if(a&&c){let m=r.y+i/2;u=[r,{x:r.x,y:m},{x:o.x,y:m},o]}else if(!a&&!c){let m=r.x+s/2;u=[r,{x:m,y:r.y},{x:m,y:o.y},o]}else a?u=[r,{x:r.x,y:o.y},o]:u=[r,{x:o.x,y:r.y},o];if(n.avoid!==!0)return{kind:"polyline",points:u};let p=new Set([n.start.elementID,n.end.elementID].filter(m=>m!==null)),f=Je(u,r,o,a,c,t.values(),p);return{kind:"polyline",points:f===u?u:rn(f)}}}}var tn=new WeakMap;function Yt(e){let t=e.elements,n=tn.get(t);if(n&&n.members.length===t.length&&n.members.every((o,s)=>o===t[s]))return n.index;let r=new Map;for(let o of t)r.has(o.id)||r.set(o.id,o);return tn.set(t,{members:[...t],index:r}),r}function sn(e,t,n){let r=e[1]+n>>>0,o=r<e[1]?1:0;return[e[0]+t+o>>>0,r]}function tr(e,t){let n=e&65535,r=e>>>16,o=t&65535,s=t>>>16,i=n*o,l=n*s,a=r*o,c=r*s,u=l+a,p=i+u%65536*65536;return[c+Math.floor(u/65536)+Math.floor(p/4294967296)>>>0,p>>>0]}function ln(e,t,n){let r=tr(e[1],n);return[r[0]+Math.imul(e[0],n)+Math.imul(e[1],t)>>>0,r[1]]}function ge(e,t){let n=(e[1]>>>t|e[0]<<32-t)>>>0;return[(e[0]^e[0]>>>t)>>>0,(e[1]^n)>>>0]}function er(e){return e=ln(ge(e,30),3210233709,484763065),e=ln(ge(e,27),2496678331,321982955),ge(e,31)}var Xt=class{constructor(t){_(this,"state");this.state=sn([0,t>>>0],2654435769,2135587861)}next(){return this.state=sn(this.state,2654435769,2135587861),er(this.state)}top53(){let[t,n]=this.next();return t*2097152+(n>>>11)}signed(){return Math.floor(this.top53())/2**52-1}unit(){return this.top53()/2**53}};var an=(e,t,n)=>e.signed()*t*n;function xe(e,t,n,r,o,s,i){let l=Math.hypot(t.x-e.x,t.y-e.y);if(!(l>.5))return;let a=l<200?1:l>500?.4:-.0016668*l+1.233334,c=l<20?l/10:2;for(let u=0;u<2;u++){let p=(u===0?1:.5)*a,f=()=>an(n,c,r)*p,m=n.unit()*.4+.3,y=an(n,l/60,r)*o*a,O=t.x-e.x,G=t.y-e.y,X=-G/l,q=O/l,it=s?e:{x:e.x+f(),y:e.y+f()},nt=s?t:{x:t.x+f(),y:t.y+f()},x=e.x+O*m*.66+X*y+f()*.5,P=e.y+G*m*.66+q*y+f()*.5,U=e.x+O*(.5+m*.5)+X*y+f()*.5,B=e.y+G*(.5+m*.5)+q*y+f()*.5;i.moveTo(it),i.curveTo(nt,{x,y:P},{x:U,y:B})}}function be(e,t,n,r){let o=new st;for(let s=0;s<e.length;s++)xe(e[s],e[(s+1)%e.length],t,n,r,!1,o);return o}function un(e,t,n){let r=new st,o=e.x+e.width/2,s=e.y+e.height/2,i=e.width/2,l=e.height/2;if(!(i>.5&&l>.5))return r;let a=Math.max(8,Math.min(24,Math.trunc((i+l)/6))),c=Math.min(2.5,(i+l)/25)*n;for(let u=0;u<2;u++){let p=t.unit()*2*Math.PI,f=2*Math.PI*(u===0?1:1.04),m=Math.trunc(a*f/(2*Math.PI))+1,y=[];for(let O=0;O<m;O++){let G=p+f*O/a,X=t.signed()*c,q=t.signed()*c;y.push({x:o+i*Math.cos(G)+X,y:s+l*Math.sin(G)+q})}nr(y,r)}return r}function nr(e,t){if(!(e.length<=2)){t.moveTo(e[0]);for(let n=0;n<e.length-1;n++){let r=e[Math.max(n-1,0)],o=e[n],s=e[n+1],i=e[Math.min(n+2,e.length-1)];t.curveTo(s,{x:o.x+(s.x-r.x)/6,y:o.y+(s.y-r.y)/6},{x:s.x-(i.x-o.x)/6,y:s.y-(i.y-o.y)/6})}}}var rr=-41*Math.PI/180;var Zt=class{constructor(t=6e3){_(this,"map",new Map);_(this,"limit");this.limit=t}get(t,n){let r=this.map.get(t);if(r!==void 0)return r;let o=n();return this.map.size>=this.limit&&this.map.clear(),this.map.set(t,o),o}},sr=new Zt,eo=new Zt;function ir(e,t){let n=e.style;return[t,e.kind,e.x,e.y,e.width,e.height,e.seed,n.roughness,n.bowing,n.strokeWidth,n.fillStyle,n.fillStyle==="grid"?lr(e):0,e.path?e.path.join(","):e.subpaths?JSON.stringify(e.subpaths):""].join("|")}var lr=e=>Math.max(8,e.style.gridSize??50);function mn(e){return e.kind==="freehand"&&e.path===null?hn(e):sr.get(ir(e,0),()=>hn(e))}function ar(e){return[{x:e.x,y:e.y},{x:xt(e),y:e.y},{x:xt(e),y:bt(e)},{x:e.x,y:bt(e)}]}function cn(e){return[{x:At(e),y:e.y},{x:xt(e),y:St(e)},{x:At(e),y:bt(e)},{x:e.x,y:St(e)}]}function hn(e){let t=Pt(e),n=new Xt(e.seed),r=e.style.roughness;switch(e.kind){case"ellipse":return r<=0?st.ellipse(t):un(t,n,r);case"diamond":return r<=0?new st().addLines(cn(t)).close():be(cn(t),n,r,e.style.bowing);case"text":case"connector":return st.rect(t);case"freehand":return cr(e);case"path":return r<=0?Ye(e):ur(e,n);default:return r<=0?st.rect(t):be(ar(t),n,r,e.style.bowing)}}function ur(e,t){let n=e.style.roughness,r=new st;for(let o of Lt(e)){let s=o.points;for(let i=0;i<(s.length-1)/3;i++){let l=s[3*i],a=s[3*i+1],c=s[3*i+2],u=s[3*i+3];if(a.x===l.x&&a.y===l.y&&c.x===u.x&&c.y===u.y){xe(l,u,t,n,e.style.bowing,!0,r);continue}let p=Math.hypot(a.x-l.x,a.y-l.y)+Math.hypot(c.x-a.x,c.y-a.y)+Math.hypot(u.x-c.x,u.y-c.y),f=Math.min(2.5,p/30)*n;for(let m=0;m<2;m++){let y=m===0?1:.5,O=()=>t.signed()*f*y;r.moveTo(l);let G=a.x+O(),X=a.y+O(),q=c.x+O(),it=c.y+O();r.curveTo(u,{x:G,y:X},{x:q,y:it})}}}return r}function cr(e){let t=Pt(e),n=e.path;if(n&&n.length>=8&&(n.length-2)%6===0){let s=l=>({x:t.x+n[2*l]*t.width,y:t.y+n[2*l+1]*t.height}),i=new st().moveTo(s(0));for(let l=0;l<Math.floor((n.length/2-1)/3);l++)i.curveTo(s(3*l+3),s(3*l+1),s(3*l+2));return i}let r=(e.points??[]).map(s=>({x:t.x+s.x*t.width,y:t.y+s.y*t.height})),o=new st;if(r.length===0)return o;if(o.moveTo(r[0]),r.length===1)return o.lineTo(r[0]);if(r.length===2)return o.lineTo(r[1]);for(let s=1;s<r.length-1;s++)o.quadTo({x:(r[s].x+r[s+1].x)/2,y:(r[s].y+r[s+1].y)/2},r[s]);return o.lineTo(r[r.length-1])}function fn(e,t,n=Yt(t)){if(e.kind==="connector")return new kt(nn(on(e,n)));let r=Ht(e);r.style.roughness=0;let o=mn(r).contours()[0]??[];return new kt(Ot(e)===0?o:o.map(s=>Et(e,s)))}var pn=.5,Me=160,Pe=12,Ee={r:.95,g:.36,b:.33,a:1},Tt=(e,t,n,r)=>e===null||!Number.isFinite(e)?t:Math.min(Math.max(e,n),r);function Bt(e,t){let n=(t+1099511627776)%281474976710656;return e.slice(0,24)+(n<0?n+2**48:n).toString(16).toUpperCase().padStart(12,"0")}var qt=e=>e===null||!Number.isFinite(e)?1:Math.min(Math.max(e,0),1e6),dn=new WeakMap,Jt=new Map;function hr(e){let t=e.elements,n=dn.get(t);if(n&&n.members.length===t.length&&n.members.every((l,a)=>l===t[a]))return n.graph;let r=new Set(t.filter(l=>l.kind!=="connector").map(l=>l.id)),o=[];for(let l of t){let a=l.connector;a&&o.push([l.id,a.start.elementID,a.end.elementID,String(qt(a.cost)),a.startHead!=="none"?"both":"one"])}let s=JSON.stringify([[...r],o]),i=Jt.get(s);if(!i){let l=new Map,a=(c,u)=>{let p=l.get(c);p?p.push(u):l.set(c,[u])};for(let c of t){let u=c.connector,p=u?.start.elementID??null,f=u?.end.elementID??null;if(!u||p===null||f===null||p===f||!r.has(p)||!r.has(f))continue;let m=qt(u.cost);a(p,{to:f,via:c.id,back:!1,cost:m}),u.startHead!=="none"&&a(f,{to:p,via:c.id,back:!0,cost:m})}i={shapes:r,next:l,trees:new Map},Jt.size>=16&&Jt.clear(),Jt.set(s,i)}return dn.set(t,{members:[...t],graph:i}),i}var we=class{constructor(){_(this,"heap",[])}get size(){return this.heap.length}less(t,n){let r=this.heap[t],o=this.heap[n];return r.dist<o.dist||r.dist===o.dist&&r.order<o.order}swap(t,n){[this.heap[t],this.heap[n]]=[this.heap[n],this.heap[t]]}push(t,n,r){this.heap.push({id:t,dist:n,order:r});for(let o=this.heap.length-1;o>0;){let s=o-1>>1;if(!this.less(o,s))break;this.swap(o,s),o=s}}pop(){let t=this.heap[0],n=this.heap.pop();if(this.heap.length>0){this.heap[0]=n;for(let r=0;;){let o=2*r+1,s=o+1,i=r;if(o<this.heap.length&&this.less(o,i)&&(i=o),s<this.heap.length&&this.less(s,i)&&(i=s),i===r)break;this.swap(r,i),r=i}}return t}};function Qt(e,t,n=new Set,r){let o=hr(t),s=JSON.stringify([e,r??null,[...n].sort()]);if(o.trees.has(s))return o.trees.get(s);let i=mr(o,e,n,r);return o.trees.size>=4096&&o.trees.clear(),o.trees.set(s,i),i}function mr({shapes:e,next:t},n,r,o){if(!e.has(n)||r.has(n))return null;let s=new Map([[n,0]]),i=new Map([[n,0]]),l=1,a=new ke(n),c=new we;for(c.push(n,0,0);c.size>0;){let{id:u,order:p}=c.pop();if(!(a.settled.has(u)||i.get(u)!==p)){if(a.settled.add(u),u===o&&u!==n)break;for(let f of t.get(u)??[]){if(r.has(f.via)||r.has(f.to)||a.settled.has(f.to))continue;let m=s.get(u)+f.cost,y=s.get(f.to);y!==void 0&&y<=m||(s.set(f.to,m),i.set(f.to,l),c.push(f.to,m,l++),a.came.set(f.to,{from:u,via:f.via,back:f.back}))}}}return a}var ke=class{constructor(t){_(this,"settled",new Set);_(this,"came",new Map);_(this,"from");this.from=t}goals(t,n){let r=t.filter(o=>o!==this.from&&this.settled.has(o));return r.length===0?[]:n&&r[0]!==t[0]?r:[r[0]]}hops(t){let n=[];for(let r=t,o=this.came.get(r);o;r=o.from,o=this.came.get(r))n.push([o.via,o.back]);return n.reverse()}};var fr=()=>({elements:new Map,flows:new Map,carry:{}});function bn(e,t,n){let r=e.flows.get(n);if(r)switch(t){case"throughput":return r.placed;case"backlog":return r.backlog;case"backup":return r.backup;case"transit":return r.transit;default:return null}let o=e.elements.get(n);if(!o)return null;switch(t){case"throughput":return o.throughput;case"load":return o.load;case"delay":return o.delay;case"backlog":return o.backlog;case"inFlight":return o.inFlight;case"depth":return o.depth;default:return null}}var H=1e-9,Oe=e=>Tt(e.volume,1,0,1e12);function Re(e,t){if(t===null||!e.overrides)return Oe(e);let n=null;for(let r of e.overrides)r.volume!==null&&!he(r.when)&&Wt(r.when,t)&&(n=r.volume);return n===null?Oe(e):Math.min(Math.max(Number.isFinite(n)?n:1,0),1e12)}function yn(e){let t=e.delay??null;return e.kind==="connector"||t===null||!Number.isFinite(t)?0:Math.min(Math.max(t,0),3600)}var Ae=(e,t)=>e+"|"+t;function wn(e,t,n,r,o=new Set,s=null,i={}){let l=Math.max(0,Math.min(s??n,1e6)),a=Yt(t),c=new Map,u=h=>{let d=c.get(h.id);return d||(d=fn(h,t,a).points,c.set(h.id,d)),d},p=fr(),f=new Map;for(let h of t.elements)h.kind==="connector"&&!h.connector||p.elements.set(h.id,{throughput:0,load:null,delay:h.kind!=="connector"?yn(h):0,backlog:0,inFlight:0,depth:0});let m=e??[],y=new Map;for(let h of t.elements){let d=h.capacity??null;d!==null&&Number.isFinite(d)&&y.set(h.id,Math.max(d,0))}let O=()=>new Set([...y].filter(([,h])=>h<=H).map(([h])=>h)),G=(h,d)=>{let E=[],R=[],b=d;for(let S=h.came.get(b);S;S=h.came.get(b))E.push([S.via,S.back]),R.push(b),b=S.from;return R.push(b),{hops:E.reverse(),shapes:R.reverse()}},X=(h,d)=>{let E=[],R=[],b=[],S=0;return h.forEach(([z,tt],L)=>{let lt=a.get(z);if(!lt)return;let C=tt?[...u(lt)].reverse():u(lt);if(C.length===0)return;let Z=E[E.length-1];if(Z){let rt=Math.hypot(C[0].x-Z.x,C[0].y-Z.y),yt=a.get(d[L]);R.push([S,S+rt,yt?yn(yt):0]),S+=rt}let at=S;for(let rt=1;rt<C.length;rt++)S+=Math.hypot(C[rt].x-C[rt-1].x,C[rt].y-C[rt-1].y);b.push([z,at,S]),E.push(...C)}),S>0?{line:new kt(E),length:S,inside:R,stretches:b}:null},q=(h,d,E)=>{let R=d,b=0;for(let[S,z,tt]of h.inside){let L=(S-b)/E;if(R<=L)break;R-=L,b=S;let lt=(z-S)/E+tt;if(R<lt)return null;R-=lt,b=z}return b+=R*E,b>=0&&b<=h.length?b:null},it=(h,d)=>new Set([...h,...d]),nt=(h,d)=>{let E=p.elements.get(h);E&&d(E)},x=new Map,P=[];for(let h of m){let d=x.get(h.from)??0;P.push(d),x.set(h.from,d+1)}let U=m.length>0?Math.max(...m.map(Oe)):1,B=[],W=new Map,ht=h=>Math.min(Math.max(Tt(h.every,pn,.05,60)*U/Math.max(Re(h,r),H),.05),60),Q=new Map,wt=h=>(Q.has(h)||Q.set(h,Qt(h,t,o)),Q.get(h));for(let[h,d]of m.entries()){if(d.when!==null&&r!==null&&!Wt(d.when,r))continue;let E=a.get(d.from),R=E?wt(d.from):null;if(f.set(d.id,[]),!E||!R)continue;let b=Re(d,r),S={volume:b,placed:0,backlog:0,backup:0,transit:null},z=[],tt=[],L=R.goals(d.to,d.spread===!0),lt=L.length>1?L.map(I=>[[I],b/L.length]):[[d.to,b]];for(let[I,T]of lt){if(!(T>H))continue;let N=T;for(let F=0;F<32&&N>H;F++){let Y=Qt(d.from,t,it(o,O()),I[0]),J=Y?.goals(I,!1)[0];if(!Y||J===void 0)break;let D=G(Y,J),j=[...D.shapes,...D.hops.map(([A])=>A)],$=j.filter(A=>y.has(A)).map(A=>y.get(A)),V=Math.min(N,$.length>0?Math.min(...$):1/0);if(!(V>H))break;for(let A of j)y.has(A)&&y.set(A,y.get(A)-V);z.push({hops:D.hops,shapes:D.shapes,goal:J,amount:V}),N-=V}if(!(N>H))continue;let K=d.from,gt=R.goals(I,!1)[0];if(gt!==void 0){let F=G(R,gt),Y=O(),J=[[F.shapes[0],F.shapes[0]]];F.hops.forEach(([$],V)=>{J.push([$,F.shapes[V]],[F.shapes[V+1],F.shapes[V]])});let D=J.find(([$])=>Y.has($));if(D){K=D[1];let $=F.shapes.indexOf(K);for(let V=$;V>=0;V--){let A=a.get(F.shapes[V]);if(A&&A.queue===!0&&A.kind!=="connector"){K=F.shapes[V];break}}}let j=F.shapes.indexOf(K);if(K!==d.from&&j>=0){let $=F.shapes.slice(0,j+1),V=F.hops.slice(0,j);for(let A of[...$,...V.map(([te])=>te)])y.has(A)&&y.set(A,Math.max(0,y.get(A)-N));z.push({hops:V,shapes:$,goal:K,amount:N,waits:!0})}}let et=tt.find(([F])=>F===K);et?et[1]+=N:tt.push([K,N])}W.set(d.id,tt),f.set(d.id,z.map(I=>({goal:I.goal,hops:I.hops,amount:I.amount,waits:I.waits===!0,cost:I.hops.reduce((T,[N])=>T+qt(a.get(N)?.connector?.cost??null),0)})));for(let I of z){for(let T of[...I.shapes,...I.hops.map(([N])=>N)])nt(T,N=>{N.throughput+=I.amount});I.waits||(S.placed+=I.amount)}for(let[I,T]of tt)nt(I,N=>{N.backlog+=T}),S.backlog+=T;let C=z.filter(I=>!I.waits&&I.goal===d.to[0]).reduce((I,T)=>I+T.amount,0);S.backup=b>H?Math.max(0,(b-C)/b):0;let Z=ht(d),at=Tt(d.speed,Me,1,1e4),rt=Tt(d.size,Pe,2,200),yt=P[h]/x.get(d.from)*Z,Rt=d.color??Ee,ot=[],Nt=0;for(let I of z)Nt+=I.amount/Math.max(b,H),ot.push(Nt);ot.length>0&&Math.abs(ot[ot.length-1]-1)<1e-9&&(ot[ot.length-1]=1);let Vt=0;z.forEach((I,T)=>{let N=X(I.hops,I.shapes);if(!N)return;let K=N.length/at+N.inside.reduce((D,j)=>D+j[2],0);I.waits||(Vt+=K*I.amount);let gt=Math.ceil((n-yt-K)/Z),et=Math.floor((n-yt)/Z),F=T===0?0:ot[T-1],Y=ot[T],J=(D,j)=>Math.floor((j+1)*D)-Math.floor(j*D);for(let D=Math.max(gt,et-3999);D<=et;D++){if(J(Y,D)-J(F,D)!==1)continue;let j=q(N,n-D*Z-yt,at);if(j===null)continue;let $=N.stretches.find(([,A,te])=>j>=A&&j<=te);$&&nt($[0],A=>{A.inFlight+=1});let V=N.line.point(j/N.length);B.push(Se(Bt(d.id,D),V.x-rt/2,V.y-rt/2,rt,Rt,E.layerID))}}),S.transit=S.placed>H?Vt/S.placed:null,p.flows.set(d.id,S)}let k=new Map,v=Object.keys(i).filter(h=>i[h]>H);for(let h of m){let d=W.get(h.id)??[],E=d.map(([C])=>C),R="|"+h.id;if(v.some(C=>C.endsWith(R)))for(let C of t.elements){let Z=i[Ae(C.id,h.id)];Z!==void 0&&Z>H&&!E.includes(C.id)&&E.push(C.id)}if(E.length===0)continue;let b=Re(h,r),z=ht(h)*Math.max(b,H),tt=Tt(h.speed,Me,1,1e4),L=Tt(h.size,Pe,2,200),lt=h.color??Ee;E.forEach((C,Z)=>{let at=a.get(C);if(!at)return;let rt=a.get(h.from)?.layerID??at.layerID,yt=d.find(([T])=>T===C)?.[1]??0,Rt=Math.max(0,i[Ae(C,h.id)]??0),ot=Rt+yt*l;if(yt<=H&&Rt>H){let T=new Map(y),N=[],K=0;for(let gt=0;gt<32;gt++){let et=new Set([...T].filter(([,A])=>A<=H).map(([A])=>A)),F=Qt(C,t,it(o,et),h.to[0]),Y=F?.goals(h.to,!1)[0];if(!F||Y===void 0)break;let J=G(F,Y),D=[...J.shapes.slice(1),...J.hops.map(([A])=>A)],j=D.filter(A=>T.has(A)).map(A=>T.get(A)),$=j.length>0?Math.min(...j):1/0,V=Number.isFinite($)?$:Math.max(Rt/.5-K,H*2);if(!(V>H))break;for(let A of D)T.has(A)&&T.set(A,T.get(A)-V);if(N.push({hops:J.hops,shapes:J.shapes,rate:V}),K+=V,!Number.isFinite($))break}if(K>H){if(ot=Math.max(0,Rt-K*l),ot>H){for(let[et,F]of T)y.set(et,F);for(let et of N)for(let F of[...et.shapes,...et.hops.map(([Y])=>Y)])nt(F,Y=>{Y.throughput+=et.rate})}let gt=Rt/K;N.forEach((et,F)=>{let Y=X(et.hops,et.shapes);if(!Y)return;let J=Math.max(z/et.rate,.05);for(let D=0;D*J<gt&&D*J<=l&&D<2048;D++){let j=q(Y,l-D*J,tt);if(j===null)continue;let $=Y.line.point(j/Y.length);B.push(Se(Bt(h.id,2**39+2**20+Z*2**14+F*2**11+D),$.x-L/2,$.y-L/2,L,lt,rt))}})}}if(!(ot>H||yt>H))return;nt(C,T=>{T.depth+=ot}),ot>H&&(p.carry[Ae(C,h.id)]=ot);let Nt=Math.min(Math.max(Math.ceil(ot/z-1e-9),1),30),Vt=Math.trunc((Nt+9)/10),I=k.get(C)??0;k.set(C,I+Vt);for(let T=0;T<Nt;T++){let N=at.x+2+L/2+T%10*(L+3),K=at.y-4-L/2-(I+Math.trunc(T/10))*(L+3);B.push(Se(Bt(h.id,2**39+Z*64+T),N-L/2,K-L/2,L,lt,rt))}})}for(let h of t.elements){let d=h.capacity??null,E=p.elements.get(h.id);d===null||!Number.isFinite(d)||!E||(E.load=d>0?E.throughput/d:1)}return{packets:B,metrics:p,routes:f}}var kn={seed:1,text:null,connector:null,groupID:null,points:null,path:null,subpaths:null,evenOdd:null,rotation:null,link:null,url:null,anchor:null,click:null,hover:null,when:null,overrides:null,symbol:null,playback:null,offset:null,args:null,image:null,reveal:null};function Mn(e,t,n,r="solid",o=null){return{stroke:{...e},fill:{...t},fillStyle:r,strokeWidth:n,dash:"solid",roughness:0,bowing:1,fontSize:18,font:null,gridSize:null,opacity:o,dashOffset:null,textColor:null}}function Se(e,t,n,r,o,s){return{...kn,id:e,kind:"ellipse",layerID:s,x:t,y:n,width:r,height:r,style:Mn(o,o,1.5)}}function dr(e,t){let n=new Map;for(let o of t.elements)o.anchor!==null&&!n.has(o.anchor)&&n.set(o.anchor,o.id);let r=/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/;return(o,s)=>{let i=o.target===""?s:n.get(o.target)??(r.test(o.target)?o.target.toUpperCase():null);return i===null?null:bn(e,o.metric,i)}}function Pn(e,t,n,r,o=1/0,s={}){let i=dr(t,r),l=[],a={};for(let c of e){let u=[];n!==null&&c.overrides&&c.overrides.forEach((y,O)=>{he(y.when)&&Wt(y.when,n,G=>i(G,c.id))&&u.push(O)});let p=n===null?null:c.gauge;if(!p){l.push({applied:u,gauge:null});continue}let f=bn(t,p.metric,p.of),m=s[gn(c.id)];if(f!==null&&m!==void 0&&p.metric!=="depth"&&p.metric!=="inFlight"&&o<xn){let y=Math.max(0,o/xn),O=y*y*(3-2*y);f=m+(f-m)*O}f!==null&&(a[gn(c.id)]=f),l.push({applied:u,gauge:{value:f}})}return{plan:l,readings:a}}var gn=e=>"gauge|"+e,xn=1,Ct=e=>{let t=parseInt(e.slice(1),16);return{r:(t>>16&255)/255,g:(t>>8&255)/255,b:(t&255)/255,a:1}},pr=Ct("#16a34a"),yr=Ct("#d97706"),gr=Ct("#dc2626"),xr=Ct("#2f6fdf"),Ie=Ct("#e5e7eb"),br=Ct("#9ca3af");function wr(e,t){if(t===null||!Number.isFinite(t))return"\u2013";switch(e){case"load":case"backup":return Te(t*100,0)+"%";case"transit":case"delay":return Te(t,Math.abs(t)>=10?1:2)+"s";default:return Te(t,Math.abs(t)>=100?0:Math.abs(t)>=10?1:2)}}function Te(e,t){let n=t===0?1:t===1?10:100,r=Math.floor(Math.abs(e)*n+.5);if(!(r<1e15))return e<0?"-\u221E":"\u221E";let o=Math.trunc(r/n),s=r-o*n,i=String(o);if(t>0&&s>0){let l=String(s);for(;l.length<t;)l="0"+l;for(;l.endsWith("0");)l=l.slice(0,-1);i+="."+l}return(e<0&&r>0?"-":"")+i}function En(e,t,n,r,o){let s=r.elements.find(x=>x.id===t.of),i=t.max??(t.metric==="load"?1:s?.capacity??n??1),l=n===null?0:i>0?Math.min(Math.max(n/i,0),1):0,a=t.warn??(t.metric==="load"?.7:null),c=t.alarm??(t.metric==="load"?.9:null),u=a===null&&c===null?xr:pr;n!==null&&a!==null&&n>=a&&(u=yr),n!==null&&c!==null&&n>=c&&(u=gr),n===null&&(u=br);let p=t.label;if(p===null){let x=s?s.text!==null?s.text.split(`
4
4
  `)[0]:s.anchor:null;p=`${t.metric} ${x??(o.some(P=>P.id===t.of)?"flow":"?")}`}let f=t.style??"number",m=Math.max(e.width,1),y=Math.max(e.height,1),O=(x,P)=>[x.x/m,x.y/y,(x.x+(P.x-x.x)/3)/m,(x.y+(P.y-x.y)/3)/y,(x.x+2*(P.x-x.x)/3)/m,(x.y+2*(P.y-x.y)/3)/y,P.x/m,P.y/y],G=(x,P,U,B)=>{let W=[{x,y:P},{x:x+U,y:P},{x:x+U,y:P+B},{x,y:P+B}],ht=O(W[0],W[1]);for(let Q=1;Q<4;Q++)ht=ht.concat(O(W[Q],W[(Q+1)%4]).slice(2));return{closed:!0,coords:ht}},X=(x,P,U,B)=>{let W=Math.max(1,Math.ceil(Math.abs(B-U)/(Math.PI/2)-1e-9)),ht=(B-U)/W,Q=4/3*Math.tan(ht/4),wt=h=>({x:x.x+P*Math.cos(h),y:x.y+P*Math.sin(h)}),k=wt(U),v=[k.x/m,k.y/y];for(let h=0;h<W;h++){let d=U+h*ht,E=d+ht,R=wt(d),b=wt(E),S={x:R.x-Q*P*Math.sin(d),y:R.y+Q*P*Math.cos(d)},z={x:b.x+Q*P*Math.sin(E),y:b.y-Q*P*Math.cos(E)};v.push(S.x/m,S.y/y,z.x/m,z.y/y,b.x/m,b.y/y)}return{closed:!1,coords:v}},q=(x,P,U,B,W)=>({...kn,id:Bt(e.id,-(2**38)-x),kind:"path",layerID:e.layerID,x:e.x,y:e.y,width:e.width,height:e.height,style:Mn(U,B??{r:0,g:0,b:0,a:0},W,"solid",e.style.opacity),subpaths:P}),it={...e,gauge:null,kind:"path",subpaths:[G(0,0,m,y)],text:p+`
package/dist/dottie.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! dottie.js 0.11.0 | Apache-2.0 | https://github.com/phin-tech/dottie */
1
+ /*! dottie.js 0.11.1 | Apache-2.0 | https://github.com/phin-tech/dottie */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
4
4
  var __publicField = (obj, key, value2) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2);
@@ -3965,7 +3965,7 @@ function sceneNamed(name, markers) {
3965
3965
  const exact = markers.findIndex((m) => m.name === name);
3966
3966
  return exact >= 0 ? exact : markers.findIndex((m) => m.name.toLowerCase() === name.toLowerCase());
3967
3967
  }
3968
- function clickTargets(page, file) {
3968
+ function clickTargets(page, file, hrefs) {
3969
3969
  const markers = page.timeline?.markers ?? [];
3970
3970
  const out = /* @__PURE__ */ new Map();
3971
3971
  let pageOf = null;
@@ -4001,11 +4001,19 @@ function clickTargets(page, file) {
4001
4001
  });
4002
4002
  }
4003
4003
  const target = pageOf.get(e.link);
4004
- if (target !== void 0 && file.pages[target] !== page) out.set(e.id, { page: target });
4004
+ if (target !== void 0 && file.pages[target] !== page) {
4005
+ out.set(e.id, { page: target });
4006
+ continue;
4007
+ }
4005
4008
  }
4009
+ const href = e.link && hrefs && Object.prototype.hasOwnProperty.call(hrefs, e.link) ? pageHref(hrefs[e.link]) : null;
4010
+ if (href) out.set(e.id, { href });
4006
4011
  }
4007
4012
  return out;
4008
4013
  }
4014
+ function pageHref(href) {
4015
+ return typeof href === "string" && /^[A-Za-z0-9._~%/-]+\.html(#[^\s:]*)?$/.test(href) && !href.startsWith("//") ? href : null;
4016
+ }
4009
4017
  function hoveredElement(e) {
4010
4018
  const h = e.hover;
4011
4019
  if (!h) return e;
@@ -5063,7 +5071,8 @@ output { font-variant-numeric: tabular-nums; min-width: 4.5em; text-align: right
5063
5071
  .error { padding: 16px; font-family: ui-monospace, Menlo, monospace; white-space: pre-wrap; }
5064
5072
  ${CLICK_STYLE}`;
5065
5073
  var Playback = class {
5066
- /** `file` is the drawing `page` belongs to, so links to its other pages are clickable. */
5074
+ /** `file` is the drawing `page` belongs to, so links to its other pages are clickable; `hrefs`, the web pages that
5075
+ * show the elements links point at, for pages that aren't in it (clickTargets). */
5067
5076
  constructor(page, into, options = {}) {
5068
5077
  __publicField(this, "page");
5069
5078
  __publicField(this, "plan");
@@ -5105,7 +5114,7 @@ var Playback = class {
5105
5114
  this.page = options.clean ? cleanCopy(page) : page;
5106
5115
  addFonts(usedFonts(this.page));
5107
5116
  this.plan = plan(this.page);
5108
- this.clicks = clickTargets(page, options.file);
5117
+ this.clicks = clickTargets(page, options.file, options.hrefs);
5109
5118
  const table = symbolTable(this.page);
5110
5119
  for (const e of this.page.elements) {
5111
5120
  const s = e.kind === "symbol" && e.symbol !== null ? table.get(e.symbol) : void 0;
@@ -5374,6 +5383,11 @@ var DottiePlayer = class extends ElementBase {
5374
5383
  __publicField(this, "stillTime", null);
5375
5384
  __publicField(this, "visible", true);
5376
5385
  __publicField(this, "observer", null);
5386
+ /** The page last shown, so `page` fires only when it changes. */
5387
+ __publicField(this, "shownPage", null);
5388
+ __publicField(this, "onPopState", () => {
5389
+ if (this.file) this.mount();
5390
+ });
5377
5391
  /** Runs handler `handler` from the page's logic for a click on `id` (DottieDocument.clicked). Clicks take turns, so
5378
5392
  * each handler sees the state the one before left. */
5379
5393
  __publicField(this, "logicQueue", Promise.resolve());
@@ -5422,15 +5436,21 @@ var DottiePlayer = class extends ElementBase {
5422
5436
  });
5423
5437
  this.observer.observe(this);
5424
5438
  }
5439
+ if (this.hasAttribute("history")) window.addEventListener("popstate", this.onPopState);
5425
5440
  void this.load();
5426
5441
  }
5427
5442
  disconnectedCallback() {
5428
5443
  cancelAnimationFrame(this.raf);
5429
5444
  this.raf = 0;
5430
5445
  this.observer?.disconnect();
5446
+ window.removeEventListener("popstate", this.onPopState);
5431
5447
  }
5432
5448
  attributeChangedCallback(name, old, value2) {
5433
5449
  if (old === value2 || !this.isConnected) return;
5450
+ if (name === "history") {
5451
+ if (value2 === null) window.removeEventListener("popstate", this.onPopState);
5452
+ else window.addEventListener("popstate", this.onPopState);
5453
+ }
5434
5454
  if (name === "src") void this.load();
5435
5455
  else if (name === "label") this.stage.setAttribute("aria-label", value2 ?? "");
5436
5456
  else if (this.file) this.mount();
@@ -5479,6 +5499,7 @@ var DottiePlayer = class extends ElementBase {
5479
5499
  }
5480
5500
  showFile(file) {
5481
5501
  this.file = file;
5502
+ this.shownPage = null;
5482
5503
  for (const w of file.warnings) console.warn(`dottie-player: ${w}`);
5483
5504
  this.mount(() => this.dispatchEvent(new CustomEvent("load", { detail: { file } })));
5484
5505
  }
@@ -5486,7 +5507,7 @@ var DottiePlayer = class extends ElementBase {
5486
5507
  * showing stays until it is ready; a newer mount, file or failed load in the meantime wins. */
5487
5508
  mount(mounted) {
5488
5509
  const file = this.file;
5489
- const page = file.pages[pageIndex(file, this.getAttribute("page"))];
5510
+ const page = file.pages[this.addressedPage(file) ?? pageIndex(file, this.getAttribute("page"))];
5490
5511
  const clean = this.hasAttribute("clean");
5491
5512
  const token = ++this.mountToken;
5492
5513
  const shown = clean ? cleanCopy(page) : page;
@@ -5501,10 +5522,41 @@ var DottiePlayer = class extends ElementBase {
5501
5522
  mounted?.();
5502
5523
  });
5503
5524
  }
5525
+ /** With `history`, the page the address names after its `#` (by name, any case), if it names one. */
5526
+ addressedPage(file) {
5527
+ if (!this.hasAttribute("history") || typeof location === "undefined" || location.hash.length < 2) return null;
5528
+ let name;
5529
+ try {
5530
+ name = decodeURIComponent(location.hash.slice(1));
5531
+ } catch {
5532
+ return null;
5533
+ }
5534
+ const i = file.pages.findIndex((p) => p.name.toLowerCase() === name.toLowerCase());
5535
+ return i >= 0 ? i : null;
5536
+ }
5537
+ /** The `links` attribute read: element id to web page, the pages that can't be named left out. */
5538
+ hrefs() {
5539
+ const raw = this.getAttribute("links");
5540
+ if (!raw) return void 0;
5541
+ let v;
5542
+ try {
5543
+ v = JSON.parse(raw);
5544
+ } catch {
5545
+ console.warn("dottie-player: links isn't JSON");
5546
+ return void 0;
5547
+ }
5548
+ if (v === null || typeof v !== "object" || Array.isArray(v)) return void 0;
5549
+ return v;
5550
+ }
5504
5551
  mountPage(file, page, clean) {
5505
- const p = new Playback(page, this.stage, { clean, file });
5552
+ const p = new Playback(page, this.stage, { clean, file, hrefs: this.hrefs() });
5506
5553
  p.still = this.hasAttribute("at");
5507
5554
  this.playback = p;
5555
+ if (this.shownPage !== page) {
5556
+ const first = this.shownPage === null;
5557
+ this.shownPage = page;
5558
+ queueMicrotask(() => this.dispatchEvent(new CustomEvent("page", { detail: { index: file.pages.indexOf(page), name: page.name, first } })));
5559
+ }
5508
5560
  this.style.setProperty("--dottie-page", color(p.background));
5509
5561
  this.style.setProperty("--dottie-ink", color(p.ink));
5510
5562
  this.style.colorScheme = luminance(p.background) < 0.5 ? "dark" : "light";
@@ -5616,7 +5668,15 @@ var DottiePlayer = class extends ElementBase {
5616
5668
  if ("url" in click) {
5617
5669
  if (/^(https?:|mailto:)/i.test(click.url)) window.open(click.url, "_blank", "noopener");
5618
5670
  } else if ("page" in click) {
5619
- this.setAttribute("page", String(click.page + 1));
5671
+ const target = this.file?.pages[click.page];
5672
+ if (this.hasAttribute("history") && target) {
5673
+ history.pushState(null, "", "#" + encodeURIComponent(target.name));
5674
+ this.mount();
5675
+ } else {
5676
+ this.setAttribute("page", String(click.page + 1));
5677
+ }
5678
+ } else if ("href" in click) {
5679
+ location.assign(click.href);
5620
5680
  } else if (click.scene >= 0 && click.scene < p.scenes.length) {
5621
5681
  if (reduced || this.hasAttribute("at") || p.frameCount < 2) {
5622
5682
  this.setPlaying(false);
@@ -5762,7 +5822,7 @@ var DottiePlayer = class extends ElementBase {
5762
5822
  if (handled) e.preventDefault();
5763
5823
  }
5764
5824
  };
5765
- __publicField(DottiePlayer, "observedAttributes", ["src", "page", "at", "clean", "no-controls", "label", "allow-logic"]);
5825
+ __publicField(DottiePlayer, "observedAttributes", ["src", "page", "at", "clean", "no-controls", "label", "allow-logic", "history", "links"]);
5766
5826
  function clickable(target) {
5767
5827
  const el = target;
5768
5828
  return el && typeof el.closest === "function" ? el.closest(".dottie-a") : null;
@@ -5867,7 +5927,7 @@ function render(source, options = {}) {
5867
5927
  function isFile(v) {
5868
5928
  return typeof v === "object" && v !== null && Array.isArray(v.pages) && Array.isArray(v.warnings);
5869
5929
  }
5870
- var VERSION = "0.11.0";
5930
+ var VERSION = "0.11.1";
5871
5931
  export {
5872
5932
  BOIL_DRAWINGS,
5873
5933
  BUNDLED_FONTS,
@@ -1,13 +1,16 @@
1
1
  import { type ClickValue, type DottieFile, type Element, type Marker, type Page } from "./model.ts";
2
2
  /** Jump to scene `scene` (an index into the page's markers) and play on to the next; open `url` in a new tab; or,
3
3
  * in <dottie-player> only, show page `page` (an index into the file's pages), where the element's link points. Any
4
- * of them may first `set` and `toggle` page variables (ClickAction.set, .toggle), and a click may do only that. */
4
+ * of them may first `set` and `toggle` page variables (ClickAction.set, .toggle), and a click may do only that. Or go to
5
+ * `href`, the exported web page that holds the page a `link` points at, when a drawing is exported one page per file. */
5
6
  export type Click = ({
6
7
  scene: number;
7
8
  } | {
8
9
  url: string;
9
10
  } | {
10
11
  page: number;
12
+ } | {
13
+ href: string;
11
14
  } | {
12
15
  state: true;
13
16
  }) & {
@@ -20,8 +23,12 @@ export type Click = ({
20
23
  export declare function sceneNamed(name: string, markers: Marker[]): number;
21
24
  /** The page's clickable elements and what each click does, by element id. A scene named by no marker, or a link
22
25
  * that isn't allowed, makes nothing clickable; an element with no `click` opens its `url` when that is a web link. Given the whole file, an element whose `link` points at an element on
23
- * another page shows that page (the HTML export holds one page, so it can't). */
24
- export declare function clickTargets(page: Page, file?: DottieFile): Map<string, Click>;
26
+ * another page shows that page. `hrefs` names, by the id of an element a link points at, the web page that shows it
27
+ * (`<dottie-player links>`): a page exported on its own reaches the others through them. */
28
+ export declare function clickTargets(page: Page, file?: DottieFile, hrefs?: Record<string, string>): Map<string, Click>;
29
+ /** `href` if it is a page beside this one (a relative `.html` path, maybe with a `#fragment`), else null: no scheme,
30
+ * so never `javascript:` or another site. */
31
+ export declare function pageHref(href: unknown): string | null;
25
32
  /** `e` as it looks hovered (HoverLook.apply). */
26
33
  export declare function hoveredElement(e: Element): Element;
27
34
  /** `page` with `ids` drawn as they look hovered. */
@@ -2,8 +2,12 @@ import type { Face } from "./metrics.ts";
2
2
  /** What follows the runtime; DOTTIE_DATA, DOTTIE_OPTIONS and DOTTIE_FONTS are replaced with JSON. Plain ES5, unminified. */
3
3
  export declare const LOADER = ";(function () {\n var data = DOTTIE_DATA, options = DOTTIE_OPTIONS, fonts = DOTTIE_FONTS;\n var script = document.currentScript;\n if (window.Dottie.addFonts) window.Dottie.addFonts(Object.keys(fonts), fonts);\n function attr(el, name, value) { el.setAttribute(name.replace(/[A-Z]/g, function (c) { return \"-\" + c.toLowerCase(); }), value); }\n function mount() {\n var player = document.createElement(\"dottie-player\"), k;\n for (k in options) attr(player, k, options[k]);\n if (script) for (k in script.dataset) if (k !== \"target\") attr(player, k, script.dataset[k]);\n var target = script && script.dataset.target ? document.querySelector(script.dataset.target) : null;\n if (target) target.appendChild(player);\n else if (script && script.parentNode && script.parentNode !== document.head) script.parentNode.insertBefore(player, script);\n else document.body.appendChild(player);\n player.setFile(window.Dottie.parseDottie(data));\n }\n if (document.readyState === \"loading\" && (!script || script.parentNode === document.head || script.dataset.target)) {\n document.addEventListener(\"DOMContentLoaded\", mount);\n } else {\n mount();\n }\n})();\n";
4
4
  export interface CompileOptions {
5
- /** Page name or 1-based number; only that page goes in. The first page by default. */
5
+ /** Page name or 1-based number; only that page goes in. The first page by default. With `allPages`, the page to
6
+ * start on. */
6
7
  page?: string | number;
8
+ /** Every page goes in, and links between them work: each page shown gets its own address (`#` and its name), so
9
+ * the browser's Back and Forward go between them (the player's `history`). */
10
+ allPages?: boolean;
7
11
  /** Show this moment (seconds) as a still. */
8
12
  at?: number;
9
13
  clean?: boolean;
@@ -20,4 +20,4 @@ export interface RenderOptions {
20
20
  /** One page of a drawing as an SVG document, as Dottie's own SVG export draws it. */
21
21
  export declare function render(source: string | DottieFile | unknown, options?: RenderOptions): string;
22
22
  /** The library's version. */
23
- export declare const VERSION = "0.11.0";
23
+ export declare const VERSION = "0.11.1";
@@ -49,10 +49,12 @@ export declare class Playback {
49
49
  private order;
50
50
  frame: number;
51
51
  onFrame: ((frame: number) => void) | null;
52
- /** `file` is the drawing `page` belongs to, so links to its other pages are clickable. */
52
+ /** `file` is the drawing `page` belongs to, so links to its other pages are clickable; `hrefs`, the web pages that
53
+ * show the elements links point at, for pages that aren't in it (clickTargets). */
53
54
  constructor(page: Page, into: Element, options?: {
54
55
  clean?: boolean;
55
56
  file?: DottieFile;
57
+ hrefs?: Record<string, string>;
56
58
  });
57
59
  get frameCount(): number;
58
60
  get posterFrame(): number;
@@ -108,6 +110,9 @@ export declare class DottiePlayer extends ElementBase {
108
110
  private stillTime;
109
111
  private visible;
110
112
  private observer;
113
+ /** The page last shown, so `page` fires only when it changes. */
114
+ private shownPage;
115
+ private readonly onPopState;
111
116
  constructor();
112
117
  connectedCallback(): void;
113
118
  disconnectedCallback(): void;
@@ -120,6 +125,10 @@ export declare class DottiePlayer extends ElementBase {
120
125
  /** Shows the file's page; then `mounted`. A big animation is planned in a worker first (planner.ts), and what was
121
126
  * showing stays until it is ready; a newer mount, file or failed load in the meantime wins. */
122
127
  private mount;
128
+ /** With `history`, the page the address names after its `#` (by name, any case), if it names one. */
129
+ private addressedPage;
130
+ /** The `links` attribute read: element id to web page, the pages that can't be named left out. */
131
+ private hrefs;
123
132
  private mountPage;
124
133
  get paused(): boolean;
125
134
  /** The moment shown: a still's own time (its `at`, or the poster), else the current frame's. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phin-tech/dottie",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "Render, play and compile Dottie (.dottie) drawings and animations in the browser",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",