anniedrawing 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +4 -0
  3. package/dist/agent/index.js +1 -1
  4. package/dist/agent/index.js.map +1 -1
  5. package/dist/agent/toolDefs.d.ts +1 -0
  6. package/dist/board.d.ts +7 -1
  7. package/dist/core/index.js +1 -1
  8. package/dist/core/types.d.ts +12 -0
  9. package/dist/docs/agents-repository.md +1 -1
  10. package/dist/docs/agents.md +4 -0
  11. package/dist/docs/api.md +4 -0
  12. package/dist/docs/board-js.md +4 -0
  13. package/dist/docs/decisions.md +6 -0
  14. package/dist/docs/llms-full.txt +4 -0
  15. package/dist/docs/llms.txt +4 -0
  16. package/dist/fellow.d.ts +2 -2
  17. package/dist/fellow.js +1 -1
  18. package/dist/fellow.js.map +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/shared/board-p60lv7As.js +2 -0
  21. package/dist/shared/board-p60lv7As.js.map +1 -0
  22. package/dist/shared/{cards-DWgSVE54.js → cards-DF0uI4-I.js} +2 -2
  23. package/dist/shared/{cards-DWgSVE54.js.map → cards-DF0uI4-I.js.map} +1 -1
  24. package/dist/shared/{paste-C22i8o-g.js → paste-B8nZA2Gh.js} +2 -2
  25. package/dist/shared/{paste-C22i8o-g.js.map → paste-B8nZA2Gh.js.map} +1 -1
  26. package/dist/shared/{picker-Dv_i4iNP.js → picker-DZpEpkED.js} +2 -2
  27. package/dist/shared/picker-DZpEpkED.js.map +1 -0
  28. package/dist/shared/{ui-DEBI1jv_.js → ui-DWQtW0zJ.js} +2 -2
  29. package/dist/shared/{ui-DEBI1jv_.js.map → ui-DWQtW0zJ.js.map} +1 -1
  30. package/dist/shared/{urlPaste-DN4JtgeB.js → urlPaste-Oc4kZ0P7.js} +2 -2
  31. package/dist/shared/{urlPaste-DN4JtgeB.js.map → urlPaste-Oc4kZ0P7.js.map} +1 -1
  32. package/dist/ui/index.js +1 -1
  33. package/dist/ui/version.d.ts +1 -1
  34. package/llms-full.txt +4 -0
  35. package/llms.txt +4 -0
  36. package/package.json +1 -1
  37. package/dist/shared/board-DV5lzxNR.js +0 -2
  38. package/dist/shared/board-DV5lzxNR.js.map +0 -1
  39. package/dist/shared/picker-Dv_i4iNP.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ui-DEBI1jv_.js","names":[],"sources":["../../node_modules/perfect-freehand/dist/esm/index.mjs","../../src/stage/paint.ts","../../src/porter/json.ts","../../src/ui/icons.ts","../../src/ui/version.ts","../../src/ui/index.ts"],"sourcesContent":["const{PI:e}=Math,t=e+1e-4,n=.5,r=[1,1];function i(e,t,n,r=e=>e){return e*r(.5-t*(.5-n))}const{min:a}=Math;function o(e,t,n){let r=a(1,t/n);return a(1,e+(a(1,1-r)-e)*(r*.275))}function s(e){return[-e[0],-e[1]]}function c(e,t){return[e[0]+t[0],e[1]+t[1]]}function l(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function u(e,t){return[e[0]-t[0],e[1]-t[1]]}function d(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function f(e,t){return[e[0]*t,e[1]*t]}function p(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function m(e,t){return[e[0]/t,e[1]/t]}function h(e){return[e[1],-e[0]]}function g(e,t){let n=t[0];return e[0]=t[1],e[1]=-n,e}function ee(e,t){return e[0]*t[0]+e[1]*t[1]}function _(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return Math.hypot(e[0],e[1])}function y(e,t){let n=e[0]-t[0],r=e[1]-t[1];return n*n+r*r}function b(e){return m(e,v(e))}function x(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function S(e,t,n){let r=Math.sin(n),i=Math.cos(n),a=e[0]-t[0],o=e[1]-t[1],s=a*i-o*r,c=a*r+o*i;return[s+t[0],c+t[1]]}function C(e,t,n,r){let i=Math.sin(r),a=Math.cos(r),o=t[0]-n[0],s=t[1]-n[1],c=o*a-s*i,l=o*i+s*a;return e[0]=c+n[0],e[1]=l+n[1],e}function w(e,t,n){return c(e,f(u(t,e),n))}function te(e,t,n,r){let i=n[0]-t[0],a=n[1]-t[1];return e[0]=t[0]+i*r,e[1]=t[1]+a*r,e}function T(e,t,n){return c(e,f(t,n))}const E=[0,0],D=[0,0],O=[0,0];function k(e,n){let r=T(e,b(h(u(e,c(e,[1,1])))),-n),i=[],a=1/13;for(let n=a;n<=1;n+=a)i.push(S(r,e,t*2*n));return i}function A(e,n,r){let i=[],a=1/r;for(let r=a;r<=1;r+=a)i.push(S(n,e,t*r));return i}function j(e,t,n){let r=u(t,n),i=f(r,.5),a=f(r,.51);return[u(e,i),u(e,a),c(e,a),c(e,i)]}function M(e,n,r,i){let a=[],o=T(e,n,r),s=1/i;for(let n=s;n<1;n+=s)a.push(S(o,e,t*3*n));return a}function ne(e,t,n){return[c(e,f(t,n)),c(e,f(t,n*.99)),u(e,f(t,n*.99)),u(e,f(t,n))]}function N(e,t,n){return e===!1||e===void 0?0:e===!0?Math.max(t,n):e}function re(e,t,n){return e.slice(0,10).reduce((e,r)=>{let i=r.pressure;return t&&(i=o(e,r.distance,n)),(e+i)/2},e[0].pressure)}function P(e,n={}){let{size:r=16,smoothing:a=.5,thinning:f=.5,simulatePressure:m=!0,easing:_=e=>e,start:v={},end:b={},last:x=!1}=n,{cap:S=!0,easing:w=e=>e*(2-e)}=v,{cap:T=!0,easing:P=e=>--e*e*e+1}=b;if(e.length===0||r<=0)return[];let F=e[e.length-1].runningLength,I=N(v.taper,r,F),L=N(b.taper,r,F),R=(r*a)**2,z=[],B=[],V=re(e,m,r),H=i(r,f,e[e.length-1].pressure,_),U,W=e[0].vector,G=e[0].point,K=G,q=G,J=K,Y=!1;for(let n=0;n<e.length;n++){let{pressure:a}=e[n],{point:s,vector:h,distance:v,runningLength:b}=e[n],x=n===e.length-1;if(!x&&F-b<3)continue;f?(m&&(a=o(V,v,r)),H=i(r,f,a,_)):H=r/2,U===void 0&&(U=H);let S=b<I?w(b/I):1,T=F-b<L?P((F-b)/L):1;H=Math.max(.01,H*Math.min(S,T));let k=(x?e[n]:e[n+1]).vector,A=x?1:ee(h,k),j=ee(h,W)<0&&!Y,M=A!==null&&A<0;if(j||M){g(E,W),p(E,E,H);for(let e=0;e<=1;e+=.07692307692307693)d(D,s,E),C(D,D,s,t*e),q=[D[0],D[1]],z.push(q),l(O,s,E),C(O,O,s,t*-e),J=[O[0],O[1]],B.push(J);G=q,K=J,M&&(Y=!0);continue}if(Y=!1,x){g(E,h),p(E,E,H),z.push(u(s,E)),B.push(c(s,E));continue}te(E,k,h,A),g(E,E),p(E,E,H),d(D,s,E),q=[D[0],D[1]],(n<=1||y(G,q)>R)&&(z.push(q),G=q),l(O,s,E),J=[O[0],O[1]],(n<=1||y(K,J)>R)&&(B.push(J),K=J),V=a,W=h}let X=[e[0].point[0],e[0].point[1]],Z=e.length>1?[e[e.length-1].point[0],e[e.length-1].point[1]]:c(e[0].point,[1,1]),Q=[],$=[];if(e.length===1){if(!(I||L)||x)return k(X,U||H)}else{I||L&&e.length===1||(S?Q.push(...A(X,B[0],13)):Q.push(...j(X,z[0],B[0])));let t=h(s(e[e.length-1].vector));L||I&&e.length===1?$.push(Z):T?$.push(...M(Z,t,H,29)):$.push(...ne(Z,t,H))}return z.concat($,B.reverse(),Q)}const F=[0,0];function I(e){return e!=null&&e>=0}function L(e,t={}){let{streamline:i=.5,size:a=16,last:o=!1}=t;if(e.length===0)return[];let s=.15+(1-i)*.85,l=Array.isArray(e[0])?e:e.map(({x:e,y:t,pressure:r=n})=>[e,t,r]);if(l.length===2){let e=l[1];l=l.slice(0,-1);for(let t=1;t<5;t++)l.push(w(l[0],e,t/4))}l.length===1&&(l=[...l,[...c(l[0],r),...l[0].slice(2)]]);let u=[{point:[l[0][0],l[0][1]],pressure:I(l[0][2])?l[0][2]:.25,vector:[...r],distance:0,runningLength:0}],f=!1,p=0,m=u[0],h=l.length-1;for(let e=1;e<l.length;e++){let t=o&&e===h?[l[e][0],l[e][1]]:w(m.point,l[e],s);if(_(m.point,t))continue;let r=x(t,m.point);if(p+=r,e<h&&!f){if(p<a)continue;f=!0}d(F,m.point,t),m={point:t,pressure:I(l[e][2])?l[e][2]:n,vector:b(F),distance:r,runningLength:p},u.push(m)}return u[0].vector=u[1]?.vector||[0,0],u}function R(e,t={}){return P(L(e,t),t)}var z=R;export{z as default,R as getStroke,P as getStrokeOutlinePoints,L as getStrokePoints};\n//# sourceMappingURL=index.mjs.map","import { getStroke } from 'perfect-freehand';\nimport { CARD_CORNER } from '../core/defaults';\nimport type { Item, ItemText, Point, Style } from '../core/types';\n\nexport const SVG_NS = 'http://www.w3.org/2000/svg';\nexport const fonts = {\n sans: 'Nunito Variable, Nunito, ui-rounded, system-ui, sans-serif',\n serif: 'Georgia, serif',\n mono: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n hand: 'Comic Sans MS, Chalkboard SE, cursive',\n};\nexport const DEFAULT_FONT = 'hand' satisfies keyof typeof fonts;\nexport function fontFamily(font?: ItemText['font']): string {\n return fonts[font ?? DEFAULT_FONT];\n}\nconst light: Record<string, string> = {\n ink: '#103639',\n slate: '#606062',\n coral: '#FF9302',\n amber: '#FFC68A',\n moss: '#AAF1AC',\n teal: '#05D9AB',\n sky: '#92CAFF',\n violet: '#8F93F9',\n rose: '#F89B97',\n paper: '#FFFFFF',\n};\nconst dark: Record<string, string> = {\n ...light,\n ink: '#E9F7F3',\n slate: '#B6C5C1',\n paper: '#173D40',\n};\nexport function color(value = 'ink', theme: 'light' | 'dark' = 'light'): string {\n return (theme === 'dark' ? dark : light)[value] ?? value;\n}\nfunction rgb(value: string): number[] | undefined {\n const named: Record<string, string> = {\n black: '#000000',\n white: '#ffffff',\n red: '#ff0000',\n blue: '#0000ff',\n green: '#008000',\n yellow: '#ffff00',\n transparent: '#00000000',\n };\n value = named[value.toLowerCase()] ?? value;\n if (/^#[\\da-f]{3,4}$/i.test(value))\n value = `#${[...value.slice(1)].map((channel) => channel + channel).join('')}`;\n if (/^#[\\da-f]{6}([\\da-f]{2})?$/i.test(value))\n return [1, 3, 5]\n .map((index) => parseInt(value.slice(index, index + 2), 16))\n .concat(value.length === 9 ? parseInt(value.slice(7, 9), 16) / 255 : 1);\n if (!/^rgba?\\(/i.test(value)) return undefined;\n const channels = value.match(/[\\d.]+%?/g);\n if (!channels || channels.length < 3) return undefined;\n return channels\n .slice(0, 3)\n .map((channel) => parseFloat(channel) * (channel.endsWith('%') ? 2.55 : 1))\n .concat(\n channels[3] === undefined\n ? 1\n : parseFloat(channels[3]) / (channels[3].endsWith('%') ? 100 : 1),\n );\n}\nfunction luminance(channels: number[]): number {\n return channels\n .slice(0, 3)\n .map((channel) => {\n const value = channel / 255;\n return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;\n })\n .reduce((sum, channel, index) => sum + channel * [0.2126, 0.7152, 0.0722][index], 0);\n}\n/** Preserve explicit text colors and keep labels legible on opaque shape fills. */\nexport function labelColor(item: Item, theme: 'light' | 'dark'): string {\n if (item.kind === 'text') return color(item.style?.stroke ?? 'ink', theme);\n const ink = color('ink', theme),\n style = styleFor(item, theme);\n if (['connector', 'line'].includes(item.kind) || style.fillMode !== 'solid') return ink;\n const fill = rgb(style.fill);\n if (!fill) return ink;\n const paper = rgb(color('paper', theme))!;\n const background = luminance(\n fill.slice(0, 3).map((channel, index) => channel * fill[3] + paper[index] * (1 - fill[3])),\n );\n const contrast = (value: string) => {\n const foreground = luminance(rgb(value)!);\n return (Math.max(background, foreground) + 0.05) / (Math.min(background, foreground) + 0.05);\n };\n for (const candidate of [ink, color('ink', theme === 'dark' ? 'light' : 'dark')])\n if (contrast(candidate) >= 4.5) return candidate;\n return contrast('#0F0B0A') >= contrast('#FFFFFF') ? '#0F0B0A' : '#FFFFFF';\n}\nexport function fontSize(text?: ItemText): number {\n return typeof text?.size === 'number'\n ? text.size\n : { s: 14, m: 18, l: 26, xl: 36 }[text?.size ?? 'm'];\n}\nexport function esc(value: unknown): string {\n return String(value ?? '').replace(\n /[&<>\"']/g,\n (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char]!,\n );\n}\nexport function round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\nexport function pathFromPoints(points: Point[], closed = false): string {\n return (\n points\n .map((point, index) => `${index ? 'L' : 'M'}${round(point.x)},${round(point.y)}`)\n .join(' ') + (closed ? ' Z' : '')\n );\n}\nexport function freehandPath(item: Item): string {\n const points = item.points ?? [];\n if (!points.length) return '';\n if (item.closed)\n return pathFromPoints(\n points.map(([x, y]) => ({ x, y })),\n true,\n );\n const stroke = getStroke(\n points.map(([x, y, pressure]) => ({ x, y, pressure })),\n {\n size: (item.style?.strokeWidth ?? 2) * 2.2,\n thinning: 0.45,\n smoothing: 0.6,\n streamline: 0.45,\n simulatePressure: points.every((point) => point[2] === undefined),\n last: true,\n },\n );\n if (!stroke.length) return '';\n return `M${stroke.map((point) => `${round(point[0])},${round(point[1])}`).join(' L')} Z`;\n}\nexport function shapePath(item: Item): string {\n const w = item.w,\n h = item.h;\n if (item.kind === 'ellipse')\n return `M${w},${h / 2}a${w / 2},${h / 2} 0 1 0 ${-w},0a${w / 2},${h / 2} 0 1 0 ${w},0Z`;\n if (item.kind === 'diamond') return `M${w / 2},0L${w},${h / 2}L${w / 2},${h}L0,${h / 2}Z`;\n if (item.kind === 'line')\n return pathFromPoints(\n (\n item.points ?? [\n [0, 0],\n [w, h],\n ]\n ).map(([x, y]) => ({ x, y })),\n );\n if (item.kind === 'path') return freehandPath(item);\n const corner = Math.max(0, Math.min(item.style?.corner ?? CARD_CORNER, w / 2, h / 2));\n return `M${corner},0H${w - corner}Q${w},0 ${w},${corner}V${h - corner}Q${w},${h} ${w - corner},${h}H${corner}Q0,${h} 0,${h - corner}V${corner}Q0,0 ${corner},0Z`;\n}\nexport function styleFor(item: Item, theme: 'light' | 'dark'): Required<Style> {\n const fill = item.style?.fill ?? (item.kind === 'note' ? 'moss' : 'none');\n return {\n stroke: color(item.style?.stroke ?? 'ink', theme),\n strokeWidth: item.style?.strokeWidth ?? (item.kind === 'note' ? 0 : 2),\n dash: item.style?.dash ?? 'solid',\n fill: color(fill, theme),\n fillMode: item.style?.fillMode ?? 'solid',\n corner: item.style?.corner ?? CARD_CORNER,\n opacity: item.style?.opacity ?? 1,\n };\n}\nexport function shapeMarkup(\n item: Item,\n theme: 'light' | 'dark',\n uid: string,\n path = shapePath(item),\n): string {\n const style = styleFor(item, theme);\n const dash = style.dash === 'dashed' ? '8 6' : style.dash === 'dotted' ? '1 6' : '';\n const isPath = item.kind === 'path';\n const fill =\n item.kind === 'line' || item.kind === 'connector'\n ? 'none'\n : isPath\n ? item.closed && style.fill !== 'none'\n ? style.fill\n : style.stroke\n : style.fill;\n const hatchId = `ad_h_${uid.replace(/[^a-z0-9_-]/gi, '_')}`;\n const hatch = style.fillMode === 'hatch' && fill !== 'none' && !isPath;\n const defs = hatch\n ? `<defs><pattern id=\"${hatchId}\" width=\"8\" height=\"8\" patternUnits=\"userSpaceOnUse\"><path d=\"M-2 2L2-2M0 8L8 0M6 10L10 6\" fill=\"none\" stroke=\"${esc(fill)}\" stroke-opacity=\"0.5\" stroke-width=\"1.3\"/></pattern></defs>`\n : '';\n const fillAttr = hatch ? `url(#${hatchId})` : fill;\n const geometry = `<path d=\"${esc(path)}\" fill=\"${esc(fillAttr)}\"${style.fillMode === 'tint' && !isPath ? ' fill-opacity=\"0.22\"' : ''} stroke=\"${isPath && !item.closed ? 'none' : esc(style.stroke)}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/>`;\n return `${defs}${geometry}`;\n}\nexport function headMarkup(\n point: Point,\n previous: Point,\n kind: 'arrow' | 'dot' | 'none' | undefined,\n stroke: string,\n width: number,\n): string {\n if (!kind || kind === 'none') return '';\n if (kind === 'dot')\n return `<circle cx=\"${round(point.x)}\" cy=\"${round(point.y)}\" r=\"${Math.max(3, width * 2)}\" fill=\"${esc(stroke)}\"/>`;\n const angle = Math.atan2(point.y - previous.y, point.x - previous.x);\n const length = Math.max(10, width * 4.5);\n const spread = Math.PI / 6;\n const a = {\n x: point.x - Math.cos(angle - spread) * length,\n y: point.y - Math.sin(angle - spread) * length,\n };\n const b = {\n x: point.x - Math.cos(angle + spread) * length,\n y: point.y - Math.sin(angle + spread) * length,\n };\n return `<path d=\"${pathFromPoints([a, point, b])}\" fill=\"none\" stroke=\"${esc(stroke)}\" stroke-width=\"${width}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`;\n}\nexport function headsMarkup(points: Point[], item: Item, theme: 'light' | 'dark'): string {\n if (points.length < 2) return '';\n const style = styleFor(item, theme);\n return (\n headMarkup(points[0], points[1], item.heads?.start, style.stroke, style.strokeWidth) +\n headMarkup(\n points[points.length - 1],\n points[points.length - 2],\n item.heads?.end ?? (item.kind === 'connector' ? 'arrow' : 'none'),\n style.stroke,\n style.strokeWidth,\n )\n );\n}\n","import type { AnnieDoc } from '../core/types';\nexport const ANNIE_MIME = 'application/vnd.anniedrawing+json';\nexport function exportJSON(doc: AnnieDoc): string {\n return JSON.stringify(doc, null, 2);\n}\n","const paths: Record<string, string> = {\n select:\n '<path d=\"M5.8 3.8c-1-.4-1.7.4-1.4 1.4l4.9 14.4c.4 1.1 1.8 1.1 2.2 0l2.2-5.8 5.8-2.2c1.1-.4 1.1-1.8 0-2.2Z\"/>',\n hand: '<path d=\"M8 12V6a2 2 0 0 1 4 0v5-7a2 2 0 0 1 4 0v8-5a2 2 0 0 1 4 0v8c0 5-4 7-7 7-3 0-4-2-6-5l-3-4c-1-2 1-4 3-2l2 2\"/>',\n rect: '<rect x=\"3.75\" y=\"4.75\" width=\"16.5\" height=\"14.5\" rx=\"4\"/>',\n ellipse: '<ellipse cx=\"12\" cy=\"12\" rx=\"8.25\" ry=\"7.25\"/>',\n diamond:\n '<path d=\"m13.4 3.8 6.8 6.8a2 2 0 0 1 0 2.8l-6.8 6.8a2 2 0 0 1-2.8 0l-6.8-6.8a2 2 0 0 1 0-2.8l6.8-6.8a2 2 0 0 1 2.8 0Z\"/>',\n line: '<path d=\"m5.5 18.5 13-13\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"5\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/>',\n connector: '<path d=\"M4 18h5a3 3 0 0 0 3-3V9a3 3 0 0 1 3-3h5m-4-4 4 4-4 4\"/>',\n path: '<path d=\"M3.5 17.5c1.8-5 3.2-11 6-11 4 0-1 12 3 12 2.8 0 3.2-8 5.5-8 1.6 0 2.3 2 2.5 4\"/>',\n text: '<path d=\"M5 7V4.5h14V7M12 4.5v15M8.5 19.5h7\"/>',\n note: '<path d=\"M7 3.75h10a3.25 3.25 0 0 1 3.25 3.25v7.1a2 2 0 0 1-.6 1.4l-4.2 4.2a2 2 0 0 1-1.4.6H7A3.25 3.25 0 0 1 3.75 17V7A3.25 3.25 0 0 1 7 3.75Z\"/><path d=\"M20 14h-3.5a2.5 2.5 0 0 0-2.5 2.5V20\"/>',\n lock: '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 8 0v3M12 14v3\"/>',\n unlock:\n '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 7.5-2M12 14v3\"/>',\n opacity:\n '<circle cx=\"12\" cy=\"12\" r=\"8.5\"/><path d=\"M12 3.5a8.5 8.5 0 0 1 0 17Z\" fill=\"currentColor\" stroke=\"none\"/>',\n front:\n '<rect x=\"8\" y=\"3.5\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 16v1A3.5 3.5 0 0 1 12 20.5H7A3.5 3.5 0 0 1 3.5 17v-5A3.5 3.5 0 0 1 7 8.5h1\"/>',\n back: '<rect x=\"3.5\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M8.5 8V7A3.5 3.5 0 0 1 12 3.5h5A3.5 3.5 0 0 1 20.5 7v5A3.5 3.5 0 0 1 17 15.5h-1\"/>',\n eraser:\n '<path d=\"m13.2 4.3-9 9a2.4 2.4 0 0 0 0 3.4L7.5 20h4l8.2-8.2a2.4 2.4 0 0 0 0-3.4l-4.1-4.1a1.7 1.7 0 0 0-2.4 0ZM8 10.5l6 6M11.5 20H21\"/>',\n undo: '<path d=\"m8 5-4.5 4.5L8 14M4 9.5h9.5a5.5 5.5 0 0 1 0 11H11\"/>',\n redo: '<path d=\"m16 5 4.5 4.5L16 14m4-4.5h-9.5a5.5 5.5 0 0 0 0 11H13\"/>',\n plus: '<path d=\"M12 5.5v13M5.5 12h13\"/>',\n minus: '<path d=\"M5.5 12h13\"/>',\n fit: '<path d=\"M8.5 3.75h-3a1.75 1.75 0 0 0-1.75 1.75v3m11.75-4.75h3a1.75 1.75 0 0 1 1.75 1.75v3M3.75 15.5v3a1.75 1.75 0 0 0 1.75 1.75h3m11.75-4.75v3a1.75 1.75 0 0 1-1.75 1.75h-3\"/>',\n chevron: '<path d=\"m7 9.5 3.6 3.6a2 2 0 0 0 2.8 0L17 9.5\"/>',\n download: '<path d=\"M12 3.5v11m-4-4 4 4 4-4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n upload: '<path d=\"M12 15V4m-4 4 4-4 4 4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n code: '<path d=\"m7 7-4 4a1.4 1.4 0 0 0 0 2l4 4m10-10 4 4a1.4 1.4 0 0 1 0 2l-4 4M14 4l-4 16\"/>',\n close: '<path d=\"m6.5 6.5 11 11m-11 0 11-11\"/>',\n more: '<circle cx=\"5\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/>',\n image:\n '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"m4 17 3.6-3.6a1.3 1.3 0 0 1 1.8 0l2.1 2.1 3.4-5.1a1.3 1.3 0 0 1 2.2 0L20 15\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2.5v1M12 20.5v1M2.5 12h1m17 0h1M5.3 5.3l.7.7m12 12 .7.7M5.3 18.7l.7-.7M18 6l.7-.7\"/>',\n moon: '<path d=\"M20 14.5a8.2 8.2 0 0 1-10.5-10c-3.9.7-6.4 3.7-6.4 7.5a8.1 8.1 0 0 0 16.9 2.5Z\"/>',\n trash:\n '<path d=\"M4 6.5h16M9 6.5V5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5v1.5m-9 0 .7 11.2A3 3 0 0 0 9.7 20.5h4.6a3 3 0 0 0 3-2.8L18 6.5M10 10.5v6m4-6v6\"/>',\n copy: '<rect x=\"8\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 8V7A3.5 3.5 0 0 0 12 3.5H7A3.5 3.5 0 0 0 3.5 7v5A3.5 3.5 0 0 0 7 15.5h1\"/>',\n grid: '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><path d=\"M9 4v16m6-16v16M4 9h16M4 15h16\"/>',\n book: '<path d=\"M12 5.5c-2.6-2-5.2-2.5-8-2v15c2.8-.5 5.4 0 8 2 2.6-2 5.2-2.5 8-2v-15c-2.8-.5-5.4 0-8 2Zm0 0v15\"/>',\n github:\n '<path fill=\"currentColor\" stroke=\"none\" d=\"M12 1C5.922 1 1 5.922 1 12c0 4.867 3.149 8.979 7.521 10.437.55.096.75-.232.75-.546 0-.262-.013-1.13-.013-2.049-3.06.56-3.703-1.31-3.703-1.31-.498-1.316-1.216-1.667-1.216-1.667-.991-.68.075-.668.075-.668 1.109.075 1.688 1.264 1.688 1.264.982 1.686 2.573 1.2 3.201.907.096-.699.381-1.2.695-1.478-2.448-.282-5.022-1.226-5.022-5.451 0-1.2.426-2.187 1.12-2.953-.113-.275-.487-1.392.107-2.9 0 0 .917-.292 3.011 1.12.873-.24 1.809-.36 2.74-.36.93 0 1.867.12 2.74.36 2.077-1.413 3.01-1.12 3.01-1.12.596 1.508.221 2.625.108 2.9.697.766 1.12 1.748 1.12 2.953 0 4.237-2.578 5.163-5.034 5.437.39.338.746 1.016.746 2.056 0 1.478-.014 2.666-.014 3.025 0 .304.202.655.753.545C19.854 20.979 23 16.859 23 12c0-6.078-4.922-11-11-11Z\"/>',\n alignLeft: '<path d=\"M4 5h16M4 12h10M4 19h16\"/>',\n alignCenter: '<path d=\"M4 5h16M7 12h10M4 19h16\"/>',\n alignRight: '<path d=\"M4 5h16M10 12h10M4 19h16\"/>',\n align:\n '<path d=\"M4 3.5v17\"/><rect x=\"8\" y=\"5\" width=\"12.5\" height=\"5\" rx=\"1.75\"/><rect x=\"8\" y=\"14\" width=\"8.5\" height=\"5\" rx=\"1.75\"/>',\n shapes:\n '<rect x=\"3\" y=\"3\" width=\"8.5\" height=\"8.5\" rx=\"2.5\"/><circle cx=\"17.3\" cy=\"6.7\" r=\"3.7\"/><path d=\"m6 14-3.5 6h8L7 14a.6.6 0 0 0-1 0Z\"/><rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"2\" transform=\"rotate(45 17 17)\"/>',\n link: '<path d=\"M10 14.5 8.8 15.7a3.6 3.6 0 1 1-5.1-5.1l3.2-3.2a3.6 3.6 0 0 1 5.1 0\"/><path d=\"m14 9.5 1.2-1.2a3.6 3.6 0 0 1 5.1 5.1l-3.2 3.2a3.6 3.6 0 0 1-5.1 0\"/>',\n};\nexport function icon(name: string) {\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths[name] ?? paths.select}</svg>`;\n}\nexport function button(\n label: string,\n name: string,\n handler: () => void,\n className = 'ad-icon-button',\n) {\n const el = document.createElement('button');\n el.type = 'button';\n el.className = className;\n el.title = label;\n el.setAttribute('aria-label', label);\n el.innerHTML = icon(name);\n el.addEventListener('click', () => {\n el.focus();\n handler();\n });\n return el;\n}\n","/** npm package version shown in the AnnieDrawing menu. Keep in sync with package.json. */\nexport const PACKAGE_VERSION = '0.3.2';\nexport const SITE_URL = 'https://anniedrawing.com';\nexport const GITHUB_REPO_URL = 'https://github.com/Frontierz-AI/AnnieDrawing';\n","import type { Board } from '../board';\nimport type { Item, Point } from '../core/types';\nimport { button, icon } from './icons';\nimport { GITHUB_REPO_URL, PACKAGE_VERSION } from './version';\nimport { color as resolveColor, DEFAULT_FONT, fonts, fontSize, styleFor } from '../stage/paint';\nimport { pageId } from '../core/ids';\nimport { ANNIE_MIME } from '../porter/json';\n/** PNG, SVG, or AnnieDoc (`json`, saved as `.annie`). */\nexport type UiExportFormat = 'png' | 'svg' | 'json';\n/** Header controls. Pass `ui: false` to `createBoard` to omit all editor chrome. */\nexport interface UiOptions {\n /** AnnieDrawing control. Default `true`. */\n menu?: boolean;\n /**\n * Export control. Default `['png', 'svg']`. `false` hides it. Include `'json'` for AnnieDoc.\n * One format downloads on click; two or more open a menu.\n */\n export?: boolean | UiExportFormat[];\n /** Page chips, add-page, and All pages. Default true. */\n pages?: boolean;\n}\nconst defaultExportFormats: UiExportFormat[] = ['png', 'svg'];\nfunction exportFormats(value: UiOptions['export']): UiExportFormat[] {\n if (value === false) return [];\n if (!Array.isArray(value)) return [...defaultExportFormats];\n const seen = new Set<UiExportFormat>();\n const formats: UiExportFormat[] = [];\n for (const format of value) {\n if (format !== 'png' && format !== 'svg' && format !== 'json') continue;\n if (seen.has(format)) continue;\n seen.add(format);\n formats.push(format);\n }\n return formats;\n}\nconst tools = [\n ['select', 'Select', 'V'],\n ['hand', 'Hand', 'H'],\n ['rect', 'Rectangle', 'R'],\n ['ellipse', 'Ellipse', 'O'],\n ['diamond', 'Diamond', 'D'],\n ['connector', 'Arrow', 'A'],\n ['line', 'Line', 'L'],\n ['path', 'Draw', 'P'],\n ['text', 'Text', 'T'],\n ['note', 'Sticky note', 'N'],\n ['eraser', 'Eraser', 'E'],\n];\nconst palette = [\n ['ink', 'Ink'],\n ['paper', 'Paper'],\n ['teal', 'Frontierz green'],\n ['moss', 'Soft green'],\n ['coral', 'Orange'],\n ['violet', 'Lavender'],\n ['slate', 'Slate'],\n ['amber', 'Peach'],\n ['sky', 'Sky blue'],\n ['rose', 'Rose'],\n ['none', 'No fill'],\n];\n/** Narrow hosts, or a short tablet / phone-landscape host. */\nfunction phoneChrome(width: number, height: number) {\n return width <= 700 || (width <= 1023 && height <= 640);\n}\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className = '', text?: string) {\n const node = document.createElement(tag);\n node.className = className;\n if (text) node.textContent = text;\n return node;\n}\nfunction textButton(label: string, action: () => void, kind = 'ad-button') {\n const b = el('button', kind, label);\n b.type = 'button';\n b.addEventListener('click', () => {\n b.focus();\n action();\n });\n return b;\n}\nfunction field(label: string, input: HTMLElement) {\n const wrapper = el('label', 'ad-field');\n wrapper.append(el('span', 'ad-field-label', label), input);\n return wrapper;\n}\nfunction select(values: [string, string][], value: string, change: (value: string) => void) {\n const input = el('select');\n values.forEach(([v, text]) => {\n const o = el('option', '', text);\n o.value = v;\n input.append(o);\n });\n if (!values.some(([v]) => v === value)) {\n const custom = el('option', '', value);\n custom.value = value;\n input.append(custom);\n }\n input.value = value;\n input.onchange = () => change(input.value);\n return input;\n}\nfunction download(content: string | Blob, name: string, type: string) {\n const url = URL.createObjectURL(\n typeof content === 'string' ? new Blob([content], { type }) : content,\n );\n const link = el('a');\n link.href = url;\n link.download = name;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\nexport function mountUI(board: Board, options: UiOptions = {}): () => void {\n const ui = el('div', 'ad-ui');\n board.stage.root.append(ui);\n const unsubs: (() => void)[] = [];\n let activeDialog: HTMLDialogElement | undefined;\n function dialog(title: string) {\n closePopover();\n activeDialog?.close();\n const previous = document.activeElement as HTMLElement;\n const d = el('dialog', 'ad-dialog');\n const head = el('div', 'ad-dialog-head');\n const copy = el('div');\n copy.append(el('h2', '', title));\n head.append(\n copy,\n button('Close', 'close', () => d.close()),\n );\n d.append(head);\n d.addEventListener('click', (e) => {\n if (e.target === d) {\n const r = d.getBoundingClientRect();\n if (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom)\n d.close();\n }\n });\n d.addEventListener('close', () => {\n d.remove();\n if (activeDialog === d) activeDialog = undefined;\n if (!activeDialog) {\n refresh();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n }\n });\n ui.append(d);\n activeDialog = d;\n d.showModal();\n return d;\n }\n let activePopover: HTMLElement | undefined;\n let popoverTrigger: HTMLButtonElement | undefined;\n let pagePressTimer: ReturnType<typeof setTimeout> | undefined;\n function closePopover() {\n activePopover?.hidePopover();\n activePopover?.remove();\n activePopover = undefined;\n popoverTrigger?.setAttribute('aria-expanded', 'false');\n if (popoverTrigger) popoverTrigger.popoverTargetElement = null;\n popoverTrigger = undefined;\n }\n function popover(trigger: HTMLButtonElement | undefined, label: string) {\n if (trigger && popoverTrigger === trigger && activePopover?.matches(':popover-open')) {\n closePopover();\n return;\n }\n closePopover();\n const panel = el('div', 'ad-popover');\n panel.popover = 'auto';\n panel.setAttribute('role', 'group');\n panel.setAttribute('aria-label', label);\n const previous = document.activeElement as HTMLElement;\n if (trigger) {\n trigger.setAttribute('aria-expanded', 'true');\n trigger.popoverTargetElement = panel;\n trigger.popoverTargetAction = 'show';\n }\n activePopover = panel;\n popoverTrigger = trigger;\n panel.addEventListener('toggle', () => {\n if (activePopover === panel && !panel.matches(':popover-open'))\n trigger?.setAttribute('aria-expanded', 'false');\n });\n panel.addEventListener('keydown', (event) => {\n event.stopPropagation();\n if (event.key === 'Escape' || (event.key === 'Tab' && panel.popover === 'manual')) {\n if (event.key === 'Escape') event.preventDefault();\n closePopover();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n } else if (\n !(event.target instanceof HTMLInputElement) &&\n ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)\n ) {\n const items = popoverItems(panel);\n const current = items.indexOf(document.activeElement as HTMLElement);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? items.length - 1\n : (current +\n (event.key === 'ArrowDown' || event.key === 'ArrowRight' ? 1 : -1) +\n items.length) %\n items.length;\n event.preventDefault();\n items[next]?.focus();\n }\n });\n ui.append(panel);\n return panel;\n }\n function showPopover(\n panel: HTMLElement,\n trigger: HTMLButtonElement,\n alignTo: HTMLElement = trigger,\n ) {\n panel.showPopover();\n const anchor = alignTo.getBoundingClientRect(),\n bounds = board.stage.root.getBoundingClientRect();\n const mobile = phoneChrome(bounds.width, bounds.height),\n width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n const besideToolbar = trigger.closest('.ad-toolbar') && !mobile;\n const left = besideToolbar\n ? anchor.right + 12\n : trigger.closest('.ad-header') && anchor.left < bounds.left + bounds.width / 2\n ? anchor.left\n : anchor.right - width;\n const top = besideToolbar\n ? anchor.top\n : anchor.top > bounds.top + bounds.height / 2\n ? anchor.top - height - 10\n : anchor.bottom + 10;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(left, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(top, bounds.bottom - height - 12))}px`;\n popoverItems(panel)[0]?.focus();\n }\n function popoverItems(panel: HTMLElement) {\n return [...panel.querySelectorAll<HTMLElement>('button:not(:disabled), a[href]')];\n }\n function contextMenu(label: string, point: Point) {\n const panel = popover(undefined, label)!;\n // A native auto popover dismisses on the right-button release that opened it.\n panel.popover = 'manual';\n panel.classList.add('ad-context-menu');\n panel.setAttribute('role', 'menu');\n panel.tabIndex = -1;\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = textButton(\n label,\n () => {\n closePopover();\n board.focus();\n action();\n },\n 'ad-tool-option',\n );\n option.insertAdjacentHTML('afterbegin', icon(glyph));\n option.setAttribute('role', 'menuitem');\n option.disabled = board.readonly || disabled;\n if (glyph === 'trash') option.classList.add('ad-danger');\n panel.append(option);\n };\n const show = () => {\n panel.showPopover();\n const bounds = board.stage.root.getBoundingClientRect();\n const width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(point.x, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(point.y, bounds.bottom - height - 12))}px`;\n (panel.querySelector<HTMLButtonElement>('button:not(:disabled)') ?? panel).focus();\n };\n return { panel, add, show };\n }\n const hideOnResize = () => closePopover();\n const dismissContext = (event: PointerEvent) => {\n if (activePopover?.popover === 'manual' && !activePopover.contains(event.target as Node))\n closePopover();\n };\n window.addEventListener('resize', hideOnResize);\n window.addEventListener('pointerdown', dismissContext, true);\n unsubs.push(() => {\n window.removeEventListener('resize', hideOnResize);\n window.removeEventListener('pointerdown', dismissContext, true);\n });\n const showMenu = options.menu !== false;\n const formats = exportFormats(options.export);\n const header = el('header', 'ad-header');\n let brand: HTMLButtonElement | undefined;\n let drawingInput: HTMLInputElement | undefined;\n let exportButton: HTMLButtonElement | undefined;\n if (showMenu) {\n brand = button('Board menu', 'chevron', openMenu, 'ad-brand');\n brand.innerHTML =\n '<span class=\"ad-brand-mark\" aria-hidden=\"true\"><svg viewBox=\"0 0 40 40\"><path d=\"M9 29 20 8l11 21M14 22h12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"32\" cy=\"9\" r=\"2.5\" fill=\"currentColor\"/></svg></span><span class=\"ad-brand-name\">AnnieDrawing</span>' +\n icon('chevron');\n brand.setAttribute('aria-haspopup', 'true');\n brand.setAttribute('aria-expanded', 'false');\n drawingInput = el('input');\n drawingInput.type = 'file';\n drawingInput.accept = '.annie,.json,application/json';\n drawingInput.hidden = true;\n drawingInput.onchange = () => {\n const file = drawingInput?.files?.[0];\n if (drawingInput) drawingInput.value = '';\n if (file)\n void file\n .text()\n .then((value) => board.load(JSON.parse(value)))\n .catch(() => undefined);\n };\n header.append(brand);\n }\n if (formats.length) {\n const actions = el('div', 'ad-header-actions');\n exportButton = textButton('Export', openExport, 'ad-button ad-primary');\n exportButton.insertAdjacentHTML('afterbegin', icon('download'));\n if (formats.length > 1) {\n exportButton.setAttribute('aria-haspopup', 'true');\n exportButton.setAttribute('aria-expanded', 'false');\n }\n actions.append(exportButton);\n header.append(actions);\n }\n if (!showMenu) header.classList.add('ad-header-end');\n if (showMenu || formats.length) ui.append(header);\n if (drawingInput) ui.append(drawingInput);\n const toolbar = el('nav', 'ad-toolbar');\n toolbar.setAttribute('aria-label', 'Drawing tools');\n function toolButton(id: string, expanded = false) {\n const [, label, key] = tools.find((tool) => tool[0] === id)!;\n const b = button(\n label,\n id,\n () => {\n closePopover();\n board.setTool(id);\n board.focus();\n },\n expanded ? 'ad-tool-option' : 'ad-icon-button',\n );\n b.dataset.tool = id;\n b.setAttribute('aria-keyshortcuts', key);\n b.setAttribute('aria-pressed', String(board.tool === id));\n b.innerHTML += expanded ? `<span>${label}</span>` : `<span class=\"ad-tooltip\">${label}</span>`;\n if (board.readonly && id !== 'hand' && id !== 'select') b.disabled = true;\n return b;\n }\n const shapeKinds = ['rect', 'ellipse', 'diamond', 'line', 'connector'];\n const shapeButton = button('Shapes', 'shapes', () => {\n const panel = popover(shapeButton, 'Shapes');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n panel.append(...shapeKinds.map((id) => toolButton(id, true)));\n showPopover(panel, shapeButton);\n });\n shapeButton.setAttribute('aria-haspopup', 'true');\n shapeButton.setAttribute('aria-expanded', 'false');\n shapeButton.innerHTML +=\n '<span class=\"ad-tool-corner\"></span><span class=\"ad-tooltip\">Shapes</span>';\n const imageInput = el('input');\n imageInput.type = 'file';\n imageInput.accept = 'image/png,image/jpeg,image/webp,image/gif,image/avif';\n imageInput.hidden = true;\n imageInput.onchange = () => {\n if (imageInput.files?.[0]) void board.addImage(imageInput.files[0]).catch(() => undefined);\n imageInput.value = '';\n };\n const imageButton = button('Add image', 'image', () => {\n closePopover();\n imageInput.click();\n });\n imageButton.innerHTML += '<span class=\"ad-tooltip\">Add image</span>';\n imageButton.disabled = board.readonly;\n const hand = toolButton('hand');\n if (showMenu) hand.classList.add('ad-desktop-tool');\n toolbar.append(\n toolButton('select'),\n hand,\n toolButton('eraser'),\n el('div', 'ad-toolbar-divider'),\n shapeButton,\n toolButton('path'),\n toolButton('text'),\n toolButton('note'),\n imageButton,\n imageInput,\n );\n ui.append(toolbar);\n const styleDock = el('aside', 'ad-style-dock');\n styleDock.setAttribute('aria-label', 'Selection style');\n styleDock.hidden = true;\n const stylePanel = el('div', 'ad-style-panel');\n const deselect = button('Deselect', 'chevron', () => board.select([]));\n deselect.classList.add('ad-style-dismiss');\n styleDock.append(deselect, stylePanel);\n ui.append(styleDock);\n const footer = el('footer', 'ad-footer');\n const undo = button('Undo', 'undo', () => board.undo()),\n redo = button('Redo', 'redo', () => board.redo());\n undo.setAttribute('aria-keyshortcuts', 'Meta+Z Control+Z');\n redo.setAttribute('aria-keyshortcuts', 'Meta+Shift+Z Control+Shift+Z');\n const pagesBar = el('nav', 'ad-pages');\n pagesBar.setAttribute('aria-label', 'Pages');\n const pageTabs = el('div', 'ad-page-tabs');\n pageTabs.setAttribute('role', 'tablist');\n pageTabs.setAttribute('aria-label', 'Pages');\n const overflow = button('All pages', 'more', openPages);\n overflow.setAttribute('aria-haspopup', 'true');\n overflow.setAttribute('aria-expanded', 'false');\n overflow.hidden = true;\n const newPage = button('Add page', 'plus', addPage);\n newPage.disabled = board.readonly;\n pagesBar.append(pageTabs, overflow, newPage);\n let pageState = '';\n function pageContext(id: string, name: string, point: Point) {\n const menu = contextMenu('Page actions', point);\n menu.add('Rename page', 'text', () => renamePage(id, name));\n menu.add(\n 'Delete page',\n 'trash',\n () => {\n board.apply([{ op: 'page.remove', id }], { origin: 'user', label: 'Delete page' });\n },\n board.read().pages.length === 1,\n );\n menu.show();\n }\n function pageButton(id: string, name: string, tab = false) {\n const pick = textButton(\n name,\n () => {\n closePopover();\n board.setPage(id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n },\n tab ? 'ad-page-tab' : 'ad-tool-option',\n );\n pick.title = name;\n pick.dataset.pageId = id;\n let held = false;\n let start: Point;\n pick.addEventListener('pointerdown', (event) => {\n held = false;\n if (event.pointerType !== 'touch') return;\n start = { x: event.clientX, y: event.clientY };\n clearTimeout(pagePressTimer);\n pagePressTimer = setTimeout(() => {\n held = true;\n pageContext(id, name, start);\n }, 500);\n });\n pick.addEventListener('pointermove', (event) => {\n if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > 10)\n clearTimeout(pagePressTimer);\n });\n for (const type of ['pointerup', 'pointercancel'])\n pick.addEventListener(type, () => clearTimeout(pagePressTimer));\n pick.addEventListener(\n 'click',\n (event) => {\n if (held) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n },\n true,\n );\n if (tab) {\n pick.setAttribute('role', 'tab');\n pick.setAttribute('aria-selected', String(board.pageId === id));\n pick.tabIndex = board.pageId === id ? 0 : -1;\n } else pick.setAttribute('aria-current', String(board.pageId === id));\n pick.addEventListener('contextmenu', (event) => {\n event.preventDefault();\n pageContext(id, name, { x: event.clientX, y: event.clientY });\n });\n pick.addEventListener('keydown', (event) => {\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n event.preventDefault();\n const bounds = pick.getBoundingClientRect();\n pageContext(id, name, { x: bounds.left, y: bounds.top });\n } else if (tab && ['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n const pages = board.read().pages;\n const index = pages.findIndex((page) => page.id === id);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? pages.length - 1\n : (index + (event.key === 'ArrowRight' ? 1 : -1) + pages.length) % pages.length;\n closePopover();\n board.setPage(pages[next].id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n }\n });\n return pick;\n }\n let fittingPages = false;\n function fitPageTabs() {\n if (fittingPages) return;\n fittingPages = true;\n const probe = el('div', 'ad-page-tabs');\n try {\n const tabs = [...pageTabs.querySelectorAll<HTMLButtonElement>('button')];\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;width:max-content';\n const samples = tabs.map((tab) => {\n const sample = tab.cloneNode(true) as HTMLButtonElement;\n sample.hidden = false;\n sample.style.maxWidth = '';\n return sample;\n });\n const overflowSample = overflow.cloneNode(true) as HTMLButtonElement;\n overflowSample.hidden = false;\n probe.append(...samples, overflowSample);\n ui.append(probe);\n const widths = samples.map((sample) => sample.getBoundingClientRect().width);\n const overflowWidth = overflowSample.offsetWidth;\n probe.remove();\n const needed = widths.reduce((sum, width) => sum + width + 4, 0) + newPage.offsetWidth + 14;\n const room =\n pagesBar.offsetTop === footerRight.offsetTop\n ? footer.clientWidth - footerRight.offsetWidth - 16\n : pagesBar.clientWidth;\n const cap = Math.min(room, 520);\n const hideOverflow = needed <= cap;\n const nextHidden = tabs.map(() => false);\n const nextMax = tabs.map(() => '');\n if (!hideOverflow) {\n let remaining = Math.max(40, cap - newPage.offsetWidth - 14 - overflowWidth - 4);\n const selected = tabs.findIndex((tab) => tab.getAttribute('aria-selected') === 'true');\n for (const index of [\n selected,\n ...tabs.map((_, index) => index).filter((index) => index !== selected),\n ]) {\n if (index < 0) continue;\n if (index === selected) {\n nextMax[index] = `${remaining}px`;\n remaining -= Math.min(remaining, widths[index]) + 4;\n } else {\n nextHidden[index] = widths[index] > remaining;\n if (!nextHidden[index]) remaining -= widths[index] + 4;\n }\n }\n }\n overflow.hidden = hideOverflow;\n tabs.forEach((tab, index) => {\n tab.hidden = nextHidden[index];\n tab.style.maxWidth = nextMax[index];\n });\n } finally {\n probe.remove();\n fittingPages = false;\n }\n }\n function renderPages() {\n if (options.pages === false) return;\n const pages = board.read().pages;\n const state = JSON.stringify([board.pageId, pages.map(({ id, name }) => [id, name])]);\n if (state === pageState) return;\n pageState = state;\n pageTabs.replaceChildren(...pages.map((page) => pageButton(page.id, page.name, true)));\n fitPageTabs();\n }\n const pagesObserver = new ResizeObserver(fitPageTabs);\n if (options.pages !== false) {\n pagesObserver.observe(ui);\n unsubs.push(() => pagesObserver.disconnect());\n }\n function addPage() {\n closePopover();\n const id = pageId();\n const pages = board.read().pages;\n let number = pages.length + 1;\n while (pages.some((page) => page.name === `Page ${number}`)) number++;\n const result = board.apply(\n [{ op: 'page.add', page: { id, name: `Page ${number}`, items: [] } }],\n { origin: 'user', label: 'Add page' },\n );\n if (result.ok) board.setPage(id);\n }\n function openPages() {\n const panel = popover(overflow, 'All pages');\n if (!panel) return;\n panel.classList.add('ad-pages-popover');\n for (const page of board.read().pages) {\n const row = el('div', 'ad-page-row');\n row.append(pageButton(page.id, page.name));\n const actions = button(`Actions for ${page.name}`, 'more', () => {\n const bounds = actions.getBoundingClientRect();\n pageContext(page.id, page.name, { x: bounds.left, y: bounds.top });\n });\n row.append(actions);\n panel.append(row);\n }\n showPopover(panel, overflow);\n panel.querySelector<HTMLElement>('[aria-current=\"true\"]')?.scrollIntoView({ block: 'nearest' });\n }\n const footerRight = el('div', 'ad-footer-right');\n const zoom = el('div', 'ad-zoom');\n const percentage = textButton(\n '100%',\n () => {\n const panel = popover(percentage, 'Zoom controls');\n if (!panel) return;\n const row = el('div', 'ad-zoom-controls');\n row.append(\n button('Zoom out', 'minus', () => (board.view.zoom /= 1.2)),\n textButton('100%', () => (board.view.zoom = 1), 'ad-zoom-value'),\n button('Zoom in', 'plus', () => (board.view.zoom *= 1.2)),\n );\n panel.append(row);\n showPopover(panel, percentage, fitButton);\n },\n 'ad-zoom-value',\n );\n percentage.setAttribute('aria-label', 'Zoom controls');\n percentage.setAttribute('aria-haspopup', 'true');\n percentage.setAttribute('aria-expanded', 'false');\n const fitButton = button('Fit drawing', 'fit', () => board.view.fit());\n zoom.append(percentage, fitButton, undo, redo);\n footerRight.append(zoom);\n if (options.pages === false) footer.append(footerRight);\n else footer.append(pagesBar, footerRight);\n ui.append(footer);\n function renamePage(id: string, name: string) {\n if (board.readonly) return;\n const d = dialog('Name this page');\n const input = el('input');\n input.value = name;\n input.maxLength = 100;\n d.append(\n field('Page name', input),\n textButton(\n 'Save name',\n () => {\n if (input.value.trim())\n board.apply([{ op: 'page.set', id, patch: { name: input.value.trim() } }], {\n origin: 'user',\n label: 'Rename page',\n });\n d.close();\n },\n 'ad-button ad-primary',\n ),\n );\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n d.addEventListener(\n 'close',\n () => {\n const tab = pageTabs.querySelector<HTMLButtonElement>(`[data-page-id=\"${CSS.escape(id)}\"]`);\n if (tab && !tab.hidden) tab.focus();\n else if (!overflow.hidden) overflow.focus();\n },\n { once: true },\n );\n input.focus();\n input.select();\n }\n function hrefAction(kind: string) {\n return kind === 'video' ? 'Edit Video URL' : 'Edit URL';\n }\n function editHref(id: string) {\n if (board.readonly || board.isLocked(id)) return;\n const item = board.get(id);\n if (!item || (item.kind !== 'video' && item.kind !== 'link')) return;\n const video = item.kind === 'video';\n const d = dialog(video ? 'Edit video URL' : 'Edit URL');\n const input = el('input');\n input.type = 'text';\n input.inputMode = 'url';\n input.setAttribute('autocomplete', 'url');\n input.spellcheck = false;\n input.maxLength = 2000;\n input.value = item.href ?? '';\n input.setAttribute('aria-label', video ? 'Video URL' : 'URL');\n const error = el('p', 'ad-dialog-error');\n error.setAttribute('role', 'alert');\n error.hidden = true;\n const save = textButton(\n video ? 'Save video URL' : 'Save URL',\n () => {\n void (async () => {\n save.disabled = true;\n const result = await board.setHref(id, input.value);\n save.disabled = false;\n if (!result.ok) {\n const code = result.errors[0]?.code;\n error.textContent =\n code === 'LOCKED' || code === 'READONLY'\n ? (result.errors[0]?.message ?? 'This cannot be edited.')\n : video\n ? 'Use a YouTube or Vimeo URL.'\n : 'Use an http(s) URL.';\n error.hidden = false;\n input.setAttribute('aria-invalid', 'true');\n input.focus();\n return;\n }\n d.close();\n })();\n },\n 'ad-button ad-primary',\n );\n d.append(field(video ? 'Video URL' : 'URL', input), error, save);\n input.addEventListener('input', () => {\n error.hidden = true;\n input.removeAttribute('aria-invalid');\n });\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n input.focus();\n input.select();\n }\n let styleSelection = '';\n function renderStyle() {\n const locked = board.selection.some((id) => board.isLocked(id));\n if (board.tool !== 'select') {\n if (popoverTrigger && styleDock.contains(popoverTrigger)) closePopover();\n styleDock.hidden = true;\n return;\n }\n if (\n activeDialog ||\n (!locked &&\n document.activeElement instanceof HTMLInputElement &&\n document.activeElement.type === 'range' &&\n (styleDock.contains(document.activeElement) ||\n activePopover?.contains(document.activeElement)))\n )\n return;\n const focused = styleDock.contains(document.activeElement)\n ? (document.activeElement as HTMLElement)\n : undefined;\n const stylePopup =\n popoverTrigger && styleDock.contains(popoverTrigger)\n ? {\n label: popoverTrigger.getAttribute('aria-label'),\n focused: activePopover?.contains(document.activeElement),\n }\n : undefined;\n const focusLabel =\n focused?.getAttribute('aria-label') ?? (stylePopup?.focused ? stylePopup.label : undefined);\n const focusField = focused?.closest('label')?.querySelector('.ad-field-label')?.textContent;\n if (stylePopup) closePopover();\n const items = board.selection.map((id) => board.get(id)!).filter(Boolean);\n const selectedKey = items.map((item) => item.id).join(',');\n if (styleSelection !== selectedKey) {\n closePopover();\n }\n styleSelection = selectedKey;\n stylePanel.replaceChildren();\n styleDock.hidden = items.length === 0;\n if (!items.length) {\n if (stylePopup?.focused) board.focus();\n return;\n }\n const item = items[0],\n single = items.length === 1;\n const fillable = items.every((i) => ['rect', 'ellipse', 'diamond', 'note'].includes(i.kind));\n const stroked = items.every(\n (i) => !['image', 'html', 'video', 'link', 'group', 'text', 'note'].includes(i.kind),\n );\n const textOnly = items.every((i) => i.kind === 'text');\n const hasText = items.every(\n (i) => !['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(i.kind),\n );\n const colorControls = el('div', 'ad-color-controls');\n function colorControl(label: string, key: 'fill' | 'stroke') {\n const current =\n item.style?.[key] ?? (key === 'fill' ? (item.kind === 'note' ? 'moss' : 'none') : 'ink');\n const trigger = textButton(\n label,\n () => {\n const panel = popover(trigger, `${label} color`);\n if (!panel) return;\n panel.classList.add('ad-color-popover');\n for (const [token, name] of palette) {\n const b = el('button', `ad-swatch ${token === 'none' ? 'ad-swatch-none' : ''}`);\n b.type = 'button';\n b.style.setProperty('--swatch', resolveColor(token, board.stage.resolvedTheme));\n b.setAttribute('aria-label', `${label}: ${name}`);\n b.title = name;\n b.setAttribute('aria-pressed', String(current === token));\n b.onclick = () => {\n closePopover();\n board.defaultStyle[key] = token;\n board.updateSelection({ style: { [key]: token } });\n stylePanel.querySelector<HTMLButtonElement>(`[aria-label=\"${label}\"]`)?.focus();\n };\n panel.append(b);\n }\n showPopover(panel, trigger);\n },\n 'ad-color-control',\n );\n trigger.setAttribute('aria-label', label);\n trigger.setAttribute('aria-haspopup', 'true');\n trigger.setAttribute('aria-expanded', 'false');\n const swatch = el('span', `ad-color-preview ${current === 'none' ? 'ad-swatch-none' : ''}`);\n swatch.style.setProperty('--swatch', resolveColor(current, board.stage.resolvedTheme));\n trigger.prepend(swatch);\n colorControls.append(trigger);\n }\n if (fillable) colorControl('Fill', 'fill');\n if (stroked) colorControl('Line', 'stroke');\n if (textOnly) colorControl('Color', 'stroke');\n const opacityButton = textButton(\n 'Opacity',\n () => {\n const panel = popover(opacityButton, 'Opacity controls');\n if (!panel) return;\n panel.classList.add('ad-opacity-popover');\n const input = el('input');\n input.type = 'range';\n input.setAttribute('aria-label', 'Opacity');\n input.min = '0';\n input.max = '100';\n input.value = String(Math.round((board.get(item.id)?.style?.opacity ?? 1) * 100));\n const value = el('output', '', `${input.value}%`);\n const label = field('Opacity', input);\n label.querySelector('.ad-field-label')!.append(value);\n let first = true;\n input.oninput = () => {\n value.textContent = `${input.value}%`;\n board.apply(\n items.map(({ id }) => ({\n op: 'set',\n id,\n patch: { style: { opacity: Number(input.value) / 100 } },\n })),\n { origin: 'user', label: 'Change opacity', merge: !first },\n );\n first = false;\n };\n input.onchange = () => {\n first = true;\n };\n panel.append(label);\n showPopover(panel, opacityButton);\n input.focus();\n },\n 'ad-color-control',\n );\n opacityButton.insertAdjacentHTML('afterbegin', icon('opacity'));\n opacityButton.setAttribute('aria-label', 'Opacity');\n opacityButton.setAttribute('aria-haspopup', 'true');\n opacityButton.setAttribute('aria-expanded', 'false');\n if (items.every((item) => item.kind !== 'group')) colorControls.append(opacityButton);\n if (colorControls.childElementCount) stylePanel.append(colorControls);\n const updateText = (patch: Partial<NonNullable<Item['text']>>) =>\n board.apply(\n items.map((item) => ({\n op: 'set',\n id: item.id,\n patch: { text: { value: item.text?.value ?? '', ...patch } },\n })),\n { origin: 'user', label: 'Text style' },\n );\n function styleRow(label: string) {\n const row = el('div', 'ad-style-row');\n const group = el('div', 'ad-segments');\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', label);\n row.append(el('span', 'ad-style-label', label), group);\n stylePanel.append(row);\n return group;\n }\n function choices(\n group: HTMLElement,\n values: [string, string, string][],\n current: (item: Item) => string,\n change: (value: string) => void,\n ) {\n return values.map(([value, label, content]) => {\n const b = textButton(label, () => change(value), 'ad-segment');\n b.setAttribute('aria-label', label);\n b.title = label;\n b.setAttribute('aria-pressed', String(items.every((item) => current(item) === value)));\n b.innerHTML = content;\n group.append(b);\n return b;\n });\n }\n function lineIcon(width: number, dash = '') {\n return `<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3 12h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"${width}\" stroke-linecap=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/></svg>`;\n }\n if (hasText) {\n choices(\n styleRow('Text'),\n [\n ['s', 'Text size: Small', 'S'],\n ['m', 'Text size: Medium', 'M'],\n ['l', 'Text size: Large', 'L'],\n ['xl', 'Text size: Extra large', 'XL'],\n ],\n (item) => ({ 14: 's', 18: 'm', 26: 'l', 36: 'xl' })[fontSize(item.text)] ?? '',\n (value) => updateText({ size: value as 'm' }),\n );\n choices(\n styleRow('Align'),\n [\n ['start', 'Align text left', icon('alignLeft')],\n ['center', 'Align text center', icon('alignCenter')],\n ['end', 'Align text right', icon('alignRight')],\n ],\n (item) => item.text?.align ?? (item.kind === 'text' ? 'start' : 'center'),\n (value) => updateText({ align: value as 'start' }),\n );\n const fontChoices: [keyof typeof fonts, string, string][] = [\n ['sans', 'Font: Friendly', 'Aa'],\n ['serif', 'Font: Serif', 'Aa'],\n ['mono', 'Font: Mono', 'Aa'],\n ['hand', 'Font: Handwritten', 'Aa'],\n ];\n choices(\n styleRow('Font'),\n fontChoices,\n (item) => item.text?.font ?? DEFAULT_FONT,\n (value) => updateText({ font: value as 'sans' }),\n ).forEach((button, index) => {\n button.style.fontFamily = fonts[fontChoices[index][0]];\n });\n }\n if (stroked) {\n choices(\n styleRow('Line'),\n [\n ['1', 'Line: Fine', lineIcon(1)],\n ['2', 'Line: Regular', lineIcon(2)],\n ['4', 'Line: Bold', lineIcon(4)],\n ['8', 'Line: Extra bold', lineIcon(6)],\n ],\n (item) => String(styleFor(item, board.stage.resolvedTheme).strokeWidth),\n (value) => board.updateSelection({ style: { strokeWidth: Number(value) } }),\n );\n if (items.every((item) => item.kind !== 'path' || item.closed)) {\n choices(\n styleRow('Pattern'),\n [\n ['solid', 'Pattern: Solid', lineIcon(2)],\n ['dashed', 'Pattern: Dashed', lineIcon(2, '5 4')],\n ['dotted', 'Pattern: Dotted', lineIcon(2, '1 5')],\n ],\n (item) => item.style?.dash ?? 'solid',\n (value) => board.updateSelection({ style: { dash: value as 'solid' } }),\n );\n }\n }\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Route',\n select(\n [\n ['straight', 'Straight'],\n ['elbow', 'Elbow'],\n ['curve', 'Curve'],\n ],\n item.route ?? 'elbow',\n (v) => board.updateSelection({ route: v as 'elbow' }),\n ),\n ),\n );\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Arrowhead',\n select(\n [\n ['arrow', 'Arrow'],\n ['dot', 'Dot'],\n ['none', 'None'],\n ],\n item.heads?.end ?? 'arrow',\n (value) => board.updateSelection({ heads: { ...item.heads, end: value as 'arrow' } }),\n ),\n ),\n );\n if (single && (item.kind === 'video' || item.kind === 'link')) {\n const label = hrefAction(item.kind);\n const edit = textButton(label, () => editHref(item.id), 'ad-button ad-href-edit');\n edit.setAttribute('aria-label', label);\n stylePanel.append(edit);\n }\n const lock = button(\n locked ? 'Unlock selection' : 'Lock selection',\n locked ? 'lock' : 'unlock',\n () => board.updateSelection({ locked: !locked }),\n );\n lock.setAttribute('aria-pressed', String(locked));\n const row = el('div', 'ad-selection-actions');\n row.append(\n button('Duplicate selection', 'copy', () => board.duplicate()),\n button('More arrangement options', 'align', openArrange),\n lock,\n button('Delete selection', 'trash', () => board.deleteSelection()),\n );\n stylePanel.append(row);\n if (board.readonly || locked)\n stylePanel\n .querySelectorAll('button,input,select')\n .forEach(\n (e) =>\n ((e as HTMLButtonElement).disabled = e !== deselect && (e !== lock || board.readonly)),\n );\n if (focusLabel === 'Unlock selection' || focusLabel === 'Lock selection') lock.focus();\n else if (focusLabel === 'Deselect') deselect.focus();\n else if (focusLabel)\n stylePanel.querySelector<HTMLElement>(`[aria-label=\"${CSS.escape(focusLabel)}\"]`)?.focus();\n else if (focusField)\n [...stylePanel.querySelectorAll('label')]\n .find((label) => label.querySelector('.ad-field-label')?.textContent === focusField)\n ?.querySelector<HTMLElement>('input,select')\n ?.focus();\n if (focused || stylePopup?.focused)\n if (locked && !board.readonly && !styleDock.contains(document.activeElement)) lock.focus();\n }\n function openArrange() {\n const d = dialog('Give it a little order');\n const actions = el('div', 'ad-action-grid');\n const item = board.selection.length === 1 ? board.get(board.selection[0]) : undefined;\n if (item) {\n actions.append(\n textButton('Duplicate', () => {\n board.duplicate();\n d.close();\n }),\n textButton('Delete', () => {\n board.deleteSelection();\n d.close();\n }),\n );\n }\n if (board.selection.length > 1)\n for (const mode of [\n 'left',\n 'center',\n 'right',\n 'top',\n 'middle',\n 'bottom',\n 'horizontal',\n 'vertical',\n ] as const)\n actions.append(\n textButton(\n mode === 'horizontal' || mode === 'vertical' ? `Distribute ${mode}` : `Align ${mode}`,\n () => {\n board.align(mode);\n d.close();\n },\n ),\n );\n if (board.selection.length > 1)\n actions.append(\n textButton('Group', () => {\n board.group();\n d.close();\n }),\n );\n if (board.selection.some((id) => board.get(id)?.kind === 'group'))\n actions.append(\n textButton('Ungroup', () => {\n board.ungroup();\n d.close();\n }),\n );\n actions.append(\n textButton('Bring to front', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'front' })),\n { origin: 'user', label: 'Bring to front' },\n );\n d.close();\n }),\n textButton('Send to back', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'back' })),\n { origin: 'user', label: 'Send to back' },\n );\n d.close();\n }),\n );\n if (board.readonly)\n actions.querySelectorAll('button').forEach((action) => (action.disabled = true));\n d.append(actions);\n }\n function saveExport(format: UiExportFormat) {\n void board\n .export(format, {\n scope: 'page',\n padding: 40,\n background: true,\n ...(format === 'png' ? { scale: 2 } : {}),\n })\n .then((content) => {\n const name =\n board\n .read()\n .meta.title.replace(/[^a-z0-9 _-]/gi, '')\n .trim() || 'drawing';\n download(\n content,\n `${name}.${format === 'json' ? 'annie' : format}`,\n format === 'json' ? ANNIE_MIME : format === 'svg' ? 'image/svg+xml' : 'image/png',\n );\n })\n .catch(() => undefined);\n }\n function openExport() {\n if (formats.length === 1) {\n saveExport(formats[0]);\n return;\n }\n if (!exportButton) return;\n const panel = popover(exportButton, 'Export');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const choices: Record<UiExportFormat, [string, string]> = {\n png: ['PNG Image', 'image'],\n svg: ['SVG Image', 'image'],\n json: ['AnnieDoc format', 'code'],\n };\n for (const format of formats) {\n const [label, glyph] = choices[format];\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n saveExport(format);\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n panel.append(option);\n }\n showPopover(panel, exportButton);\n }\n function openMenu() {\n if (!brand) return;\n const panel = popover(brand, 'Board menu');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n action();\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n option.disabled = disabled;\n panel.append(option);\n };\n add('Open a drawing', 'upload', () => drawingInput?.click(), board.readonly);\n if (phoneChrome(board.stage.root.clientWidth, board.stage.root.clientHeight)) {\n add('Hand', 'hand', () => {\n board.setTool('hand');\n board.focus();\n });\n }\n add(board.grid ? 'Hide grid' : 'Show grid', 'grid', () => board.setGrid(!board.grid));\n const dark = board.stage.resolvedTheme === 'dark';\n add(dark ? 'Light appearance' : 'Dark appearance', dark ? 'sun' : 'moon', () =>\n board.setTheme(dark ? 'light' : 'dark'),\n );\n add('Documentation', 'book', () => {\n window.open('./docs/index.html', '_blank', 'noopener');\n });\n const github = el('a', 'ad-tool-option');\n github.href = GITHUB_REPO_URL;\n github.target = '_blank';\n github.rel = 'noopener noreferrer';\n github.title = 'GitHub';\n github.innerHTML = `${icon('github')}<span>GitHub</span>`;\n github.addEventListener('click', () => closePopover());\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n panel.append(github, separator, el('p', 'ad-menu-version', `v${PACKAGE_VERSION}`));\n showPopover(panel, brand);\n }\n function refresh() {\n undo.disabled = !board.canUndo;\n redo.disabled = !board.canRedo;\n renderPages();\n renderStyle();\n }\n const context = (event: Event) => {\n const { x, y, id } = (event as CustomEvent<Point & { id?: string }>).detail;\n const item = id ? board.get(id) : undefined;\n if (!item) {\n closePopover();\n return;\n }\n const bounds = board.stage.root.getBoundingClientRect();\n const menu = contextMenu('Element actions', { x: bounds.left + x, y: bounds.top + y });\n const locked = board.isLocked(item.id);\n if (item.kind === 'video' || item.kind === 'link')\n menu.add(hrefAction(item.kind), 'link', () => editHref(item.id), locked);\n if (!['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(item.kind))\n menu.add('Edit text', 'text', () => board.editText(item.id), locked);\n const order = (to: 'front' | 'back') =>\n board.apply([{ op: 'order', id: item.id, to }], {\n origin: 'user',\n label: to === 'front' ? 'Bring to front' : 'Send to back',\n });\n menu.add('Bring to front', 'front', () => order('front'), locked);\n menu.add('Send to back', 'back', () => order('back'), locked);\n menu.add(\n 'Duplicate',\n 'copy',\n () => {\n board.select([item.id]);\n board.duplicate();\n },\n locked,\n );\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n menu.panel.append(separator);\n menu.add(\n 'Delete',\n 'trash',\n () => {\n board.select([item.id]);\n board.deleteSelection();\n },\n locked,\n );\n menu.show();\n };\n board.host.addEventListener('ad-context', context);\n unsubs.push(\n board.on('change', refresh),\n board.on('select', () => {\n renderStyle();\n }),\n board.on('page', refresh),\n board.on('view', (state) => {\n if (activePopover?.popover === 'manual') closePopover();\n percentage.textContent = `${Math.round(state.zoom * 100)}%`;\n }),\n board.on('tool', (id) => {\n for (const b of ui.querySelectorAll<HTMLElement>('[data-tool]'))\n b.setAttribute('aria-pressed', String(id === b.dataset.tool));\n shapeButton.setAttribute('aria-pressed', String(shapeKinds.includes(id)));\n board.stage.root.dataset.adTool = id;\n renderStyle();\n }),\n );\n refresh();\n return () => {\n clearTimeout(pagePressTimer);\n closePopover();\n unsubs.forEach((fn) => fn());\n activeDialog?.close();\n board.host.removeEventListener('ad-context', context);\n ui.remove();\n };\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"ui-DWQtW0zJ.js","names":[],"sources":["../../node_modules/perfect-freehand/dist/esm/index.mjs","../../src/stage/paint.ts","../../src/porter/json.ts","../../src/ui/icons.ts","../../src/ui/version.ts","../../src/ui/index.ts"],"sourcesContent":["const{PI:e}=Math,t=e+1e-4,n=.5,r=[1,1];function i(e,t,n,r=e=>e){return e*r(.5-t*(.5-n))}const{min:a}=Math;function o(e,t,n){let r=a(1,t/n);return a(1,e+(a(1,1-r)-e)*(r*.275))}function s(e){return[-e[0],-e[1]]}function c(e,t){return[e[0]+t[0],e[1]+t[1]]}function l(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function u(e,t){return[e[0]-t[0],e[1]-t[1]]}function d(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function f(e,t){return[e[0]*t,e[1]*t]}function p(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function m(e,t){return[e[0]/t,e[1]/t]}function h(e){return[e[1],-e[0]]}function g(e,t){let n=t[0];return e[0]=t[1],e[1]=-n,e}function ee(e,t){return e[0]*t[0]+e[1]*t[1]}function _(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return Math.hypot(e[0],e[1])}function y(e,t){let n=e[0]-t[0],r=e[1]-t[1];return n*n+r*r}function b(e){return m(e,v(e))}function x(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function S(e,t,n){let r=Math.sin(n),i=Math.cos(n),a=e[0]-t[0],o=e[1]-t[1],s=a*i-o*r,c=a*r+o*i;return[s+t[0],c+t[1]]}function C(e,t,n,r){let i=Math.sin(r),a=Math.cos(r),o=t[0]-n[0],s=t[1]-n[1],c=o*a-s*i,l=o*i+s*a;return e[0]=c+n[0],e[1]=l+n[1],e}function w(e,t,n){return c(e,f(u(t,e),n))}function te(e,t,n,r){let i=n[0]-t[0],a=n[1]-t[1];return e[0]=t[0]+i*r,e[1]=t[1]+a*r,e}function T(e,t,n){return c(e,f(t,n))}const E=[0,0],D=[0,0],O=[0,0];function k(e,n){let r=T(e,b(h(u(e,c(e,[1,1])))),-n),i=[],a=1/13;for(let n=a;n<=1;n+=a)i.push(S(r,e,t*2*n));return i}function A(e,n,r){let i=[],a=1/r;for(let r=a;r<=1;r+=a)i.push(S(n,e,t*r));return i}function j(e,t,n){let r=u(t,n),i=f(r,.5),a=f(r,.51);return[u(e,i),u(e,a),c(e,a),c(e,i)]}function M(e,n,r,i){let a=[],o=T(e,n,r),s=1/i;for(let n=s;n<1;n+=s)a.push(S(o,e,t*3*n));return a}function ne(e,t,n){return[c(e,f(t,n)),c(e,f(t,n*.99)),u(e,f(t,n*.99)),u(e,f(t,n))]}function N(e,t,n){return e===!1||e===void 0?0:e===!0?Math.max(t,n):e}function re(e,t,n){return e.slice(0,10).reduce((e,r)=>{let i=r.pressure;return t&&(i=o(e,r.distance,n)),(e+i)/2},e[0].pressure)}function P(e,n={}){let{size:r=16,smoothing:a=.5,thinning:f=.5,simulatePressure:m=!0,easing:_=e=>e,start:v={},end:b={},last:x=!1}=n,{cap:S=!0,easing:w=e=>e*(2-e)}=v,{cap:T=!0,easing:P=e=>--e*e*e+1}=b;if(e.length===0||r<=0)return[];let F=e[e.length-1].runningLength,I=N(v.taper,r,F),L=N(b.taper,r,F),R=(r*a)**2,z=[],B=[],V=re(e,m,r),H=i(r,f,e[e.length-1].pressure,_),U,W=e[0].vector,G=e[0].point,K=G,q=G,J=K,Y=!1;for(let n=0;n<e.length;n++){let{pressure:a}=e[n],{point:s,vector:h,distance:v,runningLength:b}=e[n],x=n===e.length-1;if(!x&&F-b<3)continue;f?(m&&(a=o(V,v,r)),H=i(r,f,a,_)):H=r/2,U===void 0&&(U=H);let S=b<I?w(b/I):1,T=F-b<L?P((F-b)/L):1;H=Math.max(.01,H*Math.min(S,T));let k=(x?e[n]:e[n+1]).vector,A=x?1:ee(h,k),j=ee(h,W)<0&&!Y,M=A!==null&&A<0;if(j||M){g(E,W),p(E,E,H);for(let e=0;e<=1;e+=.07692307692307693)d(D,s,E),C(D,D,s,t*e),q=[D[0],D[1]],z.push(q),l(O,s,E),C(O,O,s,t*-e),J=[O[0],O[1]],B.push(J);G=q,K=J,M&&(Y=!0);continue}if(Y=!1,x){g(E,h),p(E,E,H),z.push(u(s,E)),B.push(c(s,E));continue}te(E,k,h,A),g(E,E),p(E,E,H),d(D,s,E),q=[D[0],D[1]],(n<=1||y(G,q)>R)&&(z.push(q),G=q),l(O,s,E),J=[O[0],O[1]],(n<=1||y(K,J)>R)&&(B.push(J),K=J),V=a,W=h}let X=[e[0].point[0],e[0].point[1]],Z=e.length>1?[e[e.length-1].point[0],e[e.length-1].point[1]]:c(e[0].point,[1,1]),Q=[],$=[];if(e.length===1){if(!(I||L)||x)return k(X,U||H)}else{I||L&&e.length===1||(S?Q.push(...A(X,B[0],13)):Q.push(...j(X,z[0],B[0])));let t=h(s(e[e.length-1].vector));L||I&&e.length===1?$.push(Z):T?$.push(...M(Z,t,H,29)):$.push(...ne(Z,t,H))}return z.concat($,B.reverse(),Q)}const F=[0,0];function I(e){return e!=null&&e>=0}function L(e,t={}){let{streamline:i=.5,size:a=16,last:o=!1}=t;if(e.length===0)return[];let s=.15+(1-i)*.85,l=Array.isArray(e[0])?e:e.map(({x:e,y:t,pressure:r=n})=>[e,t,r]);if(l.length===2){let e=l[1];l=l.slice(0,-1);for(let t=1;t<5;t++)l.push(w(l[0],e,t/4))}l.length===1&&(l=[...l,[...c(l[0],r),...l[0].slice(2)]]);let u=[{point:[l[0][0],l[0][1]],pressure:I(l[0][2])?l[0][2]:.25,vector:[...r],distance:0,runningLength:0}],f=!1,p=0,m=u[0],h=l.length-1;for(let e=1;e<l.length;e++){let t=o&&e===h?[l[e][0],l[e][1]]:w(m.point,l[e],s);if(_(m.point,t))continue;let r=x(t,m.point);if(p+=r,e<h&&!f){if(p<a)continue;f=!0}d(F,m.point,t),m={point:t,pressure:I(l[e][2])?l[e][2]:n,vector:b(F),distance:r,runningLength:p},u.push(m)}return u[0].vector=u[1]?.vector||[0,0],u}function R(e,t={}){return P(L(e,t),t)}var z=R;export{z as default,R as getStroke,P as getStrokeOutlinePoints,L as getStrokePoints};\n//# sourceMappingURL=index.mjs.map","import { getStroke } from 'perfect-freehand';\nimport { CARD_CORNER } from '../core/defaults';\nimport type { Item, ItemText, Point, Style } from '../core/types';\n\nexport const SVG_NS = 'http://www.w3.org/2000/svg';\nexport const fonts = {\n sans: 'Nunito Variable, Nunito, ui-rounded, system-ui, sans-serif',\n serif: 'Georgia, serif',\n mono: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n hand: 'Comic Sans MS, Chalkboard SE, cursive',\n};\nexport const DEFAULT_FONT = 'hand' satisfies keyof typeof fonts;\nexport function fontFamily(font?: ItemText['font']): string {\n return fonts[font ?? DEFAULT_FONT];\n}\nconst light: Record<string, string> = {\n ink: '#103639',\n slate: '#606062',\n coral: '#FF9302',\n amber: '#FFC68A',\n moss: '#AAF1AC',\n teal: '#05D9AB',\n sky: '#92CAFF',\n violet: '#8F93F9',\n rose: '#F89B97',\n paper: '#FFFFFF',\n};\nconst dark: Record<string, string> = {\n ...light,\n ink: '#E9F7F3',\n slate: '#B6C5C1',\n paper: '#173D40',\n};\nexport function color(value = 'ink', theme: 'light' | 'dark' = 'light'): string {\n return (theme === 'dark' ? dark : light)[value] ?? value;\n}\nfunction rgb(value: string): number[] | undefined {\n const named: Record<string, string> = {\n black: '#000000',\n white: '#ffffff',\n red: '#ff0000',\n blue: '#0000ff',\n green: '#008000',\n yellow: '#ffff00',\n transparent: '#00000000',\n };\n value = named[value.toLowerCase()] ?? value;\n if (/^#[\\da-f]{3,4}$/i.test(value))\n value = `#${[...value.slice(1)].map((channel) => channel + channel).join('')}`;\n if (/^#[\\da-f]{6}([\\da-f]{2})?$/i.test(value))\n return [1, 3, 5]\n .map((index) => parseInt(value.slice(index, index + 2), 16))\n .concat(value.length === 9 ? parseInt(value.slice(7, 9), 16) / 255 : 1);\n if (!/^rgba?\\(/i.test(value)) return undefined;\n const channels = value.match(/[\\d.]+%?/g);\n if (!channels || channels.length < 3) return undefined;\n return channels\n .slice(0, 3)\n .map((channel) => parseFloat(channel) * (channel.endsWith('%') ? 2.55 : 1))\n .concat(\n channels[3] === undefined\n ? 1\n : parseFloat(channels[3]) / (channels[3].endsWith('%') ? 100 : 1),\n );\n}\nfunction luminance(channels: number[]): number {\n return channels\n .slice(0, 3)\n .map((channel) => {\n const value = channel / 255;\n return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;\n })\n .reduce((sum, channel, index) => sum + channel * [0.2126, 0.7152, 0.0722][index], 0);\n}\n/** Preserve explicit text colors and keep labels legible on opaque shape fills. */\nexport function labelColor(item: Item, theme: 'light' | 'dark'): string {\n if (item.kind === 'text') return color(item.style?.stroke ?? 'ink', theme);\n const ink = color('ink', theme),\n style = styleFor(item, theme);\n if (['connector', 'line'].includes(item.kind) || style.fillMode !== 'solid') return ink;\n const fill = rgb(style.fill);\n if (!fill) return ink;\n const paper = rgb(color('paper', theme))!;\n const background = luminance(\n fill.slice(0, 3).map((channel, index) => channel * fill[3] + paper[index] * (1 - fill[3])),\n );\n const contrast = (value: string) => {\n const foreground = luminance(rgb(value)!);\n return (Math.max(background, foreground) + 0.05) / (Math.min(background, foreground) + 0.05);\n };\n for (const candidate of [ink, color('ink', theme === 'dark' ? 'light' : 'dark')])\n if (contrast(candidate) >= 4.5) return candidate;\n return contrast('#0F0B0A') >= contrast('#FFFFFF') ? '#0F0B0A' : '#FFFFFF';\n}\nexport function fontSize(text?: ItemText): number {\n return typeof text?.size === 'number'\n ? text.size\n : { s: 14, m: 18, l: 26, xl: 36 }[text?.size ?? 'm'];\n}\nexport function esc(value: unknown): string {\n return String(value ?? '').replace(\n /[&<>\"']/g,\n (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char]!,\n );\n}\nexport function round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\nexport function pathFromPoints(points: Point[], closed = false): string {\n return (\n points\n .map((point, index) => `${index ? 'L' : 'M'}${round(point.x)},${round(point.y)}`)\n .join(' ') + (closed ? ' Z' : '')\n );\n}\nexport function freehandPath(item: Item): string {\n const points = item.points ?? [];\n if (!points.length) return '';\n if (item.closed)\n return pathFromPoints(\n points.map(([x, y]) => ({ x, y })),\n true,\n );\n const stroke = getStroke(\n points.map(([x, y, pressure]) => ({ x, y, pressure })),\n {\n size: (item.style?.strokeWidth ?? 2) * 2.2,\n thinning: 0.45,\n smoothing: 0.6,\n streamline: 0.45,\n simulatePressure: points.every((point) => point[2] === undefined),\n last: true,\n },\n );\n if (!stroke.length) return '';\n return `M${stroke.map((point) => `${round(point[0])},${round(point[1])}`).join(' L')} Z`;\n}\nexport function shapePath(item: Item): string {\n const w = item.w,\n h = item.h;\n if (item.kind === 'ellipse')\n return `M${w},${h / 2}a${w / 2},${h / 2} 0 1 0 ${-w},0a${w / 2},${h / 2} 0 1 0 ${w},0Z`;\n if (item.kind === 'diamond') return `M${w / 2},0L${w},${h / 2}L${w / 2},${h}L0,${h / 2}Z`;\n if (item.kind === 'line')\n return pathFromPoints(\n (\n item.points ?? [\n [0, 0],\n [w, h],\n ]\n ).map(([x, y]) => ({ x, y })),\n );\n if (item.kind === 'path') return freehandPath(item);\n const corner = Math.max(0, Math.min(item.style?.corner ?? CARD_CORNER, w / 2, h / 2));\n return `M${corner},0H${w - corner}Q${w},0 ${w},${corner}V${h - corner}Q${w},${h} ${w - corner},${h}H${corner}Q0,${h} 0,${h - corner}V${corner}Q0,0 ${corner},0Z`;\n}\nexport function styleFor(item: Item, theme: 'light' | 'dark'): Required<Style> {\n const fill = item.style?.fill ?? (item.kind === 'note' ? 'moss' : 'none');\n return {\n stroke: color(item.style?.stroke ?? 'ink', theme),\n strokeWidth: item.style?.strokeWidth ?? (item.kind === 'note' ? 0 : 2),\n dash: item.style?.dash ?? 'solid',\n fill: color(fill, theme),\n fillMode: item.style?.fillMode ?? 'solid',\n corner: item.style?.corner ?? CARD_CORNER,\n opacity: item.style?.opacity ?? 1,\n };\n}\nexport function shapeMarkup(\n item: Item,\n theme: 'light' | 'dark',\n uid: string,\n path = shapePath(item),\n): string {\n const style = styleFor(item, theme);\n const dash = style.dash === 'dashed' ? '8 6' : style.dash === 'dotted' ? '1 6' : '';\n const isPath = item.kind === 'path';\n const fill =\n item.kind === 'line' || item.kind === 'connector'\n ? 'none'\n : isPath\n ? item.closed && style.fill !== 'none'\n ? style.fill\n : style.stroke\n : style.fill;\n const hatchId = `ad_h_${uid.replace(/[^a-z0-9_-]/gi, '_')}`;\n const hatch = style.fillMode === 'hatch' && fill !== 'none' && !isPath;\n const defs = hatch\n ? `<defs><pattern id=\"${hatchId}\" width=\"8\" height=\"8\" patternUnits=\"userSpaceOnUse\"><path d=\"M-2 2L2-2M0 8L8 0M6 10L10 6\" fill=\"none\" stroke=\"${esc(fill)}\" stroke-opacity=\"0.5\" stroke-width=\"1.3\"/></pattern></defs>`\n : '';\n const fillAttr = hatch ? `url(#${hatchId})` : fill;\n const geometry = `<path d=\"${esc(path)}\" fill=\"${esc(fillAttr)}\"${style.fillMode === 'tint' && !isPath ? ' fill-opacity=\"0.22\"' : ''} stroke=\"${isPath && !item.closed ? 'none' : esc(style.stroke)}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/>`;\n return `${defs}${geometry}`;\n}\nexport function headMarkup(\n point: Point,\n previous: Point,\n kind: 'arrow' | 'dot' | 'none' | undefined,\n stroke: string,\n width: number,\n): string {\n if (!kind || kind === 'none') return '';\n if (kind === 'dot')\n return `<circle cx=\"${round(point.x)}\" cy=\"${round(point.y)}\" r=\"${Math.max(3, width * 2)}\" fill=\"${esc(stroke)}\"/>`;\n const angle = Math.atan2(point.y - previous.y, point.x - previous.x);\n const length = Math.max(10, width * 4.5);\n const spread = Math.PI / 6;\n const a = {\n x: point.x - Math.cos(angle - spread) * length,\n y: point.y - Math.sin(angle - spread) * length,\n };\n const b = {\n x: point.x - Math.cos(angle + spread) * length,\n y: point.y - Math.sin(angle + spread) * length,\n };\n return `<path d=\"${pathFromPoints([a, point, b])}\" fill=\"none\" stroke=\"${esc(stroke)}\" stroke-width=\"${width}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`;\n}\nexport function headsMarkup(points: Point[], item: Item, theme: 'light' | 'dark'): string {\n if (points.length < 2) return '';\n const style = styleFor(item, theme);\n return (\n headMarkup(points[0], points[1], item.heads?.start, style.stroke, style.strokeWidth) +\n headMarkup(\n points[points.length - 1],\n points[points.length - 2],\n item.heads?.end ?? (item.kind === 'connector' ? 'arrow' : 'none'),\n style.stroke,\n style.strokeWidth,\n )\n );\n}\n","import type { AnnieDoc } from '../core/types';\nexport const ANNIE_MIME = 'application/vnd.anniedrawing+json';\nexport function exportJSON(doc: AnnieDoc): string {\n return JSON.stringify(doc, null, 2);\n}\n","const paths: Record<string, string> = {\n select:\n '<path d=\"M5.8 3.8c-1-.4-1.7.4-1.4 1.4l4.9 14.4c.4 1.1 1.8 1.1 2.2 0l2.2-5.8 5.8-2.2c1.1-.4 1.1-1.8 0-2.2Z\"/>',\n hand: '<path d=\"M8 12V6a2 2 0 0 1 4 0v5-7a2 2 0 0 1 4 0v8-5a2 2 0 0 1 4 0v8c0 5-4 7-7 7-3 0-4-2-6-5l-3-4c-1-2 1-4 3-2l2 2\"/>',\n rect: '<rect x=\"3.75\" y=\"4.75\" width=\"16.5\" height=\"14.5\" rx=\"4\"/>',\n ellipse: '<ellipse cx=\"12\" cy=\"12\" rx=\"8.25\" ry=\"7.25\"/>',\n diamond:\n '<path d=\"m13.4 3.8 6.8 6.8a2 2 0 0 1 0 2.8l-6.8 6.8a2 2 0 0 1-2.8 0l-6.8-6.8a2 2 0 0 1 0-2.8l6.8-6.8a2 2 0 0 1 2.8 0Z\"/>',\n line: '<path d=\"m5.5 18.5 13-13\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"5\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/>',\n connector: '<path d=\"M4 18h5a3 3 0 0 0 3-3V9a3 3 0 0 1 3-3h5m-4-4 4 4-4 4\"/>',\n path: '<path d=\"M3.5 17.5c1.8-5 3.2-11 6-11 4 0-1 12 3 12 2.8 0 3.2-8 5.5-8 1.6 0 2.3 2 2.5 4\"/>',\n text: '<path d=\"M5 7V4.5h14V7M12 4.5v15M8.5 19.5h7\"/>',\n note: '<path d=\"M7 3.75h10a3.25 3.25 0 0 1 3.25 3.25v7.1a2 2 0 0 1-.6 1.4l-4.2 4.2a2 2 0 0 1-1.4.6H7A3.25 3.25 0 0 1 3.75 17V7A3.25 3.25 0 0 1 7 3.75Z\"/><path d=\"M20 14h-3.5a2.5 2.5 0 0 0-2.5 2.5V20\"/>',\n lock: '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 8 0v3M12 14v3\"/>',\n unlock:\n '<rect x=\"5\" y=\"10\" width=\"14\" height=\"11\" rx=\"3.5\"/><path d=\"M8 10V7a4 4 0 0 1 7.5-2M12 14v3\"/>',\n opacity:\n '<circle cx=\"12\" cy=\"12\" r=\"8.5\"/><path d=\"M12 3.5a8.5 8.5 0 0 1 0 17Z\" fill=\"currentColor\" stroke=\"none\"/>',\n front:\n '<rect x=\"8\" y=\"3.5\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 16v1A3.5 3.5 0 0 1 12 20.5H7A3.5 3.5 0 0 1 3.5 17v-5A3.5 3.5 0 0 1 7 8.5h1\"/>',\n back: '<rect x=\"3.5\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M8.5 8V7A3.5 3.5 0 0 1 12 3.5h5A3.5 3.5 0 0 1 20.5 7v5A3.5 3.5 0 0 1 17 15.5h-1\"/>',\n eraser:\n '<path d=\"m13.2 4.3-9 9a2.4 2.4 0 0 0 0 3.4L7.5 20h4l8.2-8.2a2.4 2.4 0 0 0 0-3.4l-4.1-4.1a1.7 1.7 0 0 0-2.4 0ZM8 10.5l6 6M11.5 20H21\"/>',\n undo: '<path d=\"m8 5-4.5 4.5L8 14M4 9.5h9.5a5.5 5.5 0 0 1 0 11H11\"/>',\n redo: '<path d=\"m16 5 4.5 4.5L16 14m4-4.5h-9.5a5.5 5.5 0 0 0 0 11H13\"/>',\n plus: '<path d=\"M12 5.5v13M5.5 12h13\"/>',\n minus: '<path d=\"M5.5 12h13\"/>',\n fit: '<path d=\"M8.5 3.75h-3a1.75 1.75 0 0 0-1.75 1.75v3m11.75-4.75h3a1.75 1.75 0 0 1 1.75 1.75v3M3.75 15.5v3a1.75 1.75 0 0 0 1.75 1.75h3m11.75-4.75v3a1.75 1.75 0 0 1-1.75 1.75h-3\"/>',\n chevron: '<path d=\"m7 9.5 3.6 3.6a2 2 0 0 0 2.8 0L17 9.5\"/>',\n download: '<path d=\"M12 3.5v11m-4-4 4 4 4-4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n upload: '<path d=\"M12 15V4m-4 4 4-4 4 4M4.5 15.5v2A3 3 0 0 0 7.5 20h9a3 3 0 0 0 3-2.5v-2\"/>',\n code: '<path d=\"m7 7-4 4a1.4 1.4 0 0 0 0 2l4 4m10-10 4 4a1.4 1.4 0 0 1 0 2l-4 4M14 4l-4 16\"/>',\n close: '<path d=\"m6.5 6.5 11 11m-11 0 11-11\"/>',\n more: '<circle cx=\"5\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/>',\n image:\n '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"m4 17 3.6-3.6a1.3 1.3 0 0 1 1.8 0l2.1 2.1 3.4-5.1a1.3 1.3 0 0 1 2.2 0L20 15\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2.5v1M12 20.5v1M2.5 12h1m17 0h1M5.3 5.3l.7.7m12 12 .7.7M5.3 18.7l.7-.7M18 6l.7-.7\"/>',\n moon: '<path d=\"M20 14.5a8.2 8.2 0 0 1-10.5-10c-3.9.7-6.4 3.7-6.4 7.5a8.1 8.1 0 0 0 16.9 2.5Z\"/>',\n trash:\n '<path d=\"M4 6.5h16M9 6.5V5a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 5v1.5m-9 0 .7 11.2A3 3 0 0 0 9.7 20.5h4.6a3 3 0 0 0 3-2.8L18 6.5M10 10.5v6m4-6v6\"/>',\n copy: '<rect x=\"8\" y=\"8\" width=\"12.5\" height=\"12.5\" rx=\"3.5\"/><path d=\"M15.5 8V7A3.5 3.5 0 0 0 12 3.5H7A3.5 3.5 0 0 0 3.5 7v5A3.5 3.5 0 0 0 7 15.5h1\"/>',\n grid: '<rect x=\"3.5\" y=\"3.5\" width=\"17\" height=\"17\" rx=\"4\"/><path d=\"M9 4v16m6-16v16M4 9h16M4 15h16\"/>',\n book: '<path d=\"M12 5.5c-2.6-2-5.2-2.5-8-2v15c2.8-.5 5.4 0 8 2 2.6-2 5.2-2.5 8-2v-15c-2.8-.5-5.4 0-8 2Zm0 0v15\"/>',\n github:\n '<path fill=\"currentColor\" stroke=\"none\" d=\"M12 1C5.922 1 1 5.922 1 12c0 4.867 3.149 8.979 7.521 10.437.55.096.75-.232.75-.546 0-.262-.013-1.13-.013-2.049-3.06.56-3.703-1.31-3.703-1.31-.498-1.316-1.216-1.667-1.216-1.667-.991-.68.075-.668.075-.668 1.109.075 1.688 1.264 1.688 1.264.982 1.686 2.573 1.2 3.201.907.096-.699.381-1.2.695-1.478-2.448-.282-5.022-1.226-5.022-5.451 0-1.2.426-2.187 1.12-2.953-.113-.275-.487-1.392.107-2.9 0 0 .917-.292 3.011 1.12.873-.24 1.809-.36 2.74-.36.93 0 1.867.12 2.74.36 2.077-1.413 3.01-1.12 3.01-1.12.596 1.508.221 2.625.108 2.9.697.766 1.12 1.748 1.12 2.953 0 4.237-2.578 5.163-5.034 5.437.39.338.746 1.016.746 2.056 0 1.478-.014 2.666-.014 3.025 0 .304.202.655.753.545C19.854 20.979 23 16.859 23 12c0-6.078-4.922-11-11-11Z\"/>',\n alignLeft: '<path d=\"M4 5h16M4 12h10M4 19h16\"/>',\n alignCenter: '<path d=\"M4 5h16M7 12h10M4 19h16\"/>',\n alignRight: '<path d=\"M4 5h16M10 12h10M4 19h16\"/>',\n align:\n '<path d=\"M4 3.5v17\"/><rect x=\"8\" y=\"5\" width=\"12.5\" height=\"5\" rx=\"1.75\"/><rect x=\"8\" y=\"14\" width=\"8.5\" height=\"5\" rx=\"1.75\"/>',\n shapes:\n '<rect x=\"3\" y=\"3\" width=\"8.5\" height=\"8.5\" rx=\"2.5\"/><circle cx=\"17.3\" cy=\"6.7\" r=\"3.7\"/><path d=\"m6 14-3.5 6h8L7 14a.6.6 0 0 0-1 0Z\"/><rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"2\" transform=\"rotate(45 17 17)\"/>',\n link: '<path d=\"M10 14.5 8.8 15.7a3.6 3.6 0 1 1-5.1-5.1l3.2-3.2a3.6 3.6 0 0 1 5.1 0\"/><path d=\"m14 9.5 1.2-1.2a3.6 3.6 0 0 1 5.1 5.1l-3.2 3.2a3.6 3.6 0 0 1-5.1 0\"/>',\n};\nexport function icon(name: string) {\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths[name] ?? paths.select}</svg>`;\n}\nexport function button(\n label: string,\n name: string,\n handler: () => void,\n className = 'ad-icon-button',\n) {\n const el = document.createElement('button');\n el.type = 'button';\n el.className = className;\n el.title = label;\n el.setAttribute('aria-label', label);\n el.innerHTML = icon(name);\n el.addEventListener('click', () => {\n el.focus();\n handler();\n });\n return el;\n}\n","/** npm package version shown in the AnnieDrawing menu. Keep in sync with package.json. */\nexport const PACKAGE_VERSION = '0.3.3';\nexport const SITE_URL = 'https://anniedrawing.com';\nexport const GITHUB_REPO_URL = 'https://github.com/Frontierz-AI/AnnieDrawing';\n","import type { Board } from '../board';\nimport type { Item, Point } from '../core/types';\nimport { button, icon } from './icons';\nimport { GITHUB_REPO_URL, PACKAGE_VERSION } from './version';\nimport { color as resolveColor, DEFAULT_FONT, fonts, fontSize, styleFor } from '../stage/paint';\nimport { pageId } from '../core/ids';\nimport { ANNIE_MIME } from '../porter/json';\n/** PNG, SVG, or AnnieDoc (`json`, saved as `.annie`). */\nexport type UiExportFormat = 'png' | 'svg' | 'json';\n/** Header controls. Pass `ui: false` to `createBoard` to omit all editor chrome. */\nexport interface UiOptions {\n /** AnnieDrawing control. Default `true`. */\n menu?: boolean;\n /**\n * Export control. Default `['png', 'svg']`. `false` hides it. Include `'json'` for AnnieDoc.\n * One format downloads on click; two or more open a menu.\n */\n export?: boolean | UiExportFormat[];\n /** Page chips, add-page, and All pages. Default true. */\n pages?: boolean;\n}\nconst defaultExportFormats: UiExportFormat[] = ['png', 'svg'];\nfunction exportFormats(value: UiOptions['export']): UiExportFormat[] {\n if (value === false) return [];\n if (!Array.isArray(value)) return [...defaultExportFormats];\n const seen = new Set<UiExportFormat>();\n const formats: UiExportFormat[] = [];\n for (const format of value) {\n if (format !== 'png' && format !== 'svg' && format !== 'json') continue;\n if (seen.has(format)) continue;\n seen.add(format);\n formats.push(format);\n }\n return formats;\n}\nconst tools = [\n ['select', 'Select', 'V'],\n ['hand', 'Hand', 'H'],\n ['rect', 'Rectangle', 'R'],\n ['ellipse', 'Ellipse', 'O'],\n ['diamond', 'Diamond', 'D'],\n ['connector', 'Arrow', 'A'],\n ['line', 'Line', 'L'],\n ['path', 'Draw', 'P'],\n ['text', 'Text', 'T'],\n ['note', 'Sticky note', 'N'],\n ['eraser', 'Eraser', 'E'],\n];\nconst palette = [\n ['ink', 'Ink'],\n ['paper', 'Paper'],\n ['teal', 'Frontierz green'],\n ['moss', 'Soft green'],\n ['coral', 'Orange'],\n ['violet', 'Lavender'],\n ['slate', 'Slate'],\n ['amber', 'Peach'],\n ['sky', 'Sky blue'],\n ['rose', 'Rose'],\n ['none', 'No fill'],\n];\n/** Narrow hosts, or a short tablet / phone-landscape host. */\nfunction phoneChrome(width: number, height: number) {\n return width <= 700 || (width <= 1023 && height <= 640);\n}\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className = '', text?: string) {\n const node = document.createElement(tag);\n node.className = className;\n if (text) node.textContent = text;\n return node;\n}\nfunction textButton(label: string, action: () => void, kind = 'ad-button') {\n const b = el('button', kind, label);\n b.type = 'button';\n b.addEventListener('click', () => {\n b.focus();\n action();\n });\n return b;\n}\nfunction field(label: string, input: HTMLElement) {\n const wrapper = el('label', 'ad-field');\n wrapper.append(el('span', 'ad-field-label', label), input);\n return wrapper;\n}\nfunction select(values: [string, string][], value: string, change: (value: string) => void) {\n const input = el('select');\n values.forEach(([v, text]) => {\n const o = el('option', '', text);\n o.value = v;\n input.append(o);\n });\n if (!values.some(([v]) => v === value)) {\n const custom = el('option', '', value);\n custom.value = value;\n input.append(custom);\n }\n input.value = value;\n input.onchange = () => change(input.value);\n return input;\n}\nfunction download(content: string | Blob, name: string, type: string) {\n const url = URL.createObjectURL(\n typeof content === 'string' ? new Blob([content], { type }) : content,\n );\n const link = el('a');\n link.href = url;\n link.download = name;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\nexport function mountUI(board: Board, options: UiOptions = {}): () => void {\n const ui = el('div', 'ad-ui');\n board.stage.root.append(ui);\n const unsubs: (() => void)[] = [];\n let activeDialog: HTMLDialogElement | undefined;\n function dialog(title: string) {\n closePopover();\n activeDialog?.close();\n const previous = document.activeElement as HTMLElement;\n const d = el('dialog', 'ad-dialog');\n const head = el('div', 'ad-dialog-head');\n const copy = el('div');\n copy.append(el('h2', '', title));\n head.append(\n copy,\n button('Close', 'close', () => d.close()),\n );\n d.append(head);\n d.addEventListener('click', (e) => {\n if (e.target === d) {\n const r = d.getBoundingClientRect();\n if (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom)\n d.close();\n }\n });\n d.addEventListener('close', () => {\n d.remove();\n if (activeDialog === d) activeDialog = undefined;\n if (!activeDialog) {\n refresh();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n }\n });\n ui.append(d);\n activeDialog = d;\n d.showModal();\n return d;\n }\n let activePopover: HTMLElement | undefined;\n let popoverTrigger: HTMLButtonElement | undefined;\n let pagePressTimer: ReturnType<typeof setTimeout> | undefined;\n function closePopover() {\n activePopover?.hidePopover();\n activePopover?.remove();\n activePopover = undefined;\n popoverTrigger?.setAttribute('aria-expanded', 'false');\n if (popoverTrigger) popoverTrigger.popoverTargetElement = null;\n popoverTrigger = undefined;\n }\n function popover(trigger: HTMLButtonElement | undefined, label: string) {\n if (trigger && popoverTrigger === trigger && activePopover?.matches(':popover-open')) {\n closePopover();\n return;\n }\n closePopover();\n const panel = el('div', 'ad-popover');\n panel.popover = 'auto';\n panel.setAttribute('role', 'group');\n panel.setAttribute('aria-label', label);\n const previous = document.activeElement as HTMLElement;\n if (trigger) {\n trigger.setAttribute('aria-expanded', 'true');\n trigger.popoverTargetElement = panel;\n trigger.popoverTargetAction = 'show';\n }\n activePopover = panel;\n popoverTrigger = trigger;\n panel.addEventListener('toggle', () => {\n if (activePopover === panel && !panel.matches(':popover-open'))\n trigger?.setAttribute('aria-expanded', 'false');\n });\n panel.addEventListener('keydown', (event) => {\n event.stopPropagation();\n if (event.key === 'Escape' || (event.key === 'Tab' && panel.popover === 'manual')) {\n if (event.key === 'Escape') event.preventDefault();\n closePopover();\n if (previous?.isConnected) previous.focus();\n else board.focus();\n } else if (\n !(event.target instanceof HTMLInputElement) &&\n ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)\n ) {\n const items = popoverItems(panel);\n const current = items.indexOf(document.activeElement as HTMLElement);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? items.length - 1\n : (current +\n (event.key === 'ArrowDown' || event.key === 'ArrowRight' ? 1 : -1) +\n items.length) %\n items.length;\n event.preventDefault();\n items[next]?.focus();\n }\n });\n ui.append(panel);\n return panel;\n }\n function showPopover(\n panel: HTMLElement,\n trigger: HTMLButtonElement,\n alignTo: HTMLElement = trigger,\n ) {\n panel.showPopover();\n const anchor = alignTo.getBoundingClientRect(),\n bounds = board.stage.root.getBoundingClientRect();\n const mobile = phoneChrome(bounds.width, bounds.height),\n width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n const besideToolbar = trigger.closest('.ad-toolbar') && !mobile;\n const left = besideToolbar\n ? anchor.right + 12\n : trigger.closest('.ad-header') && anchor.left < bounds.left + bounds.width / 2\n ? anchor.left\n : anchor.right - width;\n const top = besideToolbar\n ? anchor.top\n : anchor.top > bounds.top + bounds.height / 2\n ? anchor.top - height - 10\n : anchor.bottom + 10;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(left, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(top, bounds.bottom - height - 12))}px`;\n popoverItems(panel)[0]?.focus();\n }\n function popoverItems(panel: HTMLElement) {\n return [...panel.querySelectorAll<HTMLElement>('button:not(:disabled), a[href]')];\n }\n function contextMenu(label: string, point: Point) {\n const panel = popover(undefined, label)!;\n // A native auto popover dismisses on the right-button release that opened it.\n panel.popover = 'manual';\n panel.classList.add('ad-context-menu');\n panel.setAttribute('role', 'menu');\n panel.tabIndex = -1;\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = textButton(\n label,\n () => {\n closePopover();\n board.focus();\n action();\n },\n 'ad-tool-option',\n );\n option.insertAdjacentHTML('afterbegin', icon(glyph));\n option.setAttribute('role', 'menuitem');\n option.disabled = board.readonly || disabled;\n if (glyph === 'trash') option.classList.add('ad-danger');\n panel.append(option);\n };\n const show = () => {\n panel.showPopover();\n const bounds = board.stage.root.getBoundingClientRect();\n const width = Math.min(228, bounds.width - 24);\n panel.style.width = `${width}px`;\n const height = panel.getBoundingClientRect().height;\n panel.style.left = `${Math.max(bounds.left + 12, Math.min(point.x, bounds.right - width - 12))}px`;\n panel.style.top = `${Math.max(bounds.top + 12, Math.min(point.y, bounds.bottom - height - 12))}px`;\n (panel.querySelector<HTMLButtonElement>('button:not(:disabled)') ?? panel).focus();\n };\n return { panel, add, show };\n }\n const hideOnResize = () => closePopover();\n const dismissContext = (event: PointerEvent) => {\n if (activePopover?.popover === 'manual' && !activePopover.contains(event.target as Node))\n closePopover();\n };\n window.addEventListener('resize', hideOnResize);\n window.addEventListener('pointerdown', dismissContext, true);\n unsubs.push(() => {\n window.removeEventListener('resize', hideOnResize);\n window.removeEventListener('pointerdown', dismissContext, true);\n });\n const showMenu = options.menu !== false;\n const formats = exportFormats(options.export);\n const header = el('header', 'ad-header');\n let brand: HTMLButtonElement | undefined;\n let drawingInput: HTMLInputElement | undefined;\n let exportButton: HTMLButtonElement | undefined;\n if (showMenu) {\n brand = button('Board menu', 'chevron', openMenu, 'ad-brand');\n brand.innerHTML =\n '<span class=\"ad-brand-mark\" aria-hidden=\"true\"><svg viewBox=\"0 0 40 40\"><path d=\"M9 29 20 8l11 21M14 22h12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><circle cx=\"32\" cy=\"9\" r=\"2.5\" fill=\"currentColor\"/></svg></span><span class=\"ad-brand-name\">AnnieDrawing</span>' +\n icon('chevron');\n brand.setAttribute('aria-haspopup', 'true');\n brand.setAttribute('aria-expanded', 'false');\n drawingInput = el('input');\n drawingInput.type = 'file';\n drawingInput.accept = '.annie,.json,application/json';\n drawingInput.hidden = true;\n drawingInput.onchange = () => {\n const file = drawingInput?.files?.[0];\n if (drawingInput) drawingInput.value = '';\n if (file)\n void file\n .text()\n .then((value) => board.load(JSON.parse(value)))\n .catch(() => undefined);\n };\n header.append(brand);\n }\n if (formats.length) {\n const actions = el('div', 'ad-header-actions');\n exportButton = textButton('Export', openExport, 'ad-button ad-primary');\n exportButton.insertAdjacentHTML('afterbegin', icon('download'));\n if (formats.length > 1) {\n exportButton.setAttribute('aria-haspopup', 'true');\n exportButton.setAttribute('aria-expanded', 'false');\n }\n actions.append(exportButton);\n header.append(actions);\n }\n if (!showMenu) header.classList.add('ad-header-end');\n if (showMenu || formats.length) ui.append(header);\n if (drawingInput) ui.append(drawingInput);\n const toolbar = el('nav', 'ad-toolbar');\n toolbar.setAttribute('aria-label', 'Drawing tools');\n function toolButton(id: string, expanded = false) {\n const [, label, key] = tools.find((tool) => tool[0] === id)!;\n const b = button(\n label,\n id,\n () => {\n closePopover();\n board.setTool(id);\n board.focus();\n },\n expanded ? 'ad-tool-option' : 'ad-icon-button',\n );\n b.dataset.tool = id;\n b.setAttribute('aria-keyshortcuts', key);\n b.setAttribute('aria-pressed', String(board.tool === id));\n b.innerHTML += expanded ? `<span>${label}</span>` : `<span class=\"ad-tooltip\">${label}</span>`;\n if (board.readonly && id !== 'hand' && id !== 'select') b.disabled = true;\n return b;\n }\n const shapeKinds = ['rect', 'ellipse', 'diamond', 'line', 'connector'];\n const shapeButton = button('Shapes', 'shapes', () => {\n const panel = popover(shapeButton, 'Shapes');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n panel.append(...shapeKinds.map((id) => toolButton(id, true)));\n showPopover(panel, shapeButton);\n });\n shapeButton.setAttribute('aria-haspopup', 'true');\n shapeButton.setAttribute('aria-expanded', 'false');\n shapeButton.innerHTML +=\n '<span class=\"ad-tool-corner\"></span><span class=\"ad-tooltip\">Shapes</span>';\n const imageInput = el('input');\n imageInput.type = 'file';\n imageInput.accept = 'image/png,image/jpeg,image/webp,image/gif,image/avif';\n imageInput.hidden = true;\n imageInput.onchange = () => {\n if (imageInput.files?.[0]) void board.addImage(imageInput.files[0]).catch(() => undefined);\n imageInput.value = '';\n };\n const imageButton = button('Add image', 'image', () => {\n closePopover();\n imageInput.click();\n });\n imageButton.innerHTML += '<span class=\"ad-tooltip\">Add image</span>';\n imageButton.disabled = board.readonly;\n const hand = toolButton('hand');\n if (showMenu) hand.classList.add('ad-desktop-tool');\n toolbar.append(\n toolButton('select'),\n hand,\n toolButton('eraser'),\n el('div', 'ad-toolbar-divider'),\n shapeButton,\n toolButton('path'),\n toolButton('text'),\n toolButton('note'),\n imageButton,\n imageInput,\n );\n ui.append(toolbar);\n const styleDock = el('aside', 'ad-style-dock');\n styleDock.setAttribute('aria-label', 'Selection style');\n styleDock.hidden = true;\n const stylePanel = el('div', 'ad-style-panel');\n const deselect = button('Deselect', 'chevron', () => board.select([]));\n deselect.classList.add('ad-style-dismiss');\n styleDock.append(deselect, stylePanel);\n ui.append(styleDock);\n const footer = el('footer', 'ad-footer');\n const undo = button('Undo', 'undo', () => board.undo()),\n redo = button('Redo', 'redo', () => board.redo());\n undo.setAttribute('aria-keyshortcuts', 'Meta+Z Control+Z');\n redo.setAttribute('aria-keyshortcuts', 'Meta+Shift+Z Control+Shift+Z');\n const pagesBar = el('nav', 'ad-pages');\n pagesBar.setAttribute('aria-label', 'Pages');\n const pageTabs = el('div', 'ad-page-tabs');\n pageTabs.setAttribute('role', 'tablist');\n pageTabs.setAttribute('aria-label', 'Pages');\n const overflow = button('All pages', 'more', openPages);\n overflow.setAttribute('aria-haspopup', 'true');\n overflow.setAttribute('aria-expanded', 'false');\n overflow.hidden = true;\n const newPage = button('Add page', 'plus', addPage);\n newPage.disabled = board.readonly;\n pagesBar.append(pageTabs, overflow, newPage);\n let pageState = '';\n function pageContext(id: string, name: string, point: Point) {\n const menu = contextMenu('Page actions', point);\n menu.add('Rename page', 'text', () => renamePage(id, name));\n menu.add(\n 'Delete page',\n 'trash',\n () => {\n board.apply([{ op: 'page.remove', id }], { origin: 'user', label: 'Delete page' });\n },\n board.read().pages.length === 1,\n );\n menu.show();\n }\n function pageButton(id: string, name: string, tab = false) {\n const pick = textButton(\n name,\n () => {\n closePopover();\n board.setPage(id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n },\n tab ? 'ad-page-tab' : 'ad-tool-option',\n );\n pick.title = name;\n pick.dataset.pageId = id;\n let held = false;\n let start: Point;\n pick.addEventListener('pointerdown', (event) => {\n held = false;\n if (event.pointerType !== 'touch') return;\n start = { x: event.clientX, y: event.clientY };\n clearTimeout(pagePressTimer);\n pagePressTimer = setTimeout(() => {\n held = true;\n pageContext(id, name, start);\n }, 500);\n });\n pick.addEventListener('pointermove', (event) => {\n if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > 10)\n clearTimeout(pagePressTimer);\n });\n for (const type of ['pointerup', 'pointercancel'])\n pick.addEventListener(type, () => clearTimeout(pagePressTimer));\n pick.addEventListener(\n 'click',\n (event) => {\n if (held) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n },\n true,\n );\n if (tab) {\n pick.setAttribute('role', 'tab');\n pick.setAttribute('aria-selected', String(board.pageId === id));\n pick.tabIndex = board.pageId === id ? 0 : -1;\n } else pick.setAttribute('aria-current', String(board.pageId === id));\n pick.addEventListener('contextmenu', (event) => {\n event.preventDefault();\n pageContext(id, name, { x: event.clientX, y: event.clientY });\n });\n pick.addEventListener('keydown', (event) => {\n if (event.key === 'ContextMenu' || (event.shiftKey && event.key === 'F10')) {\n event.preventDefault();\n const bounds = pick.getBoundingClientRect();\n pageContext(id, name, { x: bounds.left, y: bounds.top });\n } else if (tab && ['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n const pages = board.read().pages;\n const index = pages.findIndex((page) => page.id === id);\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? pages.length - 1\n : (index + (event.key === 'ArrowRight' ? 1 : -1) + pages.length) % pages.length;\n closePopover();\n board.setPage(pages[next].id);\n pageTabs.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]')?.focus();\n }\n });\n return pick;\n }\n let fittingPages = false;\n function fitPageTabs() {\n if (fittingPages) return;\n fittingPages = true;\n const probe = el('div', 'ad-page-tabs');\n try {\n const tabs = [...pageTabs.querySelectorAll<HTMLButtonElement>('button')];\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;width:max-content';\n const samples = tabs.map((tab) => {\n const sample = tab.cloneNode(true) as HTMLButtonElement;\n sample.hidden = false;\n sample.style.maxWidth = '';\n return sample;\n });\n const overflowSample = overflow.cloneNode(true) as HTMLButtonElement;\n overflowSample.hidden = false;\n probe.append(...samples, overflowSample);\n ui.append(probe);\n const widths = samples.map((sample) => sample.getBoundingClientRect().width);\n const overflowWidth = overflowSample.offsetWidth;\n probe.remove();\n const needed = widths.reduce((sum, width) => sum + width + 4, 0) + newPage.offsetWidth + 14;\n const room =\n pagesBar.offsetTop === footerRight.offsetTop\n ? footer.clientWidth - footerRight.offsetWidth - 16\n : pagesBar.clientWidth;\n const cap = Math.min(room, 520);\n const hideOverflow = needed <= cap;\n const nextHidden = tabs.map(() => false);\n const nextMax = tabs.map(() => '');\n if (!hideOverflow) {\n let remaining = Math.max(40, cap - newPage.offsetWidth - 14 - overflowWidth - 4);\n const selected = tabs.findIndex((tab) => tab.getAttribute('aria-selected') === 'true');\n for (const index of [\n selected,\n ...tabs.map((_, index) => index).filter((index) => index !== selected),\n ]) {\n if (index < 0) continue;\n if (index === selected) {\n nextMax[index] = `${remaining}px`;\n remaining -= Math.min(remaining, widths[index]) + 4;\n } else {\n nextHidden[index] = widths[index] > remaining;\n if (!nextHidden[index]) remaining -= widths[index] + 4;\n }\n }\n }\n overflow.hidden = hideOverflow;\n tabs.forEach((tab, index) => {\n tab.hidden = nextHidden[index];\n tab.style.maxWidth = nextMax[index];\n });\n } finally {\n probe.remove();\n fittingPages = false;\n }\n }\n function renderPages() {\n if (options.pages === false) return;\n const pages = board.read().pages;\n const state = JSON.stringify([board.pageId, pages.map(({ id, name }) => [id, name])]);\n if (state === pageState) return;\n pageState = state;\n pageTabs.replaceChildren(...pages.map((page) => pageButton(page.id, page.name, true)));\n fitPageTabs();\n }\n const pagesObserver = new ResizeObserver(fitPageTabs);\n if (options.pages !== false) {\n pagesObserver.observe(ui);\n unsubs.push(() => pagesObserver.disconnect());\n }\n function addPage() {\n closePopover();\n const id = pageId();\n const pages = board.read().pages;\n let number = pages.length + 1;\n while (pages.some((page) => page.name === `Page ${number}`)) number++;\n const result = board.apply(\n [{ op: 'page.add', page: { id, name: `Page ${number}`, items: [] } }],\n { origin: 'user', label: 'Add page' },\n );\n if (result.ok) board.setPage(id);\n }\n function openPages() {\n const panel = popover(overflow, 'All pages');\n if (!panel) return;\n panel.classList.add('ad-pages-popover');\n for (const page of board.read().pages) {\n const row = el('div', 'ad-page-row');\n row.append(pageButton(page.id, page.name));\n const actions = button(`Actions for ${page.name}`, 'more', () => {\n const bounds = actions.getBoundingClientRect();\n pageContext(page.id, page.name, { x: bounds.left, y: bounds.top });\n });\n row.append(actions);\n panel.append(row);\n }\n showPopover(panel, overflow);\n panel.querySelector<HTMLElement>('[aria-current=\"true\"]')?.scrollIntoView({ block: 'nearest' });\n }\n const footerRight = el('div', 'ad-footer-right');\n const zoom = el('div', 'ad-zoom');\n const percentage = textButton(\n '100%',\n () => {\n const panel = popover(percentage, 'Zoom controls');\n if (!panel) return;\n const row = el('div', 'ad-zoom-controls');\n row.append(\n button('Zoom out', 'minus', () => (board.view.zoom /= 1.2)),\n textButton('100%', () => (board.view.zoom = 1), 'ad-zoom-value'),\n button('Zoom in', 'plus', () => (board.view.zoom *= 1.2)),\n );\n panel.append(row);\n showPopover(panel, percentage, fitButton);\n },\n 'ad-zoom-value',\n );\n percentage.setAttribute('aria-label', 'Zoom controls');\n percentage.setAttribute('aria-haspopup', 'true');\n percentage.setAttribute('aria-expanded', 'false');\n const fitButton = button('Fit drawing', 'fit', () => board.view.fit());\n zoom.append(percentage, fitButton, undo, redo);\n footerRight.append(zoom);\n if (options.pages === false) footer.append(footerRight);\n else footer.append(pagesBar, footerRight);\n ui.append(footer);\n function renamePage(id: string, name: string) {\n if (board.readonly) return;\n const d = dialog('Name this page');\n const input = el('input');\n input.value = name;\n input.maxLength = 100;\n d.append(\n field('Page name', input),\n textButton(\n 'Save name',\n () => {\n if (input.value.trim())\n board.apply([{ op: 'page.set', id, patch: { name: input.value.trim() } }], {\n origin: 'user',\n label: 'Rename page',\n });\n d.close();\n },\n 'ad-button ad-primary',\n ),\n );\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n d.addEventListener(\n 'close',\n () => {\n const tab = pageTabs.querySelector<HTMLButtonElement>(`[data-page-id=\"${CSS.escape(id)}\"]`);\n if (tab && !tab.hidden) tab.focus();\n else if (!overflow.hidden) overflow.focus();\n },\n { once: true },\n );\n input.focus();\n input.select();\n }\n function hrefAction(kind: string) {\n return kind === 'video' ? 'Edit Video URL' : 'Edit URL';\n }\n function editHref(id: string) {\n if (board.readonly || board.isLocked(id)) return;\n const item = board.get(id);\n if (!item || (item.kind !== 'video' && item.kind !== 'link')) return;\n const video = item.kind === 'video';\n const d = dialog(video ? 'Edit video URL' : 'Edit URL');\n const input = el('input');\n input.type = 'text';\n input.inputMode = 'url';\n input.setAttribute('autocomplete', 'url');\n input.spellcheck = false;\n input.maxLength = 2000;\n input.value = item.href ?? '';\n input.setAttribute('aria-label', video ? 'Video URL' : 'URL');\n const error = el('p', 'ad-dialog-error');\n error.setAttribute('role', 'alert');\n error.hidden = true;\n const save = textButton(\n video ? 'Save video URL' : 'Save URL',\n () => {\n void (async () => {\n save.disabled = true;\n const result = await board.setHref(id, input.value);\n save.disabled = false;\n if (!result.ok) {\n const code = result.errors[0]?.code;\n error.textContent =\n code === 'LOCKED' || code === 'READONLY'\n ? (result.errors[0]?.message ?? 'This cannot be edited.')\n : video\n ? 'Use a YouTube or Vimeo URL.'\n : 'Use an http(s) URL.';\n error.hidden = false;\n input.setAttribute('aria-invalid', 'true');\n input.focus();\n return;\n }\n d.close();\n })();\n },\n 'ad-button ad-primary',\n );\n d.append(field(video ? 'Video URL' : 'URL', input), error, save);\n input.addEventListener('input', () => {\n error.hidden = true;\n input.removeAttribute('aria-invalid');\n });\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') d.querySelector<HTMLButtonElement>('.ad-primary')?.click();\n });\n input.focus();\n input.select();\n }\n let styleSelection = '';\n function renderStyle() {\n const locked = board.selection.some((id) => board.isLocked(id));\n if (board.tool !== 'select') {\n if (popoverTrigger && styleDock.contains(popoverTrigger)) closePopover();\n styleDock.hidden = true;\n return;\n }\n if (\n activeDialog ||\n (!locked &&\n document.activeElement instanceof HTMLInputElement &&\n document.activeElement.type === 'range' &&\n (styleDock.contains(document.activeElement) ||\n activePopover?.contains(document.activeElement)))\n )\n return;\n const focused = styleDock.contains(document.activeElement)\n ? (document.activeElement as HTMLElement)\n : undefined;\n const stylePopup =\n popoverTrigger && styleDock.contains(popoverTrigger)\n ? {\n label: popoverTrigger.getAttribute('aria-label'),\n focused: activePopover?.contains(document.activeElement),\n }\n : undefined;\n const focusLabel =\n focused?.getAttribute('aria-label') ?? (stylePopup?.focused ? stylePopup.label : undefined);\n const focusField = focused?.closest('label')?.querySelector('.ad-field-label')?.textContent;\n if (stylePopup) closePopover();\n const items = board.selection.map((id) => board.get(id)!).filter(Boolean);\n const selectedKey = items.map((item) => item.id).join(',');\n if (styleSelection !== selectedKey) {\n closePopover();\n }\n styleSelection = selectedKey;\n stylePanel.replaceChildren();\n styleDock.hidden = items.length === 0;\n if (!items.length) {\n if (stylePopup?.focused) board.focus();\n return;\n }\n const item = items[0],\n single = items.length === 1;\n const fillable = items.every((i) => ['rect', 'ellipse', 'diamond', 'note'].includes(i.kind));\n const stroked = items.every(\n (i) => !['image', 'html', 'video', 'link', 'group', 'text', 'note'].includes(i.kind),\n );\n const textOnly = items.every((i) => i.kind === 'text');\n const hasText = items.every(\n (i) => !['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(i.kind),\n );\n const colorControls = el('div', 'ad-color-controls');\n function colorControl(label: string, key: 'fill' | 'stroke') {\n const current =\n item.style?.[key] ?? (key === 'fill' ? (item.kind === 'note' ? 'moss' : 'none') : 'ink');\n const trigger = textButton(\n label,\n () => {\n const panel = popover(trigger, `${label} color`);\n if (!panel) return;\n panel.classList.add('ad-color-popover');\n for (const [token, name] of palette) {\n const b = el('button', `ad-swatch ${token === 'none' ? 'ad-swatch-none' : ''}`);\n b.type = 'button';\n b.style.setProperty('--swatch', resolveColor(token, board.stage.resolvedTheme));\n b.setAttribute('aria-label', `${label}: ${name}`);\n b.title = name;\n b.setAttribute('aria-pressed', String(current === token));\n b.onclick = () => {\n closePopover();\n board.defaultStyle[key] = token;\n board.updateSelection({ style: { [key]: token } });\n stylePanel.querySelector<HTMLButtonElement>(`[aria-label=\"${label}\"]`)?.focus();\n };\n panel.append(b);\n }\n showPopover(panel, trigger);\n },\n 'ad-color-control',\n );\n trigger.setAttribute('aria-label', label);\n trigger.setAttribute('aria-haspopup', 'true');\n trigger.setAttribute('aria-expanded', 'false');\n const swatch = el('span', `ad-color-preview ${current === 'none' ? 'ad-swatch-none' : ''}`);\n swatch.style.setProperty('--swatch', resolveColor(current, board.stage.resolvedTheme));\n trigger.prepend(swatch);\n colorControls.append(trigger);\n }\n if (fillable) colorControl('Fill', 'fill');\n if (stroked) colorControl('Line', 'stroke');\n if (textOnly) colorControl('Color', 'stroke');\n const opacityButton = textButton(\n 'Opacity',\n () => {\n const panel = popover(opacityButton, 'Opacity controls');\n if (!panel) return;\n panel.classList.add('ad-opacity-popover');\n const input = el('input');\n input.type = 'range';\n input.setAttribute('aria-label', 'Opacity');\n input.min = '0';\n input.max = '100';\n input.value = String(Math.round((board.get(item.id)?.style?.opacity ?? 1) * 100));\n const value = el('output', '', `${input.value}%`);\n const label = field('Opacity', input);\n label.querySelector('.ad-field-label')!.append(value);\n let first = true;\n input.oninput = () => {\n value.textContent = `${input.value}%`;\n board.apply(\n items.map(({ id }) => ({\n op: 'set',\n id,\n patch: { style: { opacity: Number(input.value) / 100 } },\n })),\n { origin: 'user', label: 'Change opacity', merge: !first },\n );\n first = false;\n };\n input.onchange = () => {\n first = true;\n };\n panel.append(label);\n showPopover(panel, opacityButton);\n input.focus();\n },\n 'ad-color-control',\n );\n opacityButton.insertAdjacentHTML('afterbegin', icon('opacity'));\n opacityButton.setAttribute('aria-label', 'Opacity');\n opacityButton.setAttribute('aria-haspopup', 'true');\n opacityButton.setAttribute('aria-expanded', 'false');\n if (items.every((item) => item.kind !== 'group')) colorControls.append(opacityButton);\n if (colorControls.childElementCount) stylePanel.append(colorControls);\n const updateText = (patch: Partial<NonNullable<Item['text']>>) =>\n board.apply(\n items.map((item) => ({\n op: 'set',\n id: item.id,\n patch: { text: { value: item.text?.value ?? '', ...patch } },\n })),\n { origin: 'user', label: 'Text style' },\n );\n function styleRow(label: string) {\n const row = el('div', 'ad-style-row');\n const group = el('div', 'ad-segments');\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', label);\n row.append(el('span', 'ad-style-label', label), group);\n stylePanel.append(row);\n return group;\n }\n function choices(\n group: HTMLElement,\n values: [string, string, string][],\n current: (item: Item) => string,\n change: (value: string) => void,\n ) {\n return values.map(([value, label, content]) => {\n const b = textButton(label, () => change(value), 'ad-segment');\n b.setAttribute('aria-label', label);\n b.title = label;\n b.setAttribute('aria-pressed', String(items.every((item) => current(item) === value)));\n b.innerHTML = content;\n group.append(b);\n return b;\n });\n }\n function lineIcon(width: number, dash = '') {\n return `<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3 12h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"${width}\" stroke-linecap=\"round\"${dash ? ` stroke-dasharray=\"${dash}\"` : ''}/></svg>`;\n }\n if (hasText) {\n choices(\n styleRow('Text'),\n [\n ['s', 'Text size: Small', 'S'],\n ['m', 'Text size: Medium', 'M'],\n ['l', 'Text size: Large', 'L'],\n ['xl', 'Text size: Extra large', 'XL'],\n ],\n (item) => ({ 14: 's', 18: 'm', 26: 'l', 36: 'xl' })[fontSize(item.text)] ?? '',\n (value) => updateText({ size: value as 'm' }),\n );\n choices(\n styleRow('Align'),\n [\n ['start', 'Align text left', icon('alignLeft')],\n ['center', 'Align text center', icon('alignCenter')],\n ['end', 'Align text right', icon('alignRight')],\n ],\n (item) => item.text?.align ?? (item.kind === 'text' ? 'start' : 'center'),\n (value) => updateText({ align: value as 'start' }),\n );\n const fontChoices: [keyof typeof fonts, string, string][] = [\n ['sans', 'Font: Friendly', 'Aa'],\n ['serif', 'Font: Serif', 'Aa'],\n ['mono', 'Font: Mono', 'Aa'],\n ['hand', 'Font: Handwritten', 'Aa'],\n ];\n choices(\n styleRow('Font'),\n fontChoices,\n (item) => item.text?.font ?? DEFAULT_FONT,\n (value) => updateText({ font: value as 'sans' }),\n ).forEach((button, index) => {\n button.style.fontFamily = fonts[fontChoices[index][0]];\n });\n }\n if (stroked) {\n choices(\n styleRow('Line'),\n [\n ['1', 'Line: Fine', lineIcon(1)],\n ['2', 'Line: Regular', lineIcon(2)],\n ['4', 'Line: Bold', lineIcon(4)],\n ['8', 'Line: Extra bold', lineIcon(6)],\n ],\n (item) => String(styleFor(item, board.stage.resolvedTheme).strokeWidth),\n (value) => board.updateSelection({ style: { strokeWidth: Number(value) } }),\n );\n if (items.every((item) => item.kind !== 'path' || item.closed)) {\n choices(\n styleRow('Pattern'),\n [\n ['solid', 'Pattern: Solid', lineIcon(2)],\n ['dashed', 'Pattern: Dashed', lineIcon(2, '5 4')],\n ['dotted', 'Pattern: Dotted', lineIcon(2, '1 5')],\n ],\n (item) => item.style?.dash ?? 'solid',\n (value) => board.updateSelection({ style: { dash: value as 'solid' } }),\n );\n }\n }\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Route',\n select(\n [\n ['straight', 'Straight'],\n ['elbow', 'Elbow'],\n ['curve', 'Curve'],\n ],\n item.route ?? 'elbow',\n (v) => board.updateSelection({ route: v as 'elbow' }),\n ),\n ),\n );\n if (single && item.kind === 'connector')\n stylePanel.append(\n field(\n 'Arrowhead',\n select(\n [\n ['arrow', 'Arrow'],\n ['dot', 'Dot'],\n ['none', 'None'],\n ],\n item.heads?.end ?? 'arrow',\n (value) => board.updateSelection({ heads: { ...item.heads, end: value as 'arrow' } }),\n ),\n ),\n );\n if (single && (item.kind === 'video' || item.kind === 'link')) {\n const label = hrefAction(item.kind);\n const edit = textButton(label, () => editHref(item.id), 'ad-button ad-href-edit');\n edit.setAttribute('aria-label', label);\n stylePanel.append(edit);\n }\n const lock = button(\n locked ? 'Unlock selection' : 'Lock selection',\n locked ? 'lock' : 'unlock',\n () => board.updateSelection({ locked: !locked }),\n );\n lock.setAttribute('aria-pressed', String(locked));\n const row = el('div', 'ad-selection-actions');\n row.append(\n button('Duplicate selection', 'copy', () => board.duplicate()),\n button('More arrangement options', 'align', openArrange),\n lock,\n button('Delete selection', 'trash', () => board.deleteSelection()),\n );\n stylePanel.append(row);\n if (board.readonly || locked)\n stylePanel\n .querySelectorAll('button,input,select')\n .forEach(\n (e) =>\n ((e as HTMLButtonElement).disabled = e !== deselect && (e !== lock || board.readonly)),\n );\n if (focusLabel === 'Unlock selection' || focusLabel === 'Lock selection') lock.focus();\n else if (focusLabel === 'Deselect') deselect.focus();\n else if (focusLabel)\n stylePanel.querySelector<HTMLElement>(`[aria-label=\"${CSS.escape(focusLabel)}\"]`)?.focus();\n else if (focusField)\n [...stylePanel.querySelectorAll('label')]\n .find((label) => label.querySelector('.ad-field-label')?.textContent === focusField)\n ?.querySelector<HTMLElement>('input,select')\n ?.focus();\n if (focused || stylePopup?.focused)\n if (locked && !board.readonly && !styleDock.contains(document.activeElement)) lock.focus();\n }\n function openArrange() {\n const d = dialog('Give it a little order');\n const actions = el('div', 'ad-action-grid');\n const item = board.selection.length === 1 ? board.get(board.selection[0]) : undefined;\n if (item) {\n actions.append(\n textButton('Duplicate', () => {\n board.duplicate();\n d.close();\n }),\n textButton('Delete', () => {\n board.deleteSelection();\n d.close();\n }),\n );\n }\n if (board.selection.length > 1)\n for (const mode of [\n 'left',\n 'center',\n 'right',\n 'top',\n 'middle',\n 'bottom',\n 'horizontal',\n 'vertical',\n ] as const)\n actions.append(\n textButton(\n mode === 'horizontal' || mode === 'vertical' ? `Distribute ${mode}` : `Align ${mode}`,\n () => {\n board.align(mode);\n d.close();\n },\n ),\n );\n if (board.selection.length > 1)\n actions.append(\n textButton('Group', () => {\n board.group();\n d.close();\n }),\n );\n if (board.selection.some((id) => board.get(id)?.kind === 'group'))\n actions.append(\n textButton('Ungroup', () => {\n board.ungroup();\n d.close();\n }),\n );\n actions.append(\n textButton('Bring to front', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'front' })),\n { origin: 'user', label: 'Bring to front' },\n );\n d.close();\n }),\n textButton('Send to back', () => {\n board.apply(\n board.selection.map((id) => ({ op: 'order', id, to: 'back' })),\n { origin: 'user', label: 'Send to back' },\n );\n d.close();\n }),\n );\n if (board.readonly)\n actions.querySelectorAll('button').forEach((action) => (action.disabled = true));\n d.append(actions);\n }\n function saveExport(format: UiExportFormat) {\n void board\n .export(format, {\n scope: 'page',\n padding: 40,\n background: true,\n ...(format === 'png' ? { scale: 2 } : {}),\n })\n .then((content) => {\n const name =\n board\n .read()\n .meta.title.replace(/[^a-z0-9 _-]/gi, '')\n .trim() || 'drawing';\n download(\n content,\n `${name}.${format === 'json' ? 'annie' : format}`,\n format === 'json' ? ANNIE_MIME : format === 'svg' ? 'image/svg+xml' : 'image/png',\n );\n })\n .catch(() => undefined);\n }\n function openExport() {\n if (formats.length === 1) {\n saveExport(formats[0]);\n return;\n }\n if (!exportButton) return;\n const panel = popover(exportButton, 'Export');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const choices: Record<UiExportFormat, [string, string]> = {\n png: ['PNG Image', 'image'],\n svg: ['SVG Image', 'image'],\n json: ['AnnieDoc format', 'code'],\n };\n for (const format of formats) {\n const [label, glyph] = choices[format];\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n saveExport(format);\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n panel.append(option);\n }\n showPopover(panel, exportButton);\n }\n function openMenu() {\n if (!brand) return;\n const panel = popover(brand, 'Board menu');\n if (!panel) return;\n panel.classList.add('ad-tool-options');\n const add = (label: string, glyph: string, action: () => void, disabled = false) => {\n const option = button(\n label,\n glyph,\n () => {\n closePopover();\n action();\n },\n 'ad-tool-option',\n );\n option.innerHTML += `<span>${label}</span>`;\n option.disabled = disabled;\n panel.append(option);\n };\n add('Open a drawing', 'upload', () => drawingInput?.click(), board.readonly);\n if (phoneChrome(board.stage.root.clientWidth, board.stage.root.clientHeight)) {\n add('Hand', 'hand', () => {\n board.setTool('hand');\n board.focus();\n });\n }\n add(board.grid ? 'Hide grid' : 'Show grid', 'grid', () => board.setGrid(!board.grid));\n const dark = board.stage.resolvedTheme === 'dark';\n add(dark ? 'Light appearance' : 'Dark appearance', dark ? 'sun' : 'moon', () =>\n board.setTheme(dark ? 'light' : 'dark'),\n );\n add('Documentation', 'book', () => {\n window.open('./docs/index.html', '_blank', 'noopener');\n });\n const github = el('a', 'ad-tool-option');\n github.href = GITHUB_REPO_URL;\n github.target = '_blank';\n github.rel = 'noopener noreferrer';\n github.title = 'GitHub';\n github.innerHTML = `${icon('github')}<span>GitHub</span>`;\n github.addEventListener('click', () => closePopover());\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n panel.append(github, separator, el('p', 'ad-menu-version', `v${PACKAGE_VERSION}`));\n showPopover(panel, brand);\n }\n function refresh() {\n undo.disabled = !board.canUndo;\n redo.disabled = !board.canRedo;\n renderPages();\n renderStyle();\n }\n const context = (event: Event) => {\n const { x, y, id } = (event as CustomEvent<Point & { id?: string }>).detail;\n const item = id ? board.get(id) : undefined;\n if (!item) {\n closePopover();\n return;\n }\n const bounds = board.stage.root.getBoundingClientRect();\n const menu = contextMenu('Element actions', { x: bounds.left + x, y: bounds.top + y });\n const locked = board.isLocked(item.id);\n if (item.kind === 'video' || item.kind === 'link')\n menu.add(hrefAction(item.kind), 'link', () => editHref(item.id), locked);\n if (!['image', 'path', 'line', 'group', 'html', 'video', 'link'].includes(item.kind))\n menu.add('Edit text', 'text', () => board.editText(item.id), locked);\n const order = (to: 'front' | 'back') =>\n board.apply([{ op: 'order', id: item.id, to }], {\n origin: 'user',\n label: to === 'front' ? 'Bring to front' : 'Send to back',\n });\n menu.add('Bring to front', 'front', () => order('front'), locked);\n menu.add('Send to back', 'back', () => order('back'), locked);\n menu.add(\n 'Duplicate',\n 'copy',\n () => {\n board.select([item.id]);\n board.duplicate();\n },\n locked,\n );\n const separator = el('div', 'ad-menu-separator');\n separator.setAttribute('role', 'separator');\n menu.panel.append(separator);\n menu.add(\n 'Delete',\n 'trash',\n () => {\n board.select([item.id]);\n board.deleteSelection();\n },\n locked,\n );\n menu.show();\n };\n board.host.addEventListener('ad-context', context);\n unsubs.push(\n board.on('change', refresh),\n board.on('select', () => {\n renderStyle();\n }),\n board.on('page', refresh),\n board.on('view', (state) => {\n if (activePopover?.popover === 'manual') closePopover();\n percentage.textContent = `${Math.round(state.zoom * 100)}%`;\n }),\n board.on('tool', (id) => {\n for (const b of ui.querySelectorAll<HTMLElement>('[data-tool]'))\n b.setAttribute('aria-pressed', String(id === b.dataset.tool));\n shapeButton.setAttribute('aria-pressed', String(shapeKinds.includes(id)));\n board.stage.root.dataset.adTool = id;\n renderStyle();\n }),\n );\n refresh();\n return () => {\n clearTimeout(pagePressTimer);\n closePopover();\n unsubs.forEach((fn) => fn());\n activeDialog?.close();\n board.host.removeEventListener('ad-context', context);\n ui.remove();\n };\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{c as e}from"./picker-Dv_i4iNP.js";import{h as t,u as i}from"./defaults-C-aC_B4z.js";import{a as n,c as a,i as r,t as o}from"./paste-C22i8o-g.js";function s(e,t,n,a){const[r,o]=a??i(t),s=n??e.view.center;let d=s.x-r/2,c=s.y-o/2;if(!n)for(;e.items.some(e=>Math.abs(e.x-d)<4&&Math.abs(e.y-c)<4);)d+=24,c+=24;return{x:d,y:c,w:r,h:o}}function d(e,t,i,a){const r="link"===t?n(i):void 0,o=e.apply([{op:"add",page:e.pageId,item:{kind:t,href:i,...s(e,t,a),...r?{name:r.host,description:r.description,text:{value:r.title,font:"sans"}}:{}}}],{origin:"user",label:"video"===t?"Paste video":"Paste link"});o.ok&&(e.select(o.created),"link"===t&&o.created[0]&&c(e,o.created[0],i))}async function c(e,i,n,o="Paste link"){if(!1!==e.unfurl)try{const s=await(e.unfurl??a)(n);if(!s||e.destroyed||!e.get(i))return;const d=[],c={};if(s.title&&(c.text={value:s.title,font:"sans"}),s.image){const e=t();d.push({op:"media.set",id:e,media:{src:s.image,mime:r(s.image),w:1200,h:630}}),c.media=e}Object.keys(c).length&&d.push({op:"set",id:i,patch:c}),d.length&&e.apply(d,{origin:"user",label:o,merge:!0})}catch{}}function l(e){return{ok:!1,created:[],errors:[{index:0,code:"INVALID_OP",message:e}],warnings:[]}}function m(e,t,i){const a=e.get(t);if(!a||"video"!==a.kind&&"link"!==a.kind)return l(`Item ${t} is not a video or link.`);const r=o(i),s="text"===r.kind?void 0:r.href;if(!s||s.startsWith("data:"))return l("video"===a.kind?`Bad video (${t}).`:`Bad href (${t}).`);if("video"===a.kind&&"video"!==r.kind)return l(`Bad video (${t}).`);if(s===a.href)return{ok:!0,created:[],errors:[],warnings:[]};const d="link"===a.kind?n(s):void 0,m="video"===a.kind?"Edit video URL":"Edit URL",u=e.apply([{op:"set",id:t,patch:{href:s,...d?{name:d.host,description:d.description,text:{value:d.title,font:"sans"},media:void 0}:{}}}],{origin:"user",label:m});return u.ok&&"link"===a.kind&&c(e,t,s,m),u}async function u(i,n,a){try{const[o,d]=await function(e){return new Promise((t,i)=>{const n=new Image,a=e=>{clearTimeout(r),n.onload=n.onerror=null,e&&n.naturalWidth?t([n.naturalWidth,n.naturalHeight]):i(/* @__PURE__ */new Error("image"))},r=setTimeout(()=>a(!!n.naturalWidth),2500);n.onload=()=>a(!0),n.onerror=()=>a(!1),n.src=e})}(n),c=Math.min(1,480/o,360/d),l=t(),m=i.apply([{op:"media.set",id:l,media:{src:n,mime:r(n),w:o,h:d}},{op:"add",page:i.pageId,item:{kind:"image",...s(i,"image",a,[o*c,d*c]),media:l,name:e(n)}}],{origin:"user",label:"Paste image"});m.ok&&i.select(m.created)}catch{d(i,"link",n,a)}}function p(e,t,i){const n=o(t);if("video"===n.kind||"link"===n.kind)d(e,n.kind,n.href,i);else if("image"===n.kind)u(e,n.href,i).catch(t=>function(e,t){e.host.dispatchEvent(new CustomEvent("ad-error",{detail:String(t)}))}(e,t));else{const n=i??e.view.center,a=e.apply([{op:"add",page:e.pageId,item:{kind:"text",x:n.x,y:n.y,w:300,h:100,text:{value:t,size:"m"}}}],{origin:"user",label:"Paste text"});a.ok&&e.select(a.created)}}export{p as pastePlain,m as updateHref};
2
- //# sourceMappingURL=urlPaste-DN4JtgeB.js.map
1
+ import{c as e}from"./picker-DZpEpkED.js";import{h as t,u as i}from"./defaults-C-aC_B4z.js";import{a as n,c as a,i as r,t as o}from"./paste-B8nZA2Gh.js";function s(e,t,n,a){const[r,o]=a??i(t),s=n??e.view.center;let d=s.x-r/2,c=s.y-o/2;if(!n)for(;e.items.some(e=>Math.abs(e.x-d)<4&&Math.abs(e.y-c)<4);)d+=24,c+=24;return{x:d,y:c,w:r,h:o}}function d(e,t,i,a){const r="link"===t?n(i):void 0,o=e.apply([{op:"add",page:e.pageId,item:{kind:t,href:i,...s(e,t,a),...r?{name:r.host,description:r.description,text:{value:r.title,font:"sans"}}:{}}}],{origin:"user",label:"video"===t?"Paste video":"Paste link"});o.ok&&(e.select(o.created),"link"===t&&o.created[0]&&c(e,o.created[0],i))}async function c(e,i,n,o="Paste link"){if(!1!==e.unfurl)try{const s=await(e.unfurl??a)(n);if(!s||e.destroyed||!e.get(i))return;const d=[],c={};if(s.title&&(c.text={value:s.title,font:"sans"}),s.image){const e=t();d.push({op:"media.set",id:e,media:{src:s.image,mime:r(s.image),w:1200,h:630}}),c.media=e}Object.keys(c).length&&d.push({op:"set",id:i,patch:c}),d.length&&e.apply(d,{origin:"user",label:o,merge:!0})}catch{}}function l(e){return{ok:!1,created:[],errors:[{index:0,code:"INVALID_OP",message:e}],warnings:[]}}function m(e,t,i){const a=e.get(t);if(!a||"video"!==a.kind&&"link"!==a.kind)return l(`Item ${t} is not a video or link.`);const r=o(i),s="text"===r.kind?void 0:r.href;if(!s||s.startsWith("data:"))return l("video"===a.kind?`Bad video (${t}).`:`Bad href (${t}).`);if("video"===a.kind&&"video"!==r.kind)return l(`Bad video (${t}).`);if(s===a.href)return{ok:!0,created:[],errors:[],warnings:[]};const d="link"===a.kind?n(s):void 0,m="video"===a.kind?"Edit video URL":"Edit URL",u=e.apply([{op:"set",id:t,patch:{href:s,...d?{name:d.host,description:d.description,text:{value:d.title,font:"sans"},media:void 0}:{}}}],{origin:"user",label:m});return u.ok&&"link"===a.kind&&c(e,t,s,m),u}async function u(i,n,a){try{const[o,d]=await function(e){return new Promise((t,i)=>{const n=new Image,a=e=>{clearTimeout(r),n.onload=n.onerror=null,e&&n.naturalWidth?t([n.naturalWidth,n.naturalHeight]):i(/* @__PURE__ */new Error("image"))},r=setTimeout(()=>a(!!n.naturalWidth),2500);n.onload=()=>a(!0),n.onerror=()=>a(!1),n.src=e})}(n),c=Math.min(1,480/o,360/d),l=t(),m=i.apply([{op:"media.set",id:l,media:{src:n,mime:r(n),w:o,h:d}},{op:"add",page:i.pageId,item:{kind:"image",...s(i,"image",a,[o*c,d*c]),media:l,name:e(n)}}],{origin:"user",label:"Paste image"});m.ok&&i.select(m.created)}catch{d(i,"link",n,a)}}function p(e,t,i){const n=o(t);if("video"===n.kind||"link"===n.kind)d(e,n.kind,n.href,i);else if("image"===n.kind)u(e,n.href,i).catch(t=>function(e,t){e.host.dispatchEvent(new CustomEvent("ad-error",{detail:String(t)}))}(e,t));else{const n=i??e.view.center,a=e.apply([{op:"add",page:e.pageId,item:{kind:"text",x:n.x,y:n.y,w:300,h:100,text:{value:t,size:"m"}}}],{origin:"user",label:"Paste text"});a.ok&&e.select(a.created)}}export{p as pastePlain,m as updateHref};
2
+ //# sourceMappingURL=urlPaste-Oc4kZ0P7.js.map