Inkvec 0.2: the presentation page, and Inkvec Studio Lite under studio/
Browse files- index.html +4 -2
- studio/assets/{main-CjAquJE3.js → main-DBfkyHf-.js} +2 -2
- studio/index.html +2 -2
- studio/pkg-threads/inkvec_studio_wasm.js +1 -1
- studio/pkg-threads/inkvec_studio_wasm_bg.wasm +2 -2
- studio/pkg-threads/snippets/wasm-bindgen-rayon-38edf6e439f6d70d/src/workerHelpers.js +1 -1
- studio/pkg/inkvec_studio_wasm.js +1 -1
- studio/pkg/inkvec_studio_wasm_bg.wasm +2 -2
index.html
CHANGED
|
@@ -209,9 +209,11 @@ html.framed .top{box-shadow:0 -6px 0 var(--void),inset 0 1px 0 rgba(201,117,74,.
|
|
| 209 |
</section>
|
| 210 |
|
| 211 |
<section class="sec" id="new">
|
| 212 |
-
<h2>What's new in 0.3.
|
| 213 |
-
<p class="lede">
|
| 214 |
<div class="newgrid">
|
|
|
|
|
|
|
| 215 |
<div class="new"><span class="tag">Fidelity</span><h3>Closer to the artist's file</h3><p>Quality's colour difference from the artist's own file (dE00) is 12.5% lower at 128 px, 12.1% at 512 px and 15.2% at 512 px on an opaque ground; Fast's is 9 to 12% lower. Quality also writes fewer parameters: 1.32 per artist parameter at 512 px opaque, down from 1.96.</p></div>
|
| 216 |
<div class="new"><span class="tag">Noisy input</span><h3>JPEGs and screenshots</h3><p>A JPEG's colour bleeds two or three pixels across every edge. Those halos now go back to the inks they lie between instead of becoming shapes of their own. On icons resized and saved at quality 80, Quality's dE00 is 10.4% lower and Fast writes 4.13 parameters per artist parameter, down from 7.29.</p></div>
|
| 217 |
<div class="new"><span class="tag">Shapes</span><h3>Whole shapes, under what covers them</h3><p>A shape partly hidden by another used to come back as the sliver that shows. Quality now draws it whole: the simplest shape that leaves every visible pixel as it was. A letter's counter is cut out of its glyph instead of painted over it, and each fill is one compound path.</p></div>
|
|
|
|
| 209 |
</section>
|
| 210 |
|
| 211 |
<section class="sec" id="new">
|
| 212 |
+
<h2>What's new in 0.3.1</h2>
|
| 213 |
+
<p class="lede">With editability on, a trace is drawn more the way artists draw, and on a JPEG the edges land closer to the artist's. 0.3.0 brought traces closer to what the artist drew in every mode and condition, and much closer on the resized JPEGs and screenshots logos usually arrive as.</p>
|
| 214 |
<div class="newgrid">
|
| 215 |
+
<div class="new"><span class="tag">Editing</span><h3>Every edit has to pay for itself</h3><p>With editability on, a smooth join, a node at an extreme or an arc rewritten as cubics is kept only when the numbers it saves outweigh the fit it costs. The bonus each kind of edit receives was learned from the artists' own files. Against the plain trace, edge placement improves by up to 0.9%, and the drawing is 8 to 9% closer to the artists' by a battery of 28 drawing statistics.</p></div>
|
| 216 |
+
<div class="new"><span class="tag">Noisy input</span><h3>Edges on a JPEG</h3><p>The boundary solve fitted edges to the codec's ringing. On a lossy image that is not restored it is now skipped. On icons resized and saved at quality 80, edges sit 7% closer to the artist's and Quality's dE00 is 5.6% lower.</p></div>
|
| 217 |
<div class="new"><span class="tag">Fidelity</span><h3>Closer to the artist's file</h3><p>Quality's colour difference from the artist's own file (dE00) is 12.5% lower at 128 px, 12.1% at 512 px and 15.2% at 512 px on an opaque ground; Fast's is 9 to 12% lower. Quality also writes fewer parameters: 1.32 per artist parameter at 512 px opaque, down from 1.96.</p></div>
|
| 218 |
<div class="new"><span class="tag">Noisy input</span><h3>JPEGs and screenshots</h3><p>A JPEG's colour bleeds two or three pixels across every edge. Those halos now go back to the inks they lie between instead of becoming shapes of their own. On icons resized and saved at quality 80, Quality's dE00 is 10.4% lower and Fast writes 4.13 parameters per artist parameter, down from 7.29.</p></div>
|
| 219 |
<div class="new"><span class="tag">Shapes</span><h3>Whole shapes, under what covers them</h3><p>A shape partly hidden by another used to come back as the sliver that shows. Quality now draws it whole: the simplest shape that leaves every visible pixel as it was. A letter's counter is cut out of its glyph instead of painted over it, and each fill is one compound path.</p></div>
|
studio/assets/{main-CjAquJE3.js → main-DBfkyHf-.js}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
var la=Object.defineProperty;var ca=(e,t,s)=>t in e?la(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var R=(e,t,s)=>ca(e,typeof t!="symbol"?t+"":t,s);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))o(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const r of i.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&o(r)}).observe(document,{childList:!0,subtree:!0});function s(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(a){if(a.ep)return;a.ep=!0;const i=s(a);fetch(a.href,i)}})();async function Kt(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}function ua(){return!!(globalThis||window).isTauri}var cs;(function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_SUSPENDED="tauri://suspended",e.WINDOW_RESUMED="tauri://resumed",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"})(cs||(cs={}));var us;(function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"})(us||(us={}));var ds;(function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"})(ds||(ds={}));var ps;(function(e){e.Disabled="disabled",e.Throttle="throttle",e.Suspend="suspend"})(ps||(ps={}));var hs;(function(e){e.Default="default",e.FluentOverlay="fluentOverlay"})(hs||(hs={}));var fs;(function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"})(fs||(fs={}));var gs;(function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"})(gs||(gs={}));const da=`<!-- Generated by studio/tools/make_assets.py from web/logo.svg. Do not edit. -->
|
| 2 |
<svg color="#c9754a" xmlns="http://www.w3.org/2000/svg" viewBox="254.5 140.5 514.25 742.25"><path d="M511.3 140.6c-23.3 79.8-103 178.5-144.9 232.75L335.45 415.4a467.73 467.73 0 00-64.8 115.4c-65.5 193.1 80.8 351.3 237.85 351.7 21.26 1.1 42.56-1.3 63.06-7 90.8-18.87 211.87-120.04 195.47-280.9-17.9-164.8-187.55-272.65-251.8-443.84Zm10.2 374.9a61.05 61.05 0 00-67.1 81.6 61.05 61.05 0 00104.3 17.26 61.05 61.05 0 00-37.2-98.86ZM511.4 817.65l177.16-201.3-43-.15a44.56 44.56 0 00-36.2 18.47l-97.8 111.67-102.2-116.67c-16.06-18.94-38.06-12-74.9-13.4 5.7 7.3 159.75 179.73 176.93 201.4Z" fill="currentColor" fill-rule="evenodd"/></svg>
|
| 3 |
-
`;function n(e,t=null,...s){const[o,...a]=e.split("."),i=document.createElement(o||"div");return a.length&&(i.className=a.join(" ")),pa(i,t),Nn(i,s),i}function Ee(e,t=null,...s){const[o,...a]=e.split("."),i=document.createElementNS("http://www.w3.org/2000/svg",o||"g");a.length&&i.setAttribute("class",a.join(" "));for(const[r,l]of Object.entries(t??{}))l==null||l===!1||(r.startsWith("on")&&typeof l=="function"?i.addEventListener(r.slice(2),l):i.setAttribute(r,String(l)));return Nn(i,s),i}function pa(e,t){for(const[s,o]of Object.entries(t??{}))o==null||o===!1||(s==="class"?e.className=e.className?`${e.className} ${o}`:String(o):s==="style"&&typeof o=="object"?Object.assign(e.style,o):s.startsWith("on")&&typeof o=="function"?e.addEventListener(s.slice(2),o):s==="value"&&e instanceof HTMLInputElement?e.value=String(o):o===!0?e.setAttribute(s,""):e.setAttribute(s,String(o)))}function Nn(e,t){for(const s of t.flat(8))s==null||s===!1||e.append(s instanceof Node?s:document.createTextNode(String(s)))}function D(e,...t){e.replaceChildren(),Nn(e,t)}const ms={image:"M3 3h18v18H3zM3 15l5-5 4 4 3-3 6 6M8.5 8.5h.01",type:"M4 7V4h16v3M9 20h6M12 4v16",droplet:"M12 2.7 6.7 8a7.5 7.5 0 1 0 10.6 0Z",wand:"m3 21 9-9M15 4V2M15 16v-2M8 9h2M20 9h2M17.8 11.8 19 13M15 9h.01M17.8 6.2 19 5M12.8 6.2 11.6 5",layers:"m12 2 9 5-9 5-9-5 9-5M3 12l9 5 9-5M3 17l9 5 9-5",palette:"M12 21a9 9 0 1 1 0-18c4.97 0 9 3.58 9 8 0 1.66-1.34 3-3 3h-2a2 2 0 0 0-1.6 3.2 2 2 0 0 1-1.6 3.2ZM7.5 10.5h.01M10.5 7.5h.01M14 7.5h.01M16.5 10.5h.01",check:"m20 6-11 11-5-5",checkCircle:"M22 11.1V12a10 10 0 1 1-5.9-9.1M22 4 12 14.01l-3-3",x:"M18 6 6 18M6 6l12 12",alert:"M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z",info:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM12 16v-4M12 8h.01",clock:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM12 6v6l4 2",download:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3",upload:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12",globe:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10Z",copy:"M20 9H11a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",folder:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",settings:"M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6 1.65 1.65 0 0 0 10 3.09V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z",chevronDown:"m6 9 6 6 6-6",chevronRight:"m9 18 6-6-6-6",minus:"M5 12h14",pen:"M21.17 6.81a2.82 2.82 0 0 0-3.99-3.99L3.84 16.17a2 2 0 0 0-.5.83l-1.32 4.35a.5.5 0 0 0 .62.62l4.35-1.32a2 2 0 0 0 .83-.5Z",square:"M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2Z",crosshair:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM22 12h-4M6 12H2M12 6V2M12 22v-4",zap:"M4 14h7l-3 8 12-12h-7l3-8Z",play:"m6 3 14 9-14 9V3Z",pause:"M14 4h4v16h-4zM6 4h4v16H6z",rotate:"M3 12a9 9 0 1 0 3-6.7L3 8M3 3v5h5",share:"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13",file:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7ZM14 2v6h6",maximize:"M8 3H5a2 2 0 0 0-2 2v3M21 8V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3M16 21h3a2 2 0 0 0 2-2v-3",external:"M15 3h6v6M10 14 21 3M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"};function V(e,t=16){const s=ms[e]??ms.info;return Ee("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true",focusable:"false"},Ee("path",{d:s}))}function ao(e=18){const t=ha.cloneNode(!0);t.removeAttribute("color");const[,,s,o]=(t.getAttribute("viewBox")??"0 0 1 1").split(/\s+/).map(Number);return t.setAttribute("height",String(e)),t.setAttribute("width",String(Math.round(e*s/o))),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false"),t}const ha=(()=>{const e=new DOMParser().parseFromString(da,"image/svg+xml").documentElement;return document.importNode(e,!0)})();function fa(e,t){let s=0;const o=i=>[...i.dataTransfer?.types??[]].includes("Files"),a=()=>{s=0,e.set({dragging:!1}),document.body.classList.remove("dragging")};window.addEventListener("dragenter",i=>{o(i)&&(s++,e.set({dragging:!0}),document.body.classList.add("dragging"))}),window.addEventListener("dragover",i=>{o(i)&&(i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="copy"))}),window.addEventListener("dragleave",i=>{o(i)&&(s=Math.max(0,s-1),s===0&&a())}),window.addEventListener("drop",i=>{if(!o(i))return;i.preventDefault(),a();const r=[...i.dataTransfer?.files??[]];r.length&&t(r)}),ga(t)}function ga(e){window.addEventListener("paste",t=>{if(t.target?.closest?.("input, textarea, [contenteditable]"))return;let o=[...t.clipboardData?.files??[]];o.length||(o=[...t.clipboardData?.items??[]].filter(a=>a.kind==="file").map(a=>a.getAsFile()).filter(a=>a!==null)),o.length&&(t.preventDefault(),e(o))})}const ma=760,bs="inkvec-phone-tip-dismissed";function ba(e){const t=window.matchMedia(`(max-width: ${ma}px)`).matches,s=window.matchMedia("(pointer: coarse)").matches;if(!(t&&s))return;try{if(sessionStorage.getItem(bs))return}catch{}const o=document.documentElement;let a=null;const i=()=>{a?.disconnect(),o.style.removeProperty("--phonetip-h"),r.remove()},r=n("aside.phonetip",{"aria-label":"Tip",style:{position:"fixed",left:"0",right:"0",bottom:"0",zIndex:"40",display:"flex",alignItems:"center",gap:"8px",padding:"6px 6px 6px 14px",background:"var(--card)",borderTop:"1px solid var(--rule)",color:"var(--dim)",fontSize:"13px",lineHeight:"1.4"}},n("span",{style:{flex:"1"}},"Works on a phone; a larger screen shows the drawing, the controls and the palette side by side."),n("button.btn.ghost.compact",{"aria-label":"Close this tip",style:{minWidth:"32px",minHeight:"32px",justifyContent:"center"},onclick:()=>{i();try{sessionStorage.setItem(bs,"1")}catch{}}},V("x",14)));e.append(r);const l=()=>o.style.setProperty("--phonetip-h",`${r.offsetHeight}px`);l(),typeof ResizeObserver<"u"&&(a=new ResizeObserver(l),a.observe(r))}async function ya(){const e=new URLSearchParams(window.location.search),t=e.get("sample"),s=e.get("open")==="handoff",o=wa(window.location.hash);return!t&&!s&&!o?null:(window.history.replaceState(null,"",window.location.pathname),o||(t?{sample:t}:new Promise(a=>{let i;try{i=indexedDB.open("inkvec-handoff",1)}catch{a(null);return}i.onupgradeneeded=()=>i.result.createObjectStore("files"),i.onerror=()=>a(null),i.onsuccess=()=>{const r=i.result.transaction("files","readwrite").objectStore("files"),l=r.get("open");l.onsuccess=()=>{r.delete("open");const c=l.result;a(c?.bytes?{name:c.name??"image",bytes:c.bytes}:null)},l.onerror=()=>a(null)}})))}function wa(e){if(!e.startsWith("#"))return null;const t=new URLSearchParams(e.slice(1)),s=t.get("open");if(!s)return null;try{const o=s.replace(/-/g,"+").replace(/_/g,"/"),a=atob(o+"=".repeat(4-(o.length&3)&3)),i=new Uint8Array(a.length);for(let r=0;r<a.length;r++)i[r]=a.charCodeAt(r);return i.length?{name:t.get("name")||"image",bytes:i}:null}catch{return null}}const In=15e5;function va(e,t){if(!t.length||t.length>In)return null;let s="";for(let a=0;a<t.length;a+=32768)s+=String.fromCharCode(...t.subarray(a,a+32768));return`#open=${btoa(s).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}&name=${encodeURIComponent(e)}`}let Ft=0,Bt=null,$n=0,ft=!1,io=performance.now();const ln=e=>(e/(1024*1024)).toFixed(1);function xa(){$n=0;const e=Bt;if(Bt=null,!e||ft)return;Ft=e.fraction;const t=document.getElementById("boot-bar"),s=document.getElementById("boot-fill"),o=document.getElementById("boot-status"),a=document.getElementById("boot-pct"),i=document.getElementById("boot-detail"),r=Math.round(Ft*100);s&&(s.style.transform=`scaleX(${Ft})`),t?.setAttribute("aria-valuenow",String(r)),o&&(o.textContent=e.text),a&&(a.textContent=`${r}%`),i&&(i.textContent=e.detail)}function wt(e,t,s=""){ft||(io=performance.now(),Bt={text:e,fraction:Math.max(Ft,Bt?.fraction??0,Math.min(1,t)),detail:s},$n||($n=requestAnimationFrame(xa)))}function ka(e,t){const s=t>0?Math.min(1,e/t):0;wt("Downloading the engine",.04+.8*s,t>0?`${ln(e)} of ${ln(t)} MB`:`${ln(e)} MB`)}function Sa(){wt("Starting the engine",.88,"Compiling")}function $a(e,t){wt(e,.9+.1*Math.min(1,Math.max(0,t)))}function Ma(){if(ft)return;const e=document.getElementById("boot-fill");e&&(e.style.transitionDuration="0.12s"),wt("Ready",1),window.setTimeout(()=>{ft=!0;const t=document.getElementById("boot");t&&(t.classList.add("leaving"),window.setTimeout(()=>t.remove(),260))},130)}{window.__inkvecBoot=!0,wt("Loading the Studio",.03);const e=window.setInterval(()=>{if(ft){window.clearInterval(e);return}if(performance.now()-io>2e4){const t=document.getElementById("boot-detail");t&&(t.textContent="Still waiting for the network. On a slow connection the first visit can take a minute; later ones start from the browser's cache.")}},2e3)}function Ea(){let e;try{e=window.self!==window.top}catch{e=!0}const t=window.location.ancestorOrigins;if(t)for(let a=0;a<t.length;a++)/(^|\.)huggingface\.co(:\d+)?$/.test(t[a].replace(/^[a-z]+:\/\//,""))&&(e=!0);const s=document.documentElement;s.classList.toggle("framed",e);const o=()=>s.classList.toggle("fullscreen",!!document.fullscreenElement);document.addEventListener("fullscreenchange",o),o()}function Ze(e,t,s="application/octet-stream"){const o=t instanceof Blob?t:new Blob([t],{type:s}),a=URL.createObjectURL(o),i=document.createElement("a");i.href=a,i.download=e,i.style.display="none",document.body.append(i),i.click(),i.remove(),window.setTimeout(()=>URL.revokeObjectURL(a),6e4)}const ro="inkvec-studio-lite:prefs";function Aa(e=()=>localStorage){try{const t=e().getItem(ro);return t?JSON.parse(t):null}catch{return null}}function Ca(e,t=()=>localStorage){try{return t().setItem(ro,JSON.stringify(e)),!0}catch{return!1}}var Ta={pkg:6817202,"pkg-threads":6867358};const ys="inkvec-denoiser-v1",Pa="inkvec-ort-",La=3e4,za=700,ws="Not available in the browser. Inkvec Studio, the desktop app, has it.",vs=[["flat-logo.png","Flat logo"],["icon-64.png","Icon, 64 px"],["crest-filigree.png","Crest, filigree"],["signature-bw.png","Signature, B&W"]];class Da{constructor(){R(this,"worker",null);R(this,"ready",null);R(this,"queue",[]);R(this,"running",null);R(this,"nextId",1);R(this,"listeners",new Map);R(this,"generation",0);R(this,"previewGeneration",0);R(this,"shared",null);R(this,"source",null);R(this,"prefs",null);R(this,"prefsTimer",0);R(this,"denoiser",null);R(this,"denoiserPort",null);R(this,"downloading",!1);R(this,"fetchState",{phase:"idle",got:0,total:null});R(this,"wanted",!1);R(this,"cancelled",!1);R(this,"retried",!1);R(this,"info",null);R(this,"restartMs",null);R(this,"stopped",[]);R(this,"stopTimer",0);R(this,"denoiserRuns",0);R(this,"last",null)}openImage(){return this.source}base(){return new URL("./",document.baseURI).href}start(){const t=typeof crossOriginIsolated<"u"&&crossOriginIsolated;t&&!this.shared&&(this.shared=new Int32Array(new SharedArrayBuffer(4)));const s=new Worker(new URL(""+new URL("engine.worker-D2MRJiuD.js",import.meta.url).href,import.meta.url),{type:"module",name:"inkvec-engine"});this.worker=s;let o=null;if(t){const i=new MessageChannel;o=i.port1,this.denoiser?this.denoiser.postMessage({type:"port",port:i.port2},[i.port2]):this.denoiserPort=i.port2}this.ready=new Promise((i,r)=>{s.onmessage=l=>{const c=l.data;c.type==="loading"?(ka(c.got,c.total),c.done&&Sa()):c.type==="instantiated"?t&&(this.startDenoiser(c.denoiserUrl,c.denoiserSha256),this.prefetchDenoiser()):c.type==="ready"?(this.info={threads:c.threads,isolated:c.isolated,version:c.version,pool:c.pool,poolMs:null},t&&this.startDenoiser(c.denoiserUrl,c.denoiserSha256),i(c)):c.type==="pool"?(this.info&&(this.info={...this.info,threads:c.threads,pool:c.poolError?"failed":"running",poolMs:c.ms}),c.poolError&&console.warn("inkvec: thread pool did not start:",c.poolError)):c.type==="loadfail"?r(new Error(`The engine could not load: ${c.error}`)):c.type==="progress"?c.generation===this.generation&&this.emit("trace:progress",{generation:c.generation,...JSON.parse(c.json)}):c.type==="reply"&&this.finish(c)},s.onerror=l=>{r(new Error(`The engine stopped: ${l.message||"unknown error"}`)),this.crashed("The engine stopped unexpectedly.")}});const a=o?[o]:[];return s.postMessage({type:"init",base:this.base(),token:"d8fd58375cca",generations:this.shared?this.shared.buffer:null,denoiserPort:o,wasmBytes:Ta},a),this.ready}whenReady(){return this.ready??this.start()}crashed(t){const s=this.running;this.running=null,window.clearTimeout(this.stopTimer),this.worker?.terminate(),this.worker=null,this.ready=null,s&&s.reject(new Error(t)),s?.op==="open_bytes"&&(this.source=null);const o=this.source,a=performance.now();this.whenReady().then(async()=>{o&&await this.enqueue("open_bytes",-1,{bytes:o.bytes.slice(),name:o.name}).catch(()=>{}),this.restartMs=performance.now()-a,this.pump()})}supersede(t,s){window.clearTimeout(this.stopTimer);const o=this.running;if(o?.op!=="trace"||o.payload.generation===this.generation||!t&&s&&Fa(o.payload.request,s))return;const a=performance.now(),i=()=>{this.running!==o||o.payload.generation===this.generation||(this.stopped.push({generation:o.payload.generation,asked:a,killed:performance.now()}),this.crashed("superseded by a newer request"))},r=a-(o.started??a),l=t?0:Math.max(0,(this.restartMs??za)-r);l===0?i():this.stopTimer=window.setTimeout(i,l)}finish(t){const s=this.running;if(!(!s||s.id!==t.id)){if(this.last={op:s.op,ms:t.ms??0,mem:t.mem??null},this.running=null,window.clearTimeout(this.stopTimer),t.ok)s.resolve(t.value);else if(t.crashed){this.crashed(t.error??"The engine stopped."),s.reject(new Error(t.error??"The engine stopped."));return}else s.reject(new Error(t.error??"failed"));this.pump()}}enqueue(t,s,o,a){return new Promise((i,r)=>{if(a){for(const l of this.queue.filter(c=>c.kind===a))l.reject(new Error("superseded by a newer request"));this.queue=this.queue.filter(l=>l.kind!==a)}this.queue.push({id:this.nextId++,op:t,priority:s,kind:a,payload:o,resolve:i,reject:r}),this.queue.sort((l,c)=>l.priority-c.priority||l.id-c.id),this.whenReady().then(()=>this.pump(),l=>{for(const c of this.queue)c.reject(l);this.queue=[]})})}pump(){if(this.running||!this.worker||!this.info)return;const t=this.queue.shift();if(!t)return;if(t.op==="trace"&&t.payload.generation!==this.generation)return t.resolve(null),this.pump();if(t.op==="preview"&&t.payload.generation!==this.previewGeneration)return t.resolve(null),this.pump();this.running=t,t.started=performance.now();const s=[];t.op==="open_bytes"&&s.push(t.payload.bytes.buffer),this.worker.postMessage({type:"job",id:t.id,op:t.op,...t.payload},s)}emit(t,s){for(const o of this.listeners.get(t)??[])o(s)}async listen(t,s){const o=i=>s({payload:i});let a=this.listeners.get(t);return a||this.listeners.set(t,a=new Set),a.add(o),()=>void a?.delete(o)}async invoke(t,s={}){return await this.dispatch(t,s)}async dispatch(t,s){switch(t){case"capabilities":{const o=await this.denoiserStatus();return this.enqueue("capabilities",0,{supported:o.supported,installed:o.installed,bytes:o.bytes})}case"startup_progress":return $a(String(s.text??""),Number(s.progress??0)),null;case"app_ready":return Ma(),null;case"open_path":throw new Error("A browser opens files you choose or drop, not paths.");case"open_bytes":{const o=s.bytes,a=o instanceof Uint8Array?o:new Uint8Array(o);return this.open(a,s.name??null)}case"open_sample":{const o=String(s.name);if(!vs.some(([i])=>i===o))throw new Error(`${o} is not one of the bundled samples`);const a=await fetch(new URL(`samples/${o}`,this.base()));if(!a.ok)throw new Error(`cannot fetch the sample ${o}: HTTP ${a.status}`);return this.open(new Uint8Array(await a.arrayBuffer()),o)}case"list_samples":return vs.map(([o,a])=>({file:o,label:a,preview:new URL(`samples/${o}`,this.base()).href}));case"launch_path":return null;case"start_trace":{const o=s.request,a=this.bump();o.tier!=="draft"&&this.rememberTrace(o.settings);const i=this.withoutUnreadyDenoiser(o);this.supersede(!1,i);const r=await this.loadPrefs();return this.enqueue("trace",1,{request:i,draftPx:r.draftPx??512,draftSeconds:r.draftSeconds??.4,generation:a},"trace").then(l=>{l&&a===this.generation&&this.emit("trace:done",{generation:a,outcome:l})},l=>{a===this.generation&&!/superseded/.test(l.message)&&this.emit("trace:done",{generation:a,outcome:{state:"failed",message:l.message}})}),a}case"cancel_trace":return this.bump(),this.queue=this.queue.filter(o=>o.kind==="trace"?(o.resolve(null),!1):!0),this.supersede(!0),null;case"start_preview":{const o=this.withoutUnreadyDenoiser(s.request),a=++this.previewGeneration,i=await this.loadPrefs();return this.enqueue("preview",2,{request:o,draftPx:i.draftPx??512,draftSeconds:i.draftSeconds??.4,generation:a},"preview").then(r=>{r&&a===this.previewGeneration&&this.emit("preview:done",{generation:a,outcome:r})},r=>{a===this.previewGeneration&&!/superseded/.test(r.message)&&this.emit("preview:done",{generation:a,outcome:{state:"failed",message:r.message}})}),a}case"cancel_previews":{this.previewGeneration++,this.queue=this.queue.filter(a=>a.kind==="preview"?(a.resolve(null),!1):!0);const o=this.running;return o?.op==="preview"&&o.started!==void 0&&performance.now()-o.started>500&&this.crashed("superseded by a newer request"),null}case"source_facts":case"trace_bands":case"snap_inks":case"match_palette":case"plan_export":case"minify_svg":case"fab_analyze":return this.enqueue(t,0,{args:s});case"fab_prepare":return this.enqueue(t,0,{args:s},"fab");case"write_export":{const o=s.request,a=await this.enqueue("export",0,{request:o,zip:!0}),i=(this.source?.name??"image").replace(/\.[^.]+$/,"")||"image";if(a.length===1&&a[0].name)return Ze(a[0].name,a[0].data),[a[0].name];const r=`${i}-inkvec.zip`;return a[0]&&Ze(r,a[0].data,"application/zip"),[r]}case"read_text_file":throw new Error("A browser reads files you choose or drop, not paths.");case"save_bytes":{const o=String(s.path);return Ze(o.split(/[\\/]/).pop()||"download",new Uint8Array(s.bytes)),null}case"batch_scan":case"batch_start":case"batch_stats_csv":throw new Error(ws);case"batch_pause":case"batch_cancel":return null;case"denoiser_status":return this.denoiserStatus();case"denoiser_download":return this.downloadDenoiser();case"denoiser_cancel":return this.fetchState.phase==="downloading"&&(this.cancelled=!0,this.wanted=!1,this.denoiser?.postMessage({type:"abort"})),this.downloading&&(this.downloading=!1,this.emit("denoiser:done",{ok:!1,message:"cancelled",status:await this.denoiserStatus()})),null;case"denoiser_remove":try{await caches.delete(ys);for(const o of await caches.keys())o.startsWith(Pa)&&await caches.delete(o)}catch{}return this.denoiser?.postMessage({type:"forget"}),this.fetchState.phase!=="ready"&&this.setFetch({phase:"idle",got:0,total:null}),this.denoiserStatus();case"load_prefs":return this.loadPrefs();case"save_prefs":{this.prefs={...this.prefs??{},...s.prefs},this.storePrefs();const o=await this.enqueue("sanitise_prefs",0,{args:{prefs:s.prefs}});return this.prefs=o,this.storePrefs(),o}case"reset_prefs":{const o=await this.loadPrefs();return this.prefs=await this.enqueue("reset_prefs",0,{args:{prefs:o}}),this.storePrefs(),this.prefs}case"third_party_notices":{const a=(await Promise.all(["STUDIO_THIRD_PARTY.md","THIRD_PARTY.md"].map(i=>fetch(new URL(i,this.base())).then(r=>r.ok?r.text():null,()=>null)))).filter(i=>!!i);if(!a.length)throw new Error("the notices could not be fetched");return a.join(`
|
| 4 |
|
| 5 |
|
| 6 |
-
`)}case"check_update":return{latest:null,newer:!1,url:"https://github.com/logolabs/inkvec/releases",offline:"a web page is always the version it is served as"};case"cli_status":case"context_menu_status":case"install_cli":case"remove_cli":case"install_context_menu":case"remove_context_menu":return{available:!1,installed:!1,path:null,note:ws}}throw new Error(`${t} is not something the browser build does`)}bump(){return this.generation++,this.shared&&Atomics.store(this.shared,0,this.generation),this.generation}async open(t,s){return this.source={bytes:t.slice(),name:s},this.bump(),this.queue=this.queue.filter(o=>o.kind?(o.resolve(null),!1):!0),this.supersede(!0),this.enqueue("open_bytes",0,{bytes:t,name:s})}async loadPrefs(){if(this.prefs)return this.prefs;const t=Aa();return this.prefs=await(t?this.enqueue("sanitise_prefs",0,{args:{prefs:t}}):this.enqueue("default_prefs",0,{args:{}})),this.prefs}rememberTrace(t){if(!this.prefs)return;const s={...t};delete s.colourGroups,this.prefs={...this.prefs,trace:s},window.clearTimeout(this.prefsTimer),this.prefsTimer=window.setTimeout(()=>this.storePrefs(),1e3)}storePrefs(){Ca(this.prefs)}startDenoiser(t,s){if(this.denoiser||!this.denoiserPort)return;const o=new Worker(new URL(""+new URL("denoiser.worker-DjPuHhk4.js",import.meta.url).href,import.meta.url),{type:"module",name:"inkvec-denoiser"});this.denoiser=o,o.onmessage=a=>void this.denoiserMessage(a.data),o.postMessage({type:"init",base:this.base(),token:"d8fd58375cca",url:t,sha256:s,port:this.denoiserPort},[this.denoiserPort])}setFetch(t){this.fetchState={...this.fetchState,retrace:void 0,...t},this.emit("denoiser:fetch",this.fetchState)}get denoiserFetch(){return this.fetchState}async denoiserMessage(t){const s=this.fetchState.phase;switch(t.type){case"progress":if(s==="preparing"||s==="ready")return;this.setFetch({phase:"downloading",got:t.got??0,total:t.total??null,message:void 0,saveData:void 0}),this.downloading&&this.emit("denoiser:progress",{got:t.got,total:t.total});return;case"stored":{if(s==="preparing"||s==="ready")return;const o=this.fetchState.total??this.fetchState.got;this.setFetch({phase:"stored",got:o,total:o,message:void 0}),this.downloading&&(this.downloading=!1,this.emit("denoiser:done",{ok:!0,status:await this.denoiserStatus()}));return}case"preparing":this.setFetch({phase:"preparing",message:void 0});return;case"ran":this.denoiserRuns++;return;case"loaded":{const o=this.wanted;this.wanted=!1,this.setFetch({phase:"ready",message:void 0,retrace:o});return}case"failed":{const o=t.message??"the download did not finish";if(this.cancelled||/abort/i.test(o)){this.cancelled=!1,this.setFetch({phase:"idle",message:void 0});return}this.setFetch({phase:"failed",message:o}),this.downloading&&(this.downloading=!1,this.emit("denoiser:done",{ok:!1,message:o,status:await this.denoiserStatus()})),t.during==="download"&&!this.retried&&(this.retried=!0,window.setTimeout(()=>{this.fetchState.phase==="failed"&&this.denoiser?.postMessage({type:this.wanted?"prepare":"prefetch"})},La));return}}}prefetchDenoiser(){if(navigator.connection?.saveData){this.setFetch({phase:"idle",saveData:!0});return}this.denoiser?.postMessage({type:"prefetch"})}withoutUnreadyDenoiser(t){const s=t.settings?.cleanUpDamage;return!s||s==="off"||!this.denoiser||this.fetchState.phase==="ready"?t:(this.wanted=!0,this.cancelled=!1,this.denoiser.postMessage({type:"prepare"}),{...t,settings:{...t.settings,cleanUpDamage:"off"}})}async denoiserStatus(){const t=await this.whenReady();let s=!1,o=null;try{const a=await(await caches.open(ys)).match(t.denoiserUrl);a&&(s=!0,o=Number(a.headers.get("content-length"))||(await a.blob()).size)}catch{}return{supported:t.isolated,installed:s,path:null,bytes:o,repo:t.denoiserRepo,sha256:t.denoiserSha256}}async downloadDenoiser(){if(await this.whenReady(),!this.denoiser)throw new Error("The denoiser needs a cross-origin isolated page.");return this.downloading=!0,this.cancelled=!1,this.denoiser.postMessage({type:this.wanted?"prepare":"download"}),null}}function Fa(e,t){const s=o=>{const a={...o?.settings??{}};return delete a.minify,delete a.margin,JSON.stringify(Object.keys(a).sort().map(i=>[i,a[i]]))};return s(e)===s(t)}let Mt=null;function On(){return Mt||(Mt=new Da,globalThis.__inkvecStudioLite=Mt),Mt}function B(e,t){return On().invoke(e,t)}function Me(e,t){return On().listen(e,t)}const _={capabilities:()=>B("capabilities"),startupProgress:(e,t)=>B("startup_progress",{text:e,progress:t}),appReady:()=>B("app_ready"),openPath:e=>B("open_path",{path:e}),openBytes:(e,t)=>B("open_bytes",{bytes:e,name:t??null}),openSample:e=>B("open_sample",{name:e}),listSamples:()=>B("list_samples"),startTrace:(e,t)=>B("start_trace",{request:{settings:e,tier:t}}),cancelTrace:()=>B("cancel_trace"),startPreview:e=>B("start_preview",{request:{settings:e,tier:"draft"}}),cancelPreviews:()=>B("cancel_previews"),sourceFacts:e=>B("source_facts",{maxDim:e}),launchPath:()=>B("launch_path"),traceBands:e=>B("trace_bands",{generation:e}),snapInks:(e,t,s,o)=>B("snap_inks",{svg:e,snaps:t,width:s,height:o}),matchPalette:(e,t)=>B("match_palette",{traced:e,pasted:t}),planExport:e=>B("plan_export",{request:e}),writeExport:(e,t)=>B("write_export",{request:e,destination:t}),minify:(e,t)=>B("minify_svg",{svg:e,settings:t}),fabAnalyze:e=>B("fab_analyze",{svg:e}),fabPrepare:(e,t)=>B("fab_prepare",{svg:e,options:t}),readTextFile:e=>B("read_text_file",{path:e}),saveBytes:(e,t)=>B("save_bytes",{path:e,bytes:t}),batchScan:e=>B("batch_scan",{folder:e}),batchStart:e=>B("batch_start",{plan:e}),batchPause:e=>B("batch_pause",{paused:e}),batchCancel:()=>B("batch_cancel"),batchStatsCsv:()=>B("batch_stats_csv"),denoiserStatus:()=>B("denoiser_status"),denoiserDownload:()=>B("denoiser_download"),denoiserCancel:()=>B("denoiser_cancel"),denoiserRemove:()=>B("denoiser_remove"),loadPrefs:()=>B("load_prefs"),savePrefs:e=>B("save_prefs",{prefs:e}),resetPrefs:()=>B("reset_prefs"),thirdPartyNotices:()=>B("third_party_notices"),checkUpdate:()=>B("check_update"),cliStatus:()=>B("cli_status"),installCli:()=>B("install_cli"),removeCli:()=>B("remove_cli"),contextMenuStatus:()=>B("context_menu_status"),installContextMenu:()=>B("install_context_menu"),removeContextMenu:()=>B("remove_context_menu")},Ae={traceProgress:e=>Me("trace:progress",t=>e(t.payload)),traceDone:e=>Me("trace:done",t=>e(t.payload)),previewDone:e=>Me("preview:done",t=>e(t.payload)),openPath:e=>Me("open:path",t=>e(t.payload)),batchRow:e=>Me("batch:row",t=>e(t.payload)),batchTotals:e=>Me("batch:totals",t=>e(t.payload)),batchFinished:e=>Me("batch:finished",t=>e(t.payload)),denoiserProgress:e=>Me("denoiser:progress",t=>e(t.payload)),denoiserDone:e=>Me("denoiser:done",t=>e(t.payload)),denoiserFetch:e=>Me("denoiser:fetch",t=>e(t.payload))};function Na(e,t){return{caps:null,prefs:null,tab:"vectorize",screen:null,source:null,settings:e,preset:"logo",generation:0,tracing:!1,tracingTier:"final",tracingEngine:e.mode,liveStages:[],traceStarted:0,traceEnded:0,liveNow:null,traceLog:[],logOpen:!0,result:null,resultGeneration:0,resultEngine:e.mode,bandsMissing:!1,previous:null,svg:null,palette:[],snaps:[],colourGroups:[],groupSuggestions:null,resultGroups:[],dismissedGroups:[],simplifyTo:null,paletteSelection:[],hoverFill:null,losses:[],report:null,worstCorner:null,stageState:{kind:"empty"},justSwapped:!1,view:"side",show:{fill:!0,wireframe:!1,anchors:!1,handles:!1,certainty:!1},zoom:1,pan:{x:0,y:0},fitted:!0,flicked:!1,wipe:.5,detail:!1,railTab:"result",groupsOpen:{Detail:!0,Colour:!0,Shape:!0,Output:!1},exportOpen:!1,dragging:!1,minify:{name:null,before:null,settings:t,result:null,error:null},fab:{name:null,svg:null,analysis:null,options:lo(),plan:null,error:null,shown:-1,unit:"mm",showProblems:!0,preset:null,dxf:!1,gcode:!1},batch:{folder:null,outputDir:null,preset:"logo",skipExisting:!0,rows:[],totals:null,running:!1,paused:!1,failuresFirst:!1},update:null,denoiserFetch:null,auto:null,facts:null,chooser:!1,wizard:null,compare:null,autoNoteHidden:!1}}function lo(){return{mode:"singleColour",widthMm:100,include:[],order:[],bleedMm:.8,minFeatureMm:.8,removeThin:!1,stickerMarginMm:3,bridgeMm:1.5,stencilMarginMm:10,maxLineMm:0,penMm:.4,registration:!0,weedBorderMm:0,mirror:!1,cutStyle:"filled",sizeCheckMm:0,dogboneMm:0,gcodeFeedMmMin:1e3,gcodePower:1e3,gcodePasses:1,fileUnits:"mm",kerfMm:0,toleranceMm:.05,mergeDeltaE:3}}class Ia{constructor(t){R(this,"listeners",new Set);this.state=t}set(t){const s=new Set;for(const[o,a]of Object.entries(t))this.state[o]!==a&&(this.state[o]=a,s.add(o));s.size&&this.emit(s)}touch(...t){this.emit(new Set(t))}on(t,s){const o=new Set(t),a=i=>{for(const r of i)if(o.has(r)){s();return}};return this.listeners.add(a),()=>this.listeners.delete(a)}emit(t){for(const s of[...this.listeners])s(t)}}function oe(e){return e.toLocaleString("en-US")}function le(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ue(e){return e==null?"—":e.toFixed(2)}function gt(e){return e<1?`${Math.round(e*1e3)} ms`:`${e.toFixed(2)} s`}function mt(e,t){if(!e.source)return null;const s=Math.max(e.source.width,e.source.height),o=t==="draft"?Math.min(e.prefs?.draftPx??512,e.settings.traceSize):e.settings.traceSize;return Math.min(o,s)}function _n(e){return e==="fast"||e==="balanced"}function Mn(e){return e==="fast"?"Fast":e==="balanced"?"Balanced":"Quality"}function vt(e,t){const s=_n(t.mode)&&!t.blackAndWhite&&!t.lineArt;return e.modes==="qualityOnly"?!s:e.modes==="fastOnly"?s:!0}function Te(e,t=0){return`${(e*100).toFixed(t)}%`}function Oa(e){const t=Math.max(0,Math.round(e));return t<60?`${t} s`:`${Math.floor(t/60)} min ${t%60} s`}function co(e){return e==="macos"?"⌘":"Ctrl"}function _a(){return{preset:"logo",tab:"vectorize",railTab:"result",groupsOpen:{},view:"side",wipe:.5,show:{fill:!0,wireframe:!1,anchors:!1,handles:!1,certainty:!1},detail:!1,export:null,minify:null,minifyBackdrop:"auto",minifyView:"side",fab:null,fabUnit:"mm",fabShowProblems:!0,fabPreset:null,fabDxf:!1,fabGcode:!1,batchPreset:null,batchSkipExisting:!0,batchFailuresFirst:!1}}const ze={export:null,minifyBackdrop:"auto",minifyView:"side"};let En=()=>{};function Ba(){return{...ze}}function An(e){Object.assign(ze,e),En()}function Ra(e){const t=ze.export;return t?{...e,...t,pngSizes:[...t.pngSizes??e.pngSizes]}:e}function Cn(e){const t={...e.fab.options};return delete t.include,delete t.order,{preset:e.preset,tab:e.tab,railTab:e.railTab,groupsOpen:{...e.groupsOpen},view:e.view,wipe:e.wipe,show:{...e.show},detail:e.detail,export:ze.export,minify:{...e.minify.settings},minifyBackdrop:ze.minifyBackdrop,minifyView:ze.minifyView,fab:t,fabUnit:e.fab.unit,fabShowProblems:e.fab.showProblems,fabPreset:e.fab.preset,fabDxf:e.fab.dxf,fabGcode:e.fab.gcode,batchPreset:e.batch.preset,batchSkipExisting:e.batch.skipExisting,batchFailuresFirst:e.batch.failuresFirst}}function Tn(e){const t={...e};return delete t.colourGroups,t}function Ga(e,t,s,o){const a=e.state,i={..._a(),...t.ui??{}};ze.export=i.export,ze.minifyBackdrop=i.minifyBackdrop,ze.minifyView=i.minifyView,e.set({preset:i.preset&&o(i.preset)?i.preset:null,tab:s.includes(i.tab)?i.tab:"vectorize",railTab:i.railTab,groupsOpen:{...a.groupsOpen,...i.groupsOpen},view:i.view,wipe:i.wipe,show:{...a.show,...i.show},detail:i.detail,minify:{...a.minify,settings:{...a.minify.settings,...i.minify??{}}},fab:{...a.fab,options:{...lo(),...i.fab??{},include:[],order:[]},unit:i.fabUnit,showProblems:i.fabShowProblems,preset:i.fabPreset,dxf:i.fabDxf,gcode:i.fabGcode},batch:{...a.batch,preset:i.batchPreset&&o(i.batchPreset)?i.batchPreset:a.batch.preset,skipExisting:i.batchSkipExisting,failuresFirst:i.batchFailuresFirst}})}const Wa=["settings","preset","tab","railTab","groupsOpen","view","wipe","show","detail","minify","fab","batch"];function qa(e,t,s=500){let o=0,a=JSON.stringify({ui:Cn(e.state),trace:Tn(e.state.settings)});const i=()=>{if(window.clearTimeout(o),o=0,!e.state.prefs)return;const c={ui:Cn(e.state),trace:Tn(e.state.settings)},u=JSON.stringify(c);u!==a&&(a=u,t(c))};En=()=>{window.clearTimeout(o),o=window.setTimeout(i,s)};const r=e.on(Wa,En),l=()=>{document.visibilityState==="hidden"&&o&&i()};return window.addEventListener("pagehide",i),document.addEventListener("visibilitychange",l),()=>{r(),window.removeEventListener("pagehide",i),document.removeEventListener("visibilitychange",l)}}const Ha="modulepreload",Ua=function(e,t){return new URL(e,t).href},xs={},ja=function(t,s,o){let a=Promise.resolve();if(s&&s.length>0){let r=function(d){return Promise.all(d.map(h=>Promise.resolve(h).then(f=>({status:"fulfilled",value:f}),f=>({status:"rejected",reason:f}))))};const l=document.getElementsByTagName("link"),c=document.querySelector("meta[property=csp-nonce]"),u=c?.nonce||c?.getAttribute("nonce");a=r(s.map(d=>{if(d=Ua(d,o),d in xs)return;xs[d]=!0;const h=d.endsWith(".css"),f=h?'[rel="stylesheet"]':"";if(!!o)for(let m=l.length-1;m>=0;m--){const k=l[m];if(k.href===d&&(!h||k.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${d}"]${f}`))return;const g=document.createElement("link");if(g.rel=h?"stylesheet":Ha,h||(g.as="script"),g.crossOrigin="",g.href=d,u&&g.setAttribute("nonce",u),document.head.appendChild(g),h)return new Promise((m,k)=>{g.addEventListener("load",m),g.addEventListener("error",()=>k(new Error(`Unable to preload CSS for ${d}`)))})}))}function i(r){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=r,window.dispatchEvent(l),!l.defaultPrevented)throw r}return a.then(r=>{for(const l of r||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})};async function Va(e={}){return typeof e=="object"&&Object.freeze(e),await Kt("plugin:dialog|open",{options:e})}async function Ka(e={}){return typeof e=="object"&&Object.freeze(e),await Kt("plugin:dialog|save",{options:e})}async function Ya(e,t){await Kt("plugin:opener|open_url",{url:e,with:t})}async function Za(e){return Kt("plugin:opener|reveal_item_in_dir",{paths:typeof e=="string"?[e]:e})}const Yt="Inkvec Studio Lite",uo="https://github.com/logolabs/inkvec/releases",Ja="Inkvec Studio for Windows, macOS and Linux: the native engine is faster, it traces whole folders in one batch, has no browser memory limit (traces up to 16384 px), and works offline.";function po(e){return{name:e.name||"pasted image",path:null,file:e}}async function Bn(e,t=!1){return new Promise(s=>{const o=document.createElement("input");o.type="file",o.multiple=t,o.accept=e.flatMap(r=>r.extensions.map(l=>`.${l}`)).join(","),o.style.display="none";let a=!1;const i=r=>{a||(a=!0,o.remove(),s(r))};o.addEventListener("change",()=>i([...o.files??[]].map(po))),o.addEventListener("cancel",()=>i([])),document.body.append(o),o.click()})}async function Rt(e){if(e.file)return e.file.text();if(e.path)return _.readTextFile(e.path);throw new Error("nothing to read")}const ks=!1;async function ho(e,t,s){const o=typeof t=="string"?new TextEncoder().encode(t):t;return Ze(e,o),{path:null,name:e}}async function Xa(e,t,s){const o=new TextEncoder,a=i=>typeof i=="string"?o.encode(i):i;{if(e.length===1)Ze(e[0].name,a(e[0].data));else{const{zipStore:i}=await ja(async()=>{const{zipStore:r}=await import("./zip-DlX9-WSC.js");return{zipStore:r}},[],import.meta.url);Ze(t,i(e.map(r=>({name:r.name,data:a(r.data)}))))}return{folder:null,first:null}}}const Qa=!1;async function Zt(e){await navigator.clipboard.writeText(e)}async function Jt(e){{window.open(e,"_blank","noopener,noreferrer");return}}function Xt(e){return e&&Qa?{label:"Show in folder",run:()=>void 0}:void 0}const fo={mode:"quality",precision:.1,speckleFloor:2,traceSize:2048,timeLimit:0,maxColours:64,colourMerging:.035,flatFills:!1,blackAndWhite:!1,monochrome:!1,cleanUpDamage:"off",matchRepeatedShapes:!0,matchThreshold:.92,fewerPaths:!1,lineArt:!1,repairRings:!0,editability:!1,bezierCost:6,cornerAngle:10,minify:!1,transparentBackground:!1,margin:0,holesAsCutouts:!1,traceTransparency:!0};function ei(e,t,s){const o=e?.presets.find(i=>i.id===s);if(o)return{settings:o.settings,wantsDenoiser:o.wantsDenoiser};const a=t?.saved.find(i=>i.id===s);return a?{settings:a.settings,wantsDenoiser:!1}:null}function ti(e){return/^[0-9]$/.test(e)?(Number(e)+9)%10:null}const ni=8;class si{constructor(t){R(this,"watching",0);R(this,"newest",0);R(this,"early",new Map);R(this,"groupsSent",new Map);R(this,"settleTimer");R(this,"afterDraft",null);this.host=t}async trace(t){this.dropAfterDraft(),await this.begin(t,!1)}open(t){return this.dropAfterDraft(),t?new Promise(s=>{const o={draft:0,resolve:s};this.afterDraft=o,this.begin("draft",!0).then(a=>{a===null&&this.afterDraft===o&&this.dropAfterDraft()})}):this.begin("final",!1).then(()=>{})}async begin(t,s){if(!this.host.hasSource())return null;const o=performance.now();try{const a=this.host.groups(),i=await this.host.start(t,s);if(i<this.newest)return null;this.newest=i,s&&this.afterDraft?.draft===0&&(this.afterDraft.draft=i),this.groupsSent.set(i,a);for(const l of this.groupsSent.keys())l<i-ni&&this.groupsSent.delete(l);this.watching=i,this.host.began(i,t,o);const r=this.early.get(i);for(const l of this.early.keys())l<=i&&this.early.delete(l);for(const l of r?.progress??[])this.progressed(l);return r?.done&&this.landed(r.done,i),i}catch(a){return this.host.failed(a),null}}landed(t,s){this.host.finished(t,s);const o=this.afterDraft;o&&o.draft===s&&(this.afterDraft=null,this.begin("final",!1).then(()=>o.resolve()))}dropAfterDraft(){const t=this.afterDraft;this.afterDraft=null,t?.resolve()}onProgress(t){if(t.generation>this.newest){this.hold(t.generation).progress.push(t);return}this.progressed(t)}onDone(t,s){if(t>this.newest){this.hold(t).done=s;return}const o=this.host.shown();t!==o.generation||!o.tracing||this.landed(s,t)}controlChanged(){this.clearSettle(),this.host.hasSource()&&(this.trace("draft"),this.settleTimer=setTimeout(()=>void this.trace("final"),this.host.settleMs()))}get waitingForDraft(){return this.afterDraft!==null}cancel(){this.clearSettle(),this.host.cancel()}clearSettle(){clearTimeout(this.settleTimer),this.settleTimer=void 0,this.dropAfterDraft()}detach(){this.clearSettle(),this.watching=0}groupsFor(t){return this.groupsSent.get(t)}progressed(t){t.generation===this.watching&&this.host.progressed(t)}hold(t){const s=this.early.get(t)??{progress:[]};return this.early.set(t,s),s}}class oi{constructor(){R(this,"last",0)}take(){return++this.last}isNewest(t){return t===this.last}}function Re(e){const t={...e,cleanUpDamage:"off"};return JSON.stringify(Object.keys(t).sort().map(s=>[s,t[s]]))}class ai{constructor(){R(this,"results",new Map);R(this,"queue",[]);R(this,"running",null);R(this,"epoch",0);R(this,"early",new Map);R(this,"listeners",new Set);Ae.previewDone(({generation:t,outcome:s})=>this.done(t,s))}get(t){return this.results.get(t)}on(t){return this.listeners.add(t),()=>this.listeners.delete(t)}want(t){const s=new Set,o=t.filter(a=>{if(s.has(a.key))return!1;s.add(a.key);const i=this.results.get(a.key)?.state;return i!=="done"&&i!=="running"});if(o.map(a=>a.key).join(`
|
| 7 |
`)!==this.queue.map(a=>a.key).join(`
|
| 8 |
`)){for(const a of this.queue)this.results.get(a.key)?.state==="queued"&&this.results.delete(a.key);this.queue=o;for(const a of this.queue)this.results.set(a.key,{state:"queued"});this.emit(),this.next()}}pause(){this.want([])}reset(){this.epoch++;for(const t of this.results.values())t.state==="done"&&URL.revokeObjectURL(t.url);this.results.clear(),this.queue=[],this.early.clear(),this.running&&_.cancelPreviews().catch(()=>{}),this.running=null,this.emit()}pending(){return this.queue.length+(this.running?1:0)}next(){if(this.running)return;const t=this.queue.shift();if(!t)return;const s=this.epoch;this.running={key:t.key,generation:null,epoch:s},this.results.set(t.key,{state:"running"}),this.emit(),_.startPreview(t.settings).then(o=>{if(this.running?.epoch!==s||this.running.key!==t.key)return;this.running.generation=o;const a=this.early.get(o);a&&(this.early.delete(o),this.done(o,a))},o=>{this.running?.epoch===s&&this.finish(t.key,{state:"failed",message:String(o)})})}done(t,s){const o=this.running;if(o){if(o.generation===null){this.early.set(t,s);return}if(o.generation===t)if(s.state==="traced"){const a=URL.createObjectURL(new Blob([s.svg],{type:"image/svg+xml"}));this.finish(o.key,{state:"done",svg:s.svg,url:a,report:s.report})}else{const a="message"in s?s.message:s.state==="flat"?"one flat colour":s.state==="cancelled"?"stopped":"out of memory";this.finish(o.key,{state:"failed",message:a})}}}finish(t,s){this.results.set(t,s),this.running=null,this.emit(),this.next()}emit(){for(const t of[...this.listeners])t()}}const Ss=400;function ii(e,t,s){let o=e.liveStages,a=e.liveNow;const i=[...e.traceLog],r=c=>{for(let u=i.length-1;u>=0;u--){const d=i[u];if(d.kind==="stage")return d.what===c&&d.ms===void 0?u:-1}return-1};for(const c of t.entries)if(c.kind==="begin")a={stage:c.stage,what:c.what,since:s,step:null},i.push({at:c.at,kind:"stage",stage:c.stage,what:c.what});else if(c.kind==="end"){if(c.stage!=="measure"){const d=o.findIndex(h=>h.name===c.stage);o=d>=0?o.map((h,f)=>f===d?{...h,ms:h.ms+c.ms}:h):[...o,{name:c.stage,ms:c.ms}]}const u=r(c.what);u>=0?i[u]={...i[u],ms:c.ms,step:i[u].step??null}:i.push({at:Math.max(0,c.at-c.ms),kind:"stage",stage:c.stage,what:c.what,ms:c.ms}),a&&a.what===c.what&&(a=null)}else i.push({at:c.at,kind:"note",stage:c.stage,what:c.what,text:c.text});const l=t.step;if(l){!a||a.what!==l.what?a={stage:l.stage,what:l.what,since:s,step:l}:a={...a,step:l};const c=r(l.what);c>=0&&(i[c]={...i[c],step:l})}return{liveStages:o,liveNow:a,traceLog:i.length>Ss?i.slice(i.length-Ss):i}}function Rn(e){return e.total>0?`${e.done} / ${e.total} ${e.unit}`:`${e.unit} ${e.done}`}function Je(e){const t=Math.max(0,e)/1e3;return t<60?`${t.toFixed(1)} s`:`${Math.floor(t/60)} min ${String(Math.floor(t%60)).padStart(2,"0")} s`}function $s(e){return`${(Math.max(0,e)/1e3).toFixed(2)}`}function ri(e,t,s){let o=0;const a=()=>{const r=performance.now(),l=t(),c=s();for(const u of document.querySelectorAll('[data-live="elapsed"]'))u.textContent=Je(r-l);for(const u of document.querySelectorAll('[data-live="stage"]'))u.textContent=c===null?"":Je(r-c)},i=()=>{e()&&!o?(a(),o=window.setInterval(a,100)):!e()&&o&&(window.clearInterval(o),o=0)};return()=>{i(),o&&a()}}function Qt(e){const t=e.liveNow;if(t){const s=t.stage==="measure"?"measuring":t.stage;return t.step?`${s} · ${Rn(t.step)}`:`${s} · ${t.what}`}return e.liveStages[e.liveStages.length-1]?.name??"starting"}function en(e){return Je(performance.now()-e.traceStarted)}const li=["a[href]","button:not([disabled])","input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","iframe","[tabindex]:not([tabindex='-1'])","[contenteditable='true']"].join(","),go="#toasts, #overlays, .tooltip, script, style, link";function Gt(e){return[...e.querySelectorAll(li)].filter(t=>{if(t.closest("[hidden], [inert]"))return!1;const s=t.checkVisibility;return typeof s=="function"?s.call(t):t.getClientRects().length>0})}const Le=[];function ci(e){const t=[];for(let s=e;s&&s!==document.body;s=s.parentElement){const o=s.parentElement;if(!o)break;for(const a of o.children)a!==s&&a instanceof HTMLElement&&!a.matches(go)&&t.push(a)}return t}function Ms(e){const t=Le[Le.length-1];if(!t)return;if(e.key==="Escape"&&t.opts.onEscape){e.preventDefault(),e.stopPropagation(),t.opts.onEscape();return}if(e.key!=="Tab")return;const s=Gt(t.root),o=document.activeElement,a=!!(o&&t.root.contains(o));if(!s.length){e.preventDefault(),t.root.focus();return}const i=s[0],r=s[s.length-1];(!a||e.shiftKey&&o===i||!e.shiftKey&&o===r)&&(e.preventDefault(),(e.shiftKey?r:i).focus())}function Es(e){const t=Le[Le.length-1],s=e.target;!t?.opts.onOutside||!s||t.root.contains(s)||s.closest?.(go)||t.opts.onOutside()}function As(e){e.ctrlKey||e.metaKey||e.key==="Tab"||/^F\d{1,2}$/.test(e.key)||e.stopPropagation()}function tn(e,t={}){const s=document.activeElement,o=s instanceof HTMLElement&&s!==document.body?s:null;e.hasAttribute("tabindex")||e.setAttribute("tabindex","-1");const a=ci(e).filter(c=>!c.inert);for(const c of a)c.inert=!0;const i={root:e,opts:t,opener:o,inerted:a};Le.length||(document.addEventListener("keydown",Ms,!0),document.addEventListener("pointerdown",Es,!0)),Le.push(i),e.addEventListener("keydown",As),(t.initial?.()??Gt(e)[0]??e).focus({preventScroll:!0});let l=!1;return(c=!0)=>{if(l)return;l=!0;const u=Le.indexOf(i);u>=0&&Le.splice(u,1),Le.length||(document.removeEventListener("keydown",Ms,!0),document.removeEventListener("pointerdown",Es,!0)),e.removeEventListener("keydown",As);for(const h of a)h.inert=!1;if(!c)return;(o?.isConnected?o:t.fallback?.())?.focus({preventScroll:!0})}}const Wt=()=>document.getElementById("overlays"),ui=()=>document.getElementById("toasts");function G(e,t={}){const s=t.kind??"plain",o=s==="good"?"checkCircle":s==="bad"?"alert":"info",a=n("div.toast",{role:"status"},n(`span.glyph.${s}`,null,V(o,16)),n("span.text",null,e),t.action&&n("button",{class:"reset",onclick:()=>{t.action?.run(),a.remove()}},t.action.label));ui().append(a),window.setTimeout(()=>a.remove(),6e3)}let He=null,Pn=null;function he(){const e=Wt().contains(document.activeElement);D(Wt()),document.removeEventListener("keydown",Gn,!0);const t=He;He=null,t?.();const s=Pn;Pn=null,s?.isConnected&&(e||document.activeElement===document.body)&&s.focus({preventScroll:!0})}function Gn(e){e.key==="Escape"&&(e.stopPropagation(),he())}let di=0;function ot(e){He?.(!1),He=null;const t=n("div.scrim",{onmousedown:o=>{o.target===t&&he()}});e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true");const s=e.querySelector("h1, h2, h3");s&&!e.hasAttribute("aria-label")&&!e.hasAttribute("aria-labelledby")&&(s.id||=`modal-title-${++di}`,e.setAttribute("aria-labelledby",s.id)),t.append(e),D(Wt(),t),document.removeEventListener("keydown",Gn,!0),He=tn(e,{initial:()=>e.querySelector("button, input, select, textarea, [tabindex]:not([tabindex='-1'])"),onEscape:he})}function nn(e,t,s=[]){return n("div.modal",{tabindex:"-1"},n("h2",null,e),...t.filter(Boolean).map(o=>typeof o=="string"?n("p",null,o):o),s.length?n("div.actions",null,...s):null)}function Wn(e,t){He?.(!1),He=null,Pn=e;const s=n("div.popover",null,t),o=n("div",{style:{position:"fixed",inset:"0",zIndex:"44"},onmousedown:he});D(Wt(),o,s),document.addEventListener("keydown",Gn,!0);const a=e.getBoundingClientRect(),i=s.getBoundingClientRect(),r=8,l=Math.min(Math.max(r,a.left),window.innerWidth-i.width-r),c=a.bottom+6,u=c+i.height+r>window.innerHeight?a.top-i.height-6:c;s.style.left=`${Math.round(l)}px`,s.style.top=`${Math.round(Math.max(r,u))}px`,(s.querySelector("button, input, [tabindex]")??s).focus?.()}let Ue=null,qn=0;function bt(){window.cancelAnimationFrame(qn),Ue?.node.remove(),Ue=null}function mo(){const e=Ue;if(!e)return;if(!(e.el.isConnected&&(e.el.matches(":hover")||e.el.matches(":focus-visible")))){bt();return}qn=window.requestAnimationFrame(mo)}function We(e,t){let s=0;const o=()=>{if(!e.isConnected||Ue?.el===e)return;bt();const i=n("div.tooltip",{role:"tooltip"},t);document.body.append(i);const r=e.getBoundingClientRect(),l=i.getBoundingClientRect(),c=Math.min(Math.max(8,r.left),window.innerWidth-l.width-8),u=r.top-l.height-8;i.style.left=`${Math.round(c)}px`,i.style.top=`${Math.round(u<8?r.bottom+8:u)}px`,Ue={node:i,el:e},qn=window.requestAnimationFrame(mo)},a=()=>{window.clearTimeout(s),Ue?.el===e&&bt()};return e.addEventListener("pointerenter",()=>{window.clearTimeout(s),s=window.setTimeout(o,350)}),e.addEventListener("pointerleave",a),e.addEventListener("pointerdown",a),e.addEventListener("focus",()=>{e.matches(":focus-visible")&&o()}),e.addEventListener("blur",a),e}document.addEventListener("keydown",e=>{e.key==="Escape"&&Ue&&bt()},!0);window.addEventListener("blur",bt);function pi(e,t,s,o,a=!1){ot(nn(e,[t],[n("button.btn",{onclick:he},"Cancel"),n(`button.btn.primary${a?".danger":""}`,{onclick:()=>{he(),o()}},s)]))}function bo(e){const t=e.trim().replace(/^#/,""),s=t.length===3?[...t].map(o=>o+o).join(""):t;return/^[0-9a-fA-F]{6}$/.test(s)?[0,2,4].map(o=>parseInt(s.slice(o,o+2),16)/255):null}function yo([e,t,s]){const o=g=>g<=.04045?g/12.92:((g+.055)/1.055)**2.4,[a,i,r]=[o(e),o(t),o(s)],l=(.4124564*a+.3575761*i+.1804375*r)/.95047,c=.2126729*a+.7151522*i+.072175*r,u=(.0193339*a+.119192*i+.9503041*r)/1.08883,d=g=>g>216/24389?Math.cbrt(g):(24389/27*g+16)/116,[h,f,p]=[d(l),d(c),d(u)];return[116*f-16,500*(h-f),200*(f-p)]}function hi(e,t){const[s,o,a]=e,[i,r,l]=t,c=Math.PI/180,u=Math.hypot(o,a),d=Math.hypot(r,l),h=((u+d)/2)**7,f=.5*(1-Math.sqrt(h/(h+25**7))),p=(1+f)*o,g=(1+f)*r,m=Math.hypot(p,a),k=Math.hypot(g,l),E=(ce,Fe)=>{if(ce===0&&Fe===0)return 0;const ye=Math.atan2(Fe,ce)/c;return ye<0?ye+360:ye},x=E(p,a),$=E(g,l),y=i-s,v=k-m;let M=0;m*k!==0&&(M=$-x,M>180?M-=360:M<-180&&(M+=360));const A=2*Math.sqrt(m*k)*Math.sin(M*c/2),T=(s+i)/2,O=(m+k)/2;let Z=x+$;m*k!==0&&(Z=Math.abs(x-$)<=180?(x+$)/2:x+$<360?(x+$+360)/2:(x+$-360)/2);const te=1-.17*Math.cos((Z-30)*c)+.24*Math.cos(2*Z*c)+.32*Math.cos((3*Z+6)*c)-.2*Math.cos((4*Z-63)*c),P=30*Math.exp(-(((Z-275)/25)**2)),L=O**7,Q=2*Math.sqrt(L/(L+25**7)),U=1+.015*(T-50)**2/Math.sqrt(20+(T-50)**2),W=1+.045*O,ee=1+.015*O*te,K=-Math.sin(2*P*c)*Q,ae=y/U,ie=v/W,ne=A/ee;return Math.sqrt(ae*ae+ie*ie+ne*ne+K*ie*ne)}function qt(e){return e.kind==="gradient"&&e.stops.length>1?e.stops.map(t=>t.toLowerCase()).join(">"):e.traced.toLowerCase()}function Qe(e){return e.split(">").map(t=>t.trim().toLowerCase())}function xt(e){return e.includes(">")}function Hn(e,t=!1){const s=Qe(e);return s.length<2?s[0]??"transparent":t?`radial-gradient(circle, ${s.join(", ")})`:`linear-gradient(90deg, ${s.join(", ")})`}const Et=new Map;function Cs(e){const t=Et.get(e);if(t)return t;const s=bo(e);if(!s)return null;const o=yo(s);return Et.size>4096&&Et.clear(),Et.set(e,o),o}function Un(e,t){const s=Qe(e).map(Cs),o=Qe(t).map(Cs);if(s.some(l=>!l)||o.some(l=>!l)||!s.length||!o.length)return 1/0;const a=s,i=o,r=(l,c)=>l.reduce((u,d)=>u+Math.min(...c.map(h=>hi(d,h))),0)/l.length;return Math.max(r(a,i),r(i,a))}const fi=2;function sn(e,t){const s=xt(e),o=t.find(r=>qt(r)===e);if(o)return o;let a=null,i=fi;for(const r of t){if(r.kind==="gradient"!==s)continue;const l=Un(e,qt(r));l<=i&&(i=l,a=r)}return a}function Ce(e,t){return e===t||Un(e,t)<.5}const gi=2,mi=240;function bi(e,t={}){const s=t.skip??[],o=e.filter(d=>d.share>0),a=[...o].sort((d,h)=>h.share-d.share).slice(0,mi).map(d=>({member:qt(d),share:d.share})).filter(d=>!s.some(h=>Ce(h,d.member))),i=a.length;if(i<2)return[];const r=a.map((d,h)=>a.map((f,p)=>h===p?0:Un(d.member,f.member))),l=a.map((d,h)=>[h]);let c=i;const u=t.count?Math.max(1,Math.round(t.count)-(o.length-i)):null;for(;!(u!==null&&c<=u);){let d=1/0,h=-1,f=-1;for(let p=0;p<i;p++)if(l[p])for(let g=p+1;g<i;g++)l[g]&&r[p][g]<d&&(d=r[p][g],h=p,f=g);if(h<0||u===null&&d>gi)break;l[h]=[...l[h],...l[f]],l[f]=null,c--;for(let p=0;p<i;p++){if(p===h||!l[p])continue;const g=Math.max(r[h][p],r[f][p]);r[h][p]=g,r[p][h]=g}}return l.filter(Boolean).filter(d=>d.length>1).map(d=>d.map(h=>a[h]).sort((h,f)=>f.share-h.share)).sort((d,h)=>h.reduce((f,p)=>f+p.share,0)-d.reduce((f,p)=>f+p.share,0)).map(d=>({members:d.map(h=>h.member),target:null}))}function jn(e){return[...e.members].sort().join(",")}function yi(e){return e.filter(t=>t.trimStart().startsWith("merge colors")).map(t=>{const s=t.trim().replace(/^merge colors\s+/,""),o=/;\s*(?:not found in the trace:|no ink near)\s*(.*)$/.exec(s),a=(o?.[1]??"").split(",").map(i=>i.trim().toLowerCase()).filter(i=>/^#[0-9a-f]{6}(>#[0-9a-f]{6})*$/.test(i));return{line:o?s.slice(0,o.index).trim():s,unmatched:a,leftAlone:s.startsWith("group left alone")}})}function wi(e,t){return e?e.unmatched.some(s=>s===t||Qe(t).includes(s)||Ce(s,t)):!1}function wo(e){const t=(e.groupSuggestions??[]).filter(a=>a.edited),s=[...e.colourGroups.flatMap(a=>a.members),...t.flatMap(a=>a.members)],o=bi(e.palette,{count:e.simplifyTo,skip:s}).filter(a=>!e.dismissedGroups.includes(jn(a)));return[...t,...o]}function vi(e,t){const s=e.members.filter(a=>sn(a,t));if(s.length<2)return null;let o=e.target;if(o?.startsWith("@")){const a=e.members[Number(o.slice(1))-1],i=a?s.indexOf(a):-1;o=i>=0?`@${i+1}`:null}return{...e,members:s,target:o}}function Vn(e){return(e.groupSuggestions??[]).map((t,s)=>({g:vi(t,e.palette),index:s})).filter(t=>t.g!==null)}function vo(e,t){let s=e.target;if(s?.startsWith("@")){const o=Number(s.slice(1))-1;s=o===t?null:o>t?`@${o}`:s}return{...e,members:e.members.filter((o,a)=>a!==t),target:s}}function ke(e,t,s=-1,o=!1){return e.map((a,i)=>{if(i===s)return a;const r=a.members.findIndex(l=>Ce(l,t));return r<0?a:{...vo(a,r),...o?{edited:!0}:{}}})}const et=e=>e.filter(t=>t.members.length>1);function xi(e,t,s,o,a){const i=e.state;let r=i.colourGroups.map(f=>({...f,members:[...f.members]})),l=(i.groupSuggestions??[]).map(f=>({...f,members:[...f.members]}));const c=a?.closest("[data-drop]")??null,u=c?.dataset.drop??null,d=Number(c?.dataset.index??-1);if((u==="group"||u==="sugg")&&o.kind===u&&o.index===d||u==="ink"&&Ce(c?.dataset.member??"",s))return;if(u==="group")r=ke(r,s,d),l=ke(l,s,-1,!0),r[d].members.some(f=>Ce(f,s))||r[d].members.push(s);else if(u==="sugg")r=ke(r,s),l=ke(l,s,d,!0),l[d].members.some(f=>Ce(f,s))||(l[d]={...l[d],members:[...l[d].members,s],edited:!0});else if(u==="ink"){const f=c?.dataset.member??"";r=ke(r,s),l=ke(l,s,-1,!0);const p=r.findIndex(g=>g.members.some(m=>Ce(m,f)));p>=0?r[p].members.push(s):(l=ke(l,f,-1,!0),r.push({members:[f,s],target:null}))}else{if(o.kind==="palette")return;o.kind==="group"?r=ke(r,s):l=ke(l,s,-1,!0)}const h=et(r);e.set({groupSuggestions:et(l),paletteSelection:[]}),JSON.stringify(h)!==JSON.stringify(i.colourGroups)&&t.setColourGroups(h)}function ki(e,t){const s=e.state,o=s.paletteSelection;if(o.length<2)return;let a=s.colourGroups.map(l=>({...l,members:[...l.members]}));const i=a.findIndex(l=>l.members.some(c=>o.some(u=>Ce(u,c))));let r=s.groupSuggestions??[];for(const l of o)a=ke(a,l,i),r=ke(r,l,-1,!0);if(i>=0)for(const l of o)a[i].members.some(c=>Ce(c,l))||a[i].members.push(l);else a.push({members:[...o],target:null});e.set({groupSuggestions:et(r),paletteSelection:[]}),t.setColourGroups(et(a))}const Si=4;function xo(e,t,s,o,a,i){e.addEventListener("pointerdown",r=>{if(r.button!==0)return;const l=r.clientX,c=r.clientY;let u=null,d=null;const h=g=>{g!==d&&(d?.classList.remove("dropping"),d=g,d?.classList.add("dropping"))},f=g=>{if(!u){if(Math.hypot(g.clientX-l,g.clientY-c)<Si)return;u=n("div.dragghost",null,n("span.swatch",null,n("i",{style:{background:Hn(o,i)}}))),document.body.append(u),document.body.classList.add("dragging-ink")}u.style.left=`${g.clientX+8}px`,u.style.top=`${g.clientY+8}px`;const m=document.elementFromPoint(g.clientX,g.clientY);h(m?.closest("[data-drop]")??null)},p=g=>{if(window.removeEventListener("pointermove",f),window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",p),!u)return;u.remove(),document.body.classList.remove("dragging-ink"),h(null);const m=k=>k.stopPropagation();window.addEventListener("click",m,!0),window.setTimeout(()=>window.removeEventListener("click",m,!0),0),g.type!=="pointercancel"&&xi(t,s,o,a,document.elementFromPoint(g.clientX,g.clientY))};window.addEventListener("pointermove",f),window.addEventListener("pointerup",p),window.addEventListener("pointercancel",p)})}function At(e,t){return sn(e,t)?.keys??[]}function ko(e,t){let s=0;const o=()=>{let i=[...e.querySelectorAll("[data-fill]:hover")].pop()??null;if(!i){const l=document.activeElement;l instanceof HTMLElement&&e.contains(l)&&l.matches(":focus-visible")&&(i=l.closest("[data-fill]"))}const r=i?JSON.parse(i.dataset.fill??"[]"):[];return r.length?r:null},a=()=>{const i=o(),r=t.state.hoverFill;(i??[]).join(`
|
| 9 |
`)!==(r??[]).join(`
|
|
|
|
| 1 |
var la=Object.defineProperty;var ca=(e,t,s)=>t in e?la(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var R=(e,t,s)=>ca(e,typeof t!="symbol"?t+"":t,s);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))o(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const r of i.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&o(r)}).observe(document,{childList:!0,subtree:!0});function s(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(a){if(a.ep)return;a.ep=!0;const i=s(a);fetch(a.href,i)}})();async function Kt(e,t={},s){return window.__TAURI_INTERNALS__.invoke(e,t,s)}function ua(){return!!(globalThis||window).isTauri}var cs;(function(e){e.WINDOW_RESIZED="tauri://resize",e.WINDOW_MOVED="tauri://move",e.WINDOW_CLOSE_REQUESTED="tauri://close-requested",e.WINDOW_DESTROYED="tauri://destroyed",e.WINDOW_FOCUS="tauri://focus",e.WINDOW_BLUR="tauri://blur",e.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",e.WINDOW_THEME_CHANGED="tauri://theme-changed",e.WINDOW_CREATED="tauri://window-created",e.WINDOW_SUSPENDED="tauri://suspended",e.WINDOW_RESUMED="tauri://resumed",e.WEBVIEW_CREATED="tauri://webview-created",e.DRAG_ENTER="tauri://drag-enter",e.DRAG_OVER="tauri://drag-over",e.DRAG_DROP="tauri://drag-drop",e.DRAG_LEAVE="tauri://drag-leave"})(cs||(cs={}));var us;(function(e){e[e.Critical=1]="Critical",e[e.Informational=2]="Informational"})(us||(us={}));var ds;(function(e){e.None="none",e.Normal="normal",e.Indeterminate="indeterminate",e.Paused="paused",e.Error="error"})(ds||(ds={}));var ps;(function(e){e.Disabled="disabled",e.Throttle="throttle",e.Suspend="suspend"})(ps||(ps={}));var hs;(function(e){e.Default="default",e.FluentOverlay="fluentOverlay"})(hs||(hs={}));var fs;(function(e){e.AppearanceBased="appearanceBased",e.Light="light",e.Dark="dark",e.MediumLight="mediumLight",e.UltraDark="ultraDark",e.Titlebar="titlebar",e.Selection="selection",e.Menu="menu",e.Popover="popover",e.Sidebar="sidebar",e.HeaderView="headerView",e.Sheet="sheet",e.WindowBackground="windowBackground",e.HudWindow="hudWindow",e.FullScreenUI="fullScreenUI",e.Tooltip="tooltip",e.ContentBackground="contentBackground",e.UnderWindowBackground="underWindowBackground",e.UnderPageBackground="underPageBackground",e.Mica="mica",e.Blur="blur",e.Acrylic="acrylic",e.Tabbed="tabbed",e.TabbedDark="tabbedDark",e.TabbedLight="tabbedLight"})(fs||(fs={}));var gs;(function(e){e.FollowsWindowActiveState="followsWindowActiveState",e.Active="active",e.Inactive="inactive"})(gs||(gs={}));const da=`<!-- Generated by studio/tools/make_assets.py from web/logo.svg. Do not edit. -->
|
| 2 |
<svg color="#c9754a" xmlns="http://www.w3.org/2000/svg" viewBox="254.5 140.5 514.25 742.25"><path d="M511.3 140.6c-23.3 79.8-103 178.5-144.9 232.75L335.45 415.4a467.73 467.73 0 00-64.8 115.4c-65.5 193.1 80.8 351.3 237.85 351.7 21.26 1.1 42.56-1.3 63.06-7 90.8-18.87 211.87-120.04 195.47-280.9-17.9-164.8-187.55-272.65-251.8-443.84Zm10.2 374.9a61.05 61.05 0 00-67.1 81.6 61.05 61.05 0 00104.3 17.26 61.05 61.05 0 00-37.2-98.86ZM511.4 817.65l177.16-201.3-43-.15a44.56 44.56 0 00-36.2 18.47l-97.8 111.67-102.2-116.67c-16.06-18.94-38.06-12-74.9-13.4 5.7 7.3 159.75 179.73 176.93 201.4Z" fill="currentColor" fill-rule="evenodd"/></svg>
|
| 3 |
+
`;function n(e,t=null,...s){const[o,...a]=e.split("."),i=document.createElement(o||"div");return a.length&&(i.className=a.join(" ")),pa(i,t),Nn(i,s),i}function Ee(e,t=null,...s){const[o,...a]=e.split("."),i=document.createElementNS("http://www.w3.org/2000/svg",o||"g");a.length&&i.setAttribute("class",a.join(" "));for(const[r,l]of Object.entries(t??{}))l==null||l===!1||(r.startsWith("on")&&typeof l=="function"?i.addEventListener(r.slice(2),l):i.setAttribute(r,String(l)));return Nn(i,s),i}function pa(e,t){for(const[s,o]of Object.entries(t??{}))o==null||o===!1||(s==="class"?e.className=e.className?`${e.className} ${o}`:String(o):s==="style"&&typeof o=="object"?Object.assign(e.style,o):s.startsWith("on")&&typeof o=="function"?e.addEventListener(s.slice(2),o):s==="value"&&e instanceof HTMLInputElement?e.value=String(o):o===!0?e.setAttribute(s,""):e.setAttribute(s,String(o)))}function Nn(e,t){for(const s of t.flat(8))s==null||s===!1||e.append(s instanceof Node?s:document.createTextNode(String(s)))}function D(e,...t){e.replaceChildren(),Nn(e,t)}const ms={image:"M3 3h18v18H3zM3 15l5-5 4 4 3-3 6 6M8.5 8.5h.01",type:"M4 7V4h16v3M9 20h6M12 4v16",droplet:"M12 2.7 6.7 8a7.5 7.5 0 1 0 10.6 0Z",wand:"m3 21 9-9M15 4V2M15 16v-2M8 9h2M20 9h2M17.8 11.8 19 13M15 9h.01M17.8 6.2 19 5M12.8 6.2 11.6 5",layers:"m12 2 9 5-9 5-9-5 9-5M3 12l9 5 9-5M3 17l9 5 9-5",palette:"M12 21a9 9 0 1 1 0-18c4.97 0 9 3.58 9 8 0 1.66-1.34 3-3 3h-2a2 2 0 0 0-1.6 3.2 2 2 0 0 1-1.6 3.2ZM7.5 10.5h.01M10.5 7.5h.01M14 7.5h.01M16.5 10.5h.01",check:"m20 6-11 11-5-5",checkCircle:"M22 11.1V12a10 10 0 1 1-5.9-9.1M22 4 12 14.01l-3-3",x:"M18 6 6 18M6 6l12 12",alert:"M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z",info:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM12 16v-4M12 8h.01",clock:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM12 6v6l4 2",download:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3",upload:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12",globe:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10Z",copy:"M20 9H11a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2ZM5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",folder:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",settings:"M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6 1.65 1.65 0 0 0 10 3.09V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z",chevronDown:"m6 9 6 6 6-6",chevronRight:"m9 18 6-6-6-6",minus:"M5 12h14",pen:"M21.17 6.81a2.82 2.82 0 0 0-3.99-3.99L3.84 16.17a2 2 0 0 0-.5.83l-1.32 4.35a.5.5 0 0 0 .62.62l4.35-1.32a2 2 0 0 0 .83-.5Z",square:"M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2Z",crosshair:"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20ZM22 12h-4M6 12H2M12 6V2M12 22v-4",zap:"M4 14h7l-3 8 12-12h-7l3-8Z",play:"m6 3 14 9-14 9V3Z",pause:"M14 4h4v16h-4zM6 4h4v16H6z",rotate:"M3 12a9 9 0 1 0 3-6.7L3 8M3 3v5h5",share:"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13",file:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7ZM14 2v6h6",maximize:"M8 3H5a2 2 0 0 0-2 2v3M21 8V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3M16 21h3a2 2 0 0 0 2-2v-3",external:"M15 3h6v6M10 14 21 3M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"};function V(e,t=16){const s=ms[e]??ms.info;return Ee("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true",focusable:"false"},Ee("path",{d:s}))}function ao(e=18){const t=ha.cloneNode(!0);t.removeAttribute("color");const[,,s,o]=(t.getAttribute("viewBox")??"0 0 1 1").split(/\s+/).map(Number);return t.setAttribute("height",String(e)),t.setAttribute("width",String(Math.round(e*s/o))),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false"),t}const ha=(()=>{const e=new DOMParser().parseFromString(da,"image/svg+xml").documentElement;return document.importNode(e,!0)})();function fa(e,t){let s=0;const o=i=>[...i.dataTransfer?.types??[]].includes("Files"),a=()=>{s=0,e.set({dragging:!1}),document.body.classList.remove("dragging")};window.addEventListener("dragenter",i=>{o(i)&&(s++,e.set({dragging:!0}),document.body.classList.add("dragging"))}),window.addEventListener("dragover",i=>{o(i)&&(i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="copy"))}),window.addEventListener("dragleave",i=>{o(i)&&(s=Math.max(0,s-1),s===0&&a())}),window.addEventListener("drop",i=>{if(!o(i))return;i.preventDefault(),a();const r=[...i.dataTransfer?.files??[]];r.length&&t(r)}),ga(t)}function ga(e){window.addEventListener("paste",t=>{if(t.target?.closest?.("input, textarea, [contenteditable]"))return;let o=[...t.clipboardData?.files??[]];o.length||(o=[...t.clipboardData?.items??[]].filter(a=>a.kind==="file").map(a=>a.getAsFile()).filter(a=>a!==null)),o.length&&(t.preventDefault(),e(o))})}const ma=760,bs="inkvec-phone-tip-dismissed";function ba(e){const t=window.matchMedia(`(max-width: ${ma}px)`).matches,s=window.matchMedia("(pointer: coarse)").matches;if(!(t&&s))return;try{if(sessionStorage.getItem(bs))return}catch{}const o=document.documentElement;let a=null;const i=()=>{a?.disconnect(),o.style.removeProperty("--phonetip-h"),r.remove()},r=n("aside.phonetip",{"aria-label":"Tip",style:{position:"fixed",left:"0",right:"0",bottom:"0",zIndex:"40",display:"flex",alignItems:"center",gap:"8px",padding:"6px 6px 6px 14px",background:"var(--card)",borderTop:"1px solid var(--rule)",color:"var(--dim)",fontSize:"13px",lineHeight:"1.4"}},n("span",{style:{flex:"1"}},"Works on a phone; a larger screen shows the drawing, the controls and the palette side by side."),n("button.btn.ghost.compact",{"aria-label":"Close this tip",style:{minWidth:"32px",minHeight:"32px",justifyContent:"center"},onclick:()=>{i();try{sessionStorage.setItem(bs,"1")}catch{}}},V("x",14)));e.append(r);const l=()=>o.style.setProperty("--phonetip-h",`${r.offsetHeight}px`);l(),typeof ResizeObserver<"u"&&(a=new ResizeObserver(l),a.observe(r))}async function ya(){const e=new URLSearchParams(window.location.search),t=e.get("sample"),s=e.get("open")==="handoff",o=wa(window.location.hash);return!t&&!s&&!o?null:(window.history.replaceState(null,"",window.location.pathname),o||(t?{sample:t}:new Promise(a=>{let i;try{i=indexedDB.open("inkvec-handoff",1)}catch{a(null);return}i.onupgradeneeded=()=>i.result.createObjectStore("files"),i.onerror=()=>a(null),i.onsuccess=()=>{const r=i.result.transaction("files","readwrite").objectStore("files"),l=r.get("open");l.onsuccess=()=>{r.delete("open");const c=l.result;a(c?.bytes?{name:c.name??"image",bytes:c.bytes}:null)},l.onerror=()=>a(null)}})))}function wa(e){if(!e.startsWith("#"))return null;const t=new URLSearchParams(e.slice(1)),s=t.get("open");if(!s)return null;try{const o=s.replace(/-/g,"+").replace(/_/g,"/"),a=atob(o+"=".repeat(4-(o.length&3)&3)),i=new Uint8Array(a.length);for(let r=0;r<a.length;r++)i[r]=a.charCodeAt(r);return i.length?{name:t.get("name")||"image",bytes:i}:null}catch{return null}}const In=15e5;function va(e,t){if(!t.length||t.length>In)return null;let s="";for(let a=0;a<t.length;a+=32768)s+=String.fromCharCode(...t.subarray(a,a+32768));return`#open=${btoa(s).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}&name=${encodeURIComponent(e)}`}let Ft=0,Bt=null,$n=0,ft=!1,io=performance.now();const ln=e=>(e/(1024*1024)).toFixed(1);function xa(){$n=0;const e=Bt;if(Bt=null,!e||ft)return;Ft=e.fraction;const t=document.getElementById("boot-bar"),s=document.getElementById("boot-fill"),o=document.getElementById("boot-status"),a=document.getElementById("boot-pct"),i=document.getElementById("boot-detail"),r=Math.round(Ft*100);s&&(s.style.transform=`scaleX(${Ft})`),t?.setAttribute("aria-valuenow",String(r)),o&&(o.textContent=e.text),a&&(a.textContent=`${r}%`),i&&(i.textContent=e.detail)}function wt(e,t,s=""){ft||(io=performance.now(),Bt={text:e,fraction:Math.max(Ft,Bt?.fraction??0,Math.min(1,t)),detail:s},$n||($n=requestAnimationFrame(xa)))}function ka(e,t){const s=t>0?Math.min(1,e/t):0;wt("Downloading the engine",.04+.8*s,t>0?`${ln(e)} of ${ln(t)} MB`:`${ln(e)} MB`)}function Sa(){wt("Starting the engine",.88,"Compiling")}function $a(e,t){wt(e,.9+.1*Math.min(1,Math.max(0,t)))}function Ma(){if(ft)return;const e=document.getElementById("boot-fill");e&&(e.style.transitionDuration="0.12s"),wt("Ready",1),window.setTimeout(()=>{ft=!0;const t=document.getElementById("boot");t&&(t.classList.add("leaving"),window.setTimeout(()=>t.remove(),260))},130)}{window.__inkvecBoot=!0,wt("Loading the Studio",.03);const e=window.setInterval(()=>{if(ft){window.clearInterval(e);return}if(performance.now()-io>2e4){const t=document.getElementById("boot-detail");t&&(t.textContent="Still waiting for the network. On a slow connection the first visit can take a minute; later ones start from the browser's cache.")}},2e3)}function Ea(){let e;try{e=window.self!==window.top}catch{e=!0}const t=window.location.ancestorOrigins;if(t)for(let a=0;a<t.length;a++)/(^|\.)huggingface\.co(:\d+)?$/.test(t[a].replace(/^[a-z]+:\/\//,""))&&(e=!0);const s=document.documentElement;s.classList.toggle("framed",e);const o=()=>s.classList.toggle("fullscreen",!!document.fullscreenElement);document.addEventListener("fullscreenchange",o),o()}function Ze(e,t,s="application/octet-stream"){const o=t instanceof Blob?t:new Blob([t],{type:s}),a=URL.createObjectURL(o),i=document.createElement("a");i.href=a,i.download=e,i.style.display="none",document.body.append(i),i.click(),i.remove(),window.setTimeout(()=>URL.revokeObjectURL(a),6e4)}const ro="inkvec-studio-lite:prefs";function Aa(e=()=>localStorage){try{const t=e().getItem(ro);return t?JSON.parse(t):null}catch{return null}}function Ca(e,t=()=>localStorage){try{return t().setItem(ro,JSON.stringify(e)),!0}catch{return!1}}var Ta={pkg:6806978,"pkg-threads":6858009};const ys="inkvec-denoiser-v1",Pa="inkvec-ort-",La=3e4,za=700,ws="Not available in the browser. Inkvec Studio, the desktop app, has it.",vs=[["flat-logo.png","Flat logo"],["icon-64.png","Icon, 64 px"],["crest-filigree.png","Crest, filigree"],["signature-bw.png","Signature, B&W"]];class Da{constructor(){R(this,"worker",null);R(this,"ready",null);R(this,"queue",[]);R(this,"running",null);R(this,"nextId",1);R(this,"listeners",new Map);R(this,"generation",0);R(this,"previewGeneration",0);R(this,"shared",null);R(this,"source",null);R(this,"prefs",null);R(this,"prefsTimer",0);R(this,"denoiser",null);R(this,"denoiserPort",null);R(this,"downloading",!1);R(this,"fetchState",{phase:"idle",got:0,total:null});R(this,"wanted",!1);R(this,"cancelled",!1);R(this,"retried",!1);R(this,"info",null);R(this,"restartMs",null);R(this,"stopped",[]);R(this,"stopTimer",0);R(this,"denoiserRuns",0);R(this,"last",null)}openImage(){return this.source}base(){return new URL("./",document.baseURI).href}start(){const t=typeof crossOriginIsolated<"u"&&crossOriginIsolated;t&&!this.shared&&(this.shared=new Int32Array(new SharedArrayBuffer(4)));const s=new Worker(new URL(""+new URL("engine.worker-D2MRJiuD.js",import.meta.url).href,import.meta.url),{type:"module",name:"inkvec-engine"});this.worker=s;let o=null;if(t){const i=new MessageChannel;o=i.port1,this.denoiser?this.denoiser.postMessage({type:"port",port:i.port2},[i.port2]):this.denoiserPort=i.port2}this.ready=new Promise((i,r)=>{s.onmessage=l=>{const c=l.data;c.type==="loading"?(ka(c.got,c.total),c.done&&Sa()):c.type==="instantiated"?t&&(this.startDenoiser(c.denoiserUrl,c.denoiserSha256),this.prefetchDenoiser()):c.type==="ready"?(this.info={threads:c.threads,isolated:c.isolated,version:c.version,pool:c.pool,poolMs:null},t&&this.startDenoiser(c.denoiserUrl,c.denoiserSha256),i(c)):c.type==="pool"?(this.info&&(this.info={...this.info,threads:c.threads,pool:c.poolError?"failed":"running",poolMs:c.ms}),c.poolError&&console.warn("inkvec: thread pool did not start:",c.poolError)):c.type==="loadfail"?r(new Error(`The engine could not load: ${c.error}`)):c.type==="progress"?c.generation===this.generation&&this.emit("trace:progress",{generation:c.generation,...JSON.parse(c.json)}):c.type==="reply"&&this.finish(c)},s.onerror=l=>{r(new Error(`The engine stopped: ${l.message||"unknown error"}`)),this.crashed("The engine stopped unexpectedly.")}});const a=o?[o]:[];return s.postMessage({type:"init",base:this.base(),token:"4d6460155cef",generations:this.shared?this.shared.buffer:null,denoiserPort:o,wasmBytes:Ta},a),this.ready}whenReady(){return this.ready??this.start()}crashed(t){const s=this.running;this.running=null,window.clearTimeout(this.stopTimer),this.worker?.terminate(),this.worker=null,this.ready=null,s&&s.reject(new Error(t)),s?.op==="open_bytes"&&(this.source=null);const o=this.source,a=performance.now();this.whenReady().then(async()=>{o&&await this.enqueue("open_bytes",-1,{bytes:o.bytes.slice(),name:o.name}).catch(()=>{}),this.restartMs=performance.now()-a,this.pump()})}supersede(t,s){window.clearTimeout(this.stopTimer);const o=this.running;if(o?.op!=="trace"||o.payload.generation===this.generation||!t&&s&&Fa(o.payload.request,s))return;const a=performance.now(),i=()=>{this.running!==o||o.payload.generation===this.generation||(this.stopped.push({generation:o.payload.generation,asked:a,killed:performance.now()}),this.crashed("superseded by a newer request"))},r=a-(o.started??a),l=t?0:Math.max(0,(this.restartMs??za)-r);l===0?i():this.stopTimer=window.setTimeout(i,l)}finish(t){const s=this.running;if(!(!s||s.id!==t.id)){if(this.last={op:s.op,ms:t.ms??0,mem:t.mem??null},this.running=null,window.clearTimeout(this.stopTimer),t.ok)s.resolve(t.value);else if(t.crashed){this.crashed(t.error??"The engine stopped."),s.reject(new Error(t.error??"The engine stopped."));return}else s.reject(new Error(t.error??"failed"));this.pump()}}enqueue(t,s,o,a){return new Promise((i,r)=>{if(a){for(const l of this.queue.filter(c=>c.kind===a))l.reject(new Error("superseded by a newer request"));this.queue=this.queue.filter(l=>l.kind!==a)}this.queue.push({id:this.nextId++,op:t,priority:s,kind:a,payload:o,resolve:i,reject:r}),this.queue.sort((l,c)=>l.priority-c.priority||l.id-c.id),this.whenReady().then(()=>this.pump(),l=>{for(const c of this.queue)c.reject(l);this.queue=[]})})}pump(){if(this.running||!this.worker||!this.info)return;const t=this.queue.shift();if(!t)return;if(t.op==="trace"&&t.payload.generation!==this.generation)return t.resolve(null),this.pump();if(t.op==="preview"&&t.payload.generation!==this.previewGeneration)return t.resolve(null),this.pump();this.running=t,t.started=performance.now();const s=[];t.op==="open_bytes"&&s.push(t.payload.bytes.buffer),this.worker.postMessage({type:"job",id:t.id,op:t.op,...t.payload},s)}emit(t,s){for(const o of this.listeners.get(t)??[])o(s)}async listen(t,s){const o=i=>s({payload:i});let a=this.listeners.get(t);return a||this.listeners.set(t,a=new Set),a.add(o),()=>void a?.delete(o)}async invoke(t,s={}){return await this.dispatch(t,s)}async dispatch(t,s){switch(t){case"capabilities":{const o=await this.denoiserStatus();return this.enqueue("capabilities",0,{supported:o.supported,installed:o.installed,bytes:o.bytes})}case"startup_progress":return $a(String(s.text??""),Number(s.progress??0)),null;case"app_ready":return Ma(),null;case"open_path":throw new Error("A browser opens files you choose or drop, not paths.");case"open_bytes":{const o=s.bytes,a=o instanceof Uint8Array?o:new Uint8Array(o);return this.open(a,s.name??null)}case"open_sample":{const o=String(s.name);if(!vs.some(([i])=>i===o))throw new Error(`${o} is not one of the bundled samples`);const a=await fetch(new URL(`samples/${o}`,this.base()));if(!a.ok)throw new Error(`cannot fetch the sample ${o}: HTTP ${a.status}`);return this.open(new Uint8Array(await a.arrayBuffer()),o)}case"list_samples":return vs.map(([o,a])=>({file:o,label:a,preview:new URL(`samples/${o}`,this.base()).href}));case"launch_path":return null;case"start_trace":{const o=s.request,a=this.bump();o.tier!=="draft"&&this.rememberTrace(o.settings);const i=this.withoutUnreadyDenoiser(o);this.supersede(!1,i);const r=await this.loadPrefs();return this.enqueue("trace",1,{request:i,draftPx:r.draftPx??512,draftSeconds:r.draftSeconds??.4,generation:a},"trace").then(l=>{l&&a===this.generation&&this.emit("trace:done",{generation:a,outcome:l})},l=>{a===this.generation&&!/superseded/.test(l.message)&&this.emit("trace:done",{generation:a,outcome:{state:"failed",message:l.message}})}),a}case"cancel_trace":return this.bump(),this.queue=this.queue.filter(o=>o.kind==="trace"?(o.resolve(null),!1):!0),this.supersede(!0),null;case"start_preview":{const o=this.withoutUnreadyDenoiser(s.request),a=++this.previewGeneration,i=await this.loadPrefs();return this.enqueue("preview",2,{request:o,draftPx:i.draftPx??512,draftSeconds:i.draftSeconds??.4,generation:a},"preview").then(r=>{r&&a===this.previewGeneration&&this.emit("preview:done",{generation:a,outcome:r})},r=>{a===this.previewGeneration&&!/superseded/.test(r.message)&&this.emit("preview:done",{generation:a,outcome:{state:"failed",message:r.message}})}),a}case"cancel_previews":{this.previewGeneration++,this.queue=this.queue.filter(a=>a.kind==="preview"?(a.resolve(null),!1):!0);const o=this.running;return o?.op==="preview"&&o.started!==void 0&&performance.now()-o.started>500&&this.crashed("superseded by a newer request"),null}case"source_facts":case"trace_bands":case"snap_inks":case"match_palette":case"plan_export":case"minify_svg":case"fab_analyze":return this.enqueue(t,0,{args:s});case"fab_prepare":return this.enqueue(t,0,{args:s},"fab");case"write_export":{const o=s.request,a=await this.enqueue("export",0,{request:o,zip:!0}),i=(this.source?.name??"image").replace(/\.[^.]+$/,"")||"image";if(a.length===1&&a[0].name)return Ze(a[0].name,a[0].data),[a[0].name];const r=`${i}-inkvec.zip`;return a[0]&&Ze(r,a[0].data,"application/zip"),[r]}case"read_text_file":throw new Error("A browser reads files you choose or drop, not paths.");case"save_bytes":{const o=String(s.path);return Ze(o.split(/[\\/]/).pop()||"download",new Uint8Array(s.bytes)),null}case"batch_scan":case"batch_start":case"batch_stats_csv":throw new Error(ws);case"batch_pause":case"batch_cancel":return null;case"denoiser_status":return this.denoiserStatus();case"denoiser_download":return this.downloadDenoiser();case"denoiser_cancel":return this.fetchState.phase==="downloading"&&(this.cancelled=!0,this.wanted=!1,this.denoiser?.postMessage({type:"abort"})),this.downloading&&(this.downloading=!1,this.emit("denoiser:done",{ok:!1,message:"cancelled",status:await this.denoiserStatus()})),null;case"denoiser_remove":try{await caches.delete(ys);for(const o of await caches.keys())o.startsWith(Pa)&&await caches.delete(o)}catch{}return this.denoiser?.postMessage({type:"forget"}),this.fetchState.phase!=="ready"&&this.setFetch({phase:"idle",got:0,total:null}),this.denoiserStatus();case"load_prefs":return this.loadPrefs();case"save_prefs":{this.prefs={...this.prefs??{},...s.prefs},this.storePrefs();const o=await this.enqueue("sanitise_prefs",0,{args:{prefs:s.prefs}});return this.prefs=o,this.storePrefs(),o}case"reset_prefs":{const o=await this.loadPrefs();return this.prefs=await this.enqueue("reset_prefs",0,{args:{prefs:o}}),this.storePrefs(),this.prefs}case"third_party_notices":{const a=(await Promise.all(["STUDIO_THIRD_PARTY.md","THIRD_PARTY.md"].map(i=>fetch(new URL(i,this.base())).then(r=>r.ok?r.text():null,()=>null)))).filter(i=>!!i);if(!a.length)throw new Error("the notices could not be fetched");return a.join(`
|
| 4 |
|
| 5 |
|
| 6 |
+
`)}case"check_update":return{latest:null,newer:!1,url:"https://github.com/logolabs/inkvec/releases",offline:"a web page is always the version it is served as"};case"cli_status":case"context_menu_status":case"install_cli":case"remove_cli":case"install_context_menu":case"remove_context_menu":return{available:!1,installed:!1,path:null,note:ws}}throw new Error(`${t} is not something the browser build does`)}bump(){return this.generation++,this.shared&&Atomics.store(this.shared,0,this.generation),this.generation}async open(t,s){return this.source={bytes:t.slice(),name:s},this.bump(),this.queue=this.queue.filter(o=>o.kind?(o.resolve(null),!1):!0),this.supersede(!0),this.enqueue("open_bytes",0,{bytes:t,name:s})}async loadPrefs(){if(this.prefs)return this.prefs;const t=Aa();return this.prefs=await(t?this.enqueue("sanitise_prefs",0,{args:{prefs:t}}):this.enqueue("default_prefs",0,{args:{}})),this.prefs}rememberTrace(t){if(!this.prefs)return;const s={...t};delete s.colourGroups,this.prefs={...this.prefs,trace:s},window.clearTimeout(this.prefsTimer),this.prefsTimer=window.setTimeout(()=>this.storePrefs(),1e3)}storePrefs(){Ca(this.prefs)}startDenoiser(t,s){if(this.denoiser||!this.denoiserPort)return;const o=new Worker(new URL(""+new URL("denoiser.worker-DjPuHhk4.js",import.meta.url).href,import.meta.url),{type:"module",name:"inkvec-denoiser"});this.denoiser=o,o.onmessage=a=>void this.denoiserMessage(a.data),o.postMessage({type:"init",base:this.base(),token:"4d6460155cef",url:t,sha256:s,port:this.denoiserPort},[this.denoiserPort])}setFetch(t){this.fetchState={...this.fetchState,retrace:void 0,...t},this.emit("denoiser:fetch",this.fetchState)}get denoiserFetch(){return this.fetchState}async denoiserMessage(t){const s=this.fetchState.phase;switch(t.type){case"progress":if(s==="preparing"||s==="ready")return;this.setFetch({phase:"downloading",got:t.got??0,total:t.total??null,message:void 0,saveData:void 0}),this.downloading&&this.emit("denoiser:progress",{got:t.got,total:t.total});return;case"stored":{if(s==="preparing"||s==="ready")return;const o=this.fetchState.total??this.fetchState.got;this.setFetch({phase:"stored",got:o,total:o,message:void 0}),this.downloading&&(this.downloading=!1,this.emit("denoiser:done",{ok:!0,status:await this.denoiserStatus()}));return}case"preparing":this.setFetch({phase:"preparing",message:void 0});return;case"ran":this.denoiserRuns++;return;case"loaded":{const o=this.wanted;this.wanted=!1,this.setFetch({phase:"ready",message:void 0,retrace:o});return}case"failed":{const o=t.message??"the download did not finish";if(this.cancelled||/abort/i.test(o)){this.cancelled=!1,this.setFetch({phase:"idle",message:void 0});return}this.setFetch({phase:"failed",message:o}),this.downloading&&(this.downloading=!1,this.emit("denoiser:done",{ok:!1,message:o,status:await this.denoiserStatus()})),t.during==="download"&&!this.retried&&(this.retried=!0,window.setTimeout(()=>{this.fetchState.phase==="failed"&&this.denoiser?.postMessage({type:this.wanted?"prepare":"prefetch"})},La));return}}}prefetchDenoiser(){if(navigator.connection?.saveData){this.setFetch({phase:"idle",saveData:!0});return}this.denoiser?.postMessage({type:"prefetch"})}withoutUnreadyDenoiser(t){const s=t.settings?.cleanUpDamage;return!s||s==="off"||!this.denoiser||this.fetchState.phase==="ready"?t:(this.wanted=!0,this.cancelled=!1,this.denoiser.postMessage({type:"prepare"}),{...t,settings:{...t.settings,cleanUpDamage:"off"}})}async denoiserStatus(){const t=await this.whenReady();let s=!1,o=null;try{const a=await(await caches.open(ys)).match(t.denoiserUrl);a&&(s=!0,o=Number(a.headers.get("content-length"))||(await a.blob()).size)}catch{}return{supported:t.isolated,installed:s,path:null,bytes:o,repo:t.denoiserRepo,sha256:t.denoiserSha256}}async downloadDenoiser(){if(await this.whenReady(),!this.denoiser)throw new Error("The denoiser needs a cross-origin isolated page.");return this.downloading=!0,this.cancelled=!1,this.denoiser.postMessage({type:this.wanted?"prepare":"download"}),null}}function Fa(e,t){const s=o=>{const a={...o?.settings??{}};return delete a.minify,delete a.margin,JSON.stringify(Object.keys(a).sort().map(i=>[i,a[i]]))};return s(e)===s(t)}let Mt=null;function On(){return Mt||(Mt=new Da,globalThis.__inkvecStudioLite=Mt),Mt}function B(e,t){return On().invoke(e,t)}function Me(e,t){return On().listen(e,t)}const _={capabilities:()=>B("capabilities"),startupProgress:(e,t)=>B("startup_progress",{text:e,progress:t}),appReady:()=>B("app_ready"),openPath:e=>B("open_path",{path:e}),openBytes:(e,t)=>B("open_bytes",{bytes:e,name:t??null}),openSample:e=>B("open_sample",{name:e}),listSamples:()=>B("list_samples"),startTrace:(e,t)=>B("start_trace",{request:{settings:e,tier:t}}),cancelTrace:()=>B("cancel_trace"),startPreview:e=>B("start_preview",{request:{settings:e,tier:"draft"}}),cancelPreviews:()=>B("cancel_previews"),sourceFacts:e=>B("source_facts",{maxDim:e}),launchPath:()=>B("launch_path"),traceBands:e=>B("trace_bands",{generation:e}),snapInks:(e,t,s,o)=>B("snap_inks",{svg:e,snaps:t,width:s,height:o}),matchPalette:(e,t)=>B("match_palette",{traced:e,pasted:t}),planExport:e=>B("plan_export",{request:e}),writeExport:(e,t)=>B("write_export",{request:e,destination:t}),minify:(e,t)=>B("minify_svg",{svg:e,settings:t}),fabAnalyze:e=>B("fab_analyze",{svg:e}),fabPrepare:(e,t)=>B("fab_prepare",{svg:e,options:t}),readTextFile:e=>B("read_text_file",{path:e}),saveBytes:(e,t)=>B("save_bytes",{path:e,bytes:t}),batchScan:e=>B("batch_scan",{folder:e}),batchStart:e=>B("batch_start",{plan:e}),batchPause:e=>B("batch_pause",{paused:e}),batchCancel:()=>B("batch_cancel"),batchStatsCsv:()=>B("batch_stats_csv"),denoiserStatus:()=>B("denoiser_status"),denoiserDownload:()=>B("denoiser_download"),denoiserCancel:()=>B("denoiser_cancel"),denoiserRemove:()=>B("denoiser_remove"),loadPrefs:()=>B("load_prefs"),savePrefs:e=>B("save_prefs",{prefs:e}),resetPrefs:()=>B("reset_prefs"),thirdPartyNotices:()=>B("third_party_notices"),checkUpdate:()=>B("check_update"),cliStatus:()=>B("cli_status"),installCli:()=>B("install_cli"),removeCli:()=>B("remove_cli"),contextMenuStatus:()=>B("context_menu_status"),installContextMenu:()=>B("install_context_menu"),removeContextMenu:()=>B("remove_context_menu")},Ae={traceProgress:e=>Me("trace:progress",t=>e(t.payload)),traceDone:e=>Me("trace:done",t=>e(t.payload)),previewDone:e=>Me("preview:done",t=>e(t.payload)),openPath:e=>Me("open:path",t=>e(t.payload)),batchRow:e=>Me("batch:row",t=>e(t.payload)),batchTotals:e=>Me("batch:totals",t=>e(t.payload)),batchFinished:e=>Me("batch:finished",t=>e(t.payload)),denoiserProgress:e=>Me("denoiser:progress",t=>e(t.payload)),denoiserDone:e=>Me("denoiser:done",t=>e(t.payload)),denoiserFetch:e=>Me("denoiser:fetch",t=>e(t.payload))};function Na(e,t){return{caps:null,prefs:null,tab:"vectorize",screen:null,source:null,settings:e,preset:"logo",generation:0,tracing:!1,tracingTier:"final",tracingEngine:e.mode,liveStages:[],traceStarted:0,traceEnded:0,liveNow:null,traceLog:[],logOpen:!0,result:null,resultGeneration:0,resultEngine:e.mode,bandsMissing:!1,previous:null,svg:null,palette:[],snaps:[],colourGroups:[],groupSuggestions:null,resultGroups:[],dismissedGroups:[],simplifyTo:null,paletteSelection:[],hoverFill:null,losses:[],report:null,worstCorner:null,stageState:{kind:"empty"},justSwapped:!1,view:"side",show:{fill:!0,wireframe:!1,anchors:!1,handles:!1,certainty:!1},zoom:1,pan:{x:0,y:0},fitted:!0,flicked:!1,wipe:.5,detail:!1,railTab:"result",groupsOpen:{Detail:!0,Colour:!0,Shape:!0,Output:!1},exportOpen:!1,dragging:!1,minify:{name:null,before:null,settings:t,result:null,error:null},fab:{name:null,svg:null,analysis:null,options:lo(),plan:null,error:null,shown:-1,unit:"mm",showProblems:!0,preset:null,dxf:!1,gcode:!1},batch:{folder:null,outputDir:null,preset:"logo",skipExisting:!0,rows:[],totals:null,running:!1,paused:!1,failuresFirst:!1},update:null,denoiserFetch:null,auto:null,facts:null,chooser:!1,wizard:null,compare:null,autoNoteHidden:!1}}function lo(){return{mode:"singleColour",widthMm:100,include:[],order:[],bleedMm:.8,minFeatureMm:.8,removeThin:!1,stickerMarginMm:3,bridgeMm:1.5,stencilMarginMm:10,maxLineMm:0,penMm:.4,registration:!0,weedBorderMm:0,mirror:!1,cutStyle:"filled",sizeCheckMm:0,dogboneMm:0,gcodeFeedMmMin:1e3,gcodePower:1e3,gcodePasses:1,fileUnits:"mm",kerfMm:0,toleranceMm:.05,mergeDeltaE:3}}class Ia{constructor(t){R(this,"listeners",new Set);this.state=t}set(t){const s=new Set;for(const[o,a]of Object.entries(t))this.state[o]!==a&&(this.state[o]=a,s.add(o));s.size&&this.emit(s)}touch(...t){this.emit(new Set(t))}on(t,s){const o=new Set(t),a=i=>{for(const r of i)if(o.has(r)){s();return}};return this.listeners.add(a),()=>this.listeners.delete(a)}emit(t){for(const s of[...this.listeners])s(t)}}function oe(e){return e.toLocaleString("en-US")}function le(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ue(e){return e==null?"—":e.toFixed(2)}function gt(e){return e<1?`${Math.round(e*1e3)} ms`:`${e.toFixed(2)} s`}function mt(e,t){if(!e.source)return null;const s=Math.max(e.source.width,e.source.height),o=t==="draft"?Math.min(e.prefs?.draftPx??512,e.settings.traceSize):e.settings.traceSize;return Math.min(o,s)}function _n(e){return e==="fast"||e==="balanced"}function Mn(e){return e==="fast"?"Fast":e==="balanced"?"Balanced":"Quality"}function vt(e,t){const s=_n(t.mode)&&!t.blackAndWhite&&!t.lineArt;return e.modes==="qualityOnly"?!s:e.modes==="fastOnly"?s:!0}function Te(e,t=0){return`${(e*100).toFixed(t)}%`}function Oa(e){const t=Math.max(0,Math.round(e));return t<60?`${t} s`:`${Math.floor(t/60)} min ${t%60} s`}function co(e){return e==="macos"?"⌘":"Ctrl"}function _a(){return{preset:"logo",tab:"vectorize",railTab:"result",groupsOpen:{},view:"side",wipe:.5,show:{fill:!0,wireframe:!1,anchors:!1,handles:!1,certainty:!1},detail:!1,export:null,minify:null,minifyBackdrop:"auto",minifyView:"side",fab:null,fabUnit:"mm",fabShowProblems:!0,fabPreset:null,fabDxf:!1,fabGcode:!1,batchPreset:null,batchSkipExisting:!0,batchFailuresFirst:!1}}const ze={export:null,minifyBackdrop:"auto",minifyView:"side"};let En=()=>{};function Ba(){return{...ze}}function An(e){Object.assign(ze,e),En()}function Ra(e){const t=ze.export;return t?{...e,...t,pngSizes:[...t.pngSizes??e.pngSizes]}:e}function Cn(e){const t={...e.fab.options};return delete t.include,delete t.order,{preset:e.preset,tab:e.tab,railTab:e.railTab,groupsOpen:{...e.groupsOpen},view:e.view,wipe:e.wipe,show:{...e.show},detail:e.detail,export:ze.export,minify:{...e.minify.settings},minifyBackdrop:ze.minifyBackdrop,minifyView:ze.minifyView,fab:t,fabUnit:e.fab.unit,fabShowProblems:e.fab.showProblems,fabPreset:e.fab.preset,fabDxf:e.fab.dxf,fabGcode:e.fab.gcode,batchPreset:e.batch.preset,batchSkipExisting:e.batch.skipExisting,batchFailuresFirst:e.batch.failuresFirst}}function Tn(e){const t={...e};return delete t.colourGroups,t}function Ga(e,t,s,o){const a=e.state,i={..._a(),...t.ui??{}};ze.export=i.export,ze.minifyBackdrop=i.minifyBackdrop,ze.minifyView=i.minifyView,e.set({preset:i.preset&&o(i.preset)?i.preset:null,tab:s.includes(i.tab)?i.tab:"vectorize",railTab:i.railTab,groupsOpen:{...a.groupsOpen,...i.groupsOpen},view:i.view,wipe:i.wipe,show:{...a.show,...i.show},detail:i.detail,minify:{...a.minify,settings:{...a.minify.settings,...i.minify??{}}},fab:{...a.fab,options:{...lo(),...i.fab??{},include:[],order:[]},unit:i.fabUnit,showProblems:i.fabShowProblems,preset:i.fabPreset,dxf:i.fabDxf,gcode:i.fabGcode},batch:{...a.batch,preset:i.batchPreset&&o(i.batchPreset)?i.batchPreset:a.batch.preset,skipExisting:i.batchSkipExisting,failuresFirst:i.batchFailuresFirst}})}const Wa=["settings","preset","tab","railTab","groupsOpen","view","wipe","show","detail","minify","fab","batch"];function qa(e,t,s=500){let o=0,a=JSON.stringify({ui:Cn(e.state),trace:Tn(e.state.settings)});const i=()=>{if(window.clearTimeout(o),o=0,!e.state.prefs)return;const c={ui:Cn(e.state),trace:Tn(e.state.settings)},u=JSON.stringify(c);u!==a&&(a=u,t(c))};En=()=>{window.clearTimeout(o),o=window.setTimeout(i,s)};const r=e.on(Wa,En),l=()=>{document.visibilityState==="hidden"&&o&&i()};return window.addEventListener("pagehide",i),document.addEventListener("visibilitychange",l),()=>{r(),window.removeEventListener("pagehide",i),document.removeEventListener("visibilitychange",l)}}const Ha="modulepreload",Ua=function(e,t){return new URL(e,t).href},xs={},ja=function(t,s,o){let a=Promise.resolve();if(s&&s.length>0){let r=function(d){return Promise.all(d.map(h=>Promise.resolve(h).then(f=>({status:"fulfilled",value:f}),f=>({status:"rejected",reason:f}))))};const l=document.getElementsByTagName("link"),c=document.querySelector("meta[property=csp-nonce]"),u=c?.nonce||c?.getAttribute("nonce");a=r(s.map(d=>{if(d=Ua(d,o),d in xs)return;xs[d]=!0;const h=d.endsWith(".css"),f=h?'[rel="stylesheet"]':"";if(!!o)for(let m=l.length-1;m>=0;m--){const k=l[m];if(k.href===d&&(!h||k.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${d}"]${f}`))return;const g=document.createElement("link");if(g.rel=h?"stylesheet":Ha,h||(g.as="script"),g.crossOrigin="",g.href=d,u&&g.setAttribute("nonce",u),document.head.appendChild(g),h)return new Promise((m,k)=>{g.addEventListener("load",m),g.addEventListener("error",()=>k(new Error(`Unable to preload CSS for ${d}`)))})}))}function i(r){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=r,window.dispatchEvent(l),!l.defaultPrevented)throw r}return a.then(r=>{for(const l of r||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})};async function Va(e={}){return typeof e=="object"&&Object.freeze(e),await Kt("plugin:dialog|open",{options:e})}async function Ka(e={}){return typeof e=="object"&&Object.freeze(e),await Kt("plugin:dialog|save",{options:e})}async function Ya(e,t){await Kt("plugin:opener|open_url",{url:e,with:t})}async function Za(e){return Kt("plugin:opener|reveal_item_in_dir",{paths:typeof e=="string"?[e]:e})}const Yt="Inkvec Studio Lite",uo="https://github.com/logolabs/inkvec/releases",Ja="Inkvec Studio for Windows, macOS and Linux: the native engine is faster, it traces whole folders in one batch, has no browser memory limit (traces up to 16384 px), and works offline.";function po(e){return{name:e.name||"pasted image",path:null,file:e}}async function Bn(e,t=!1){return new Promise(s=>{const o=document.createElement("input");o.type="file",o.multiple=t,o.accept=e.flatMap(r=>r.extensions.map(l=>`.${l}`)).join(","),o.style.display="none";let a=!1;const i=r=>{a||(a=!0,o.remove(),s(r))};o.addEventListener("change",()=>i([...o.files??[]].map(po))),o.addEventListener("cancel",()=>i([])),document.body.append(o),o.click()})}async function Rt(e){if(e.file)return e.file.text();if(e.path)return _.readTextFile(e.path);throw new Error("nothing to read")}const ks=!1;async function ho(e,t,s){const o=typeof t=="string"?new TextEncoder().encode(t):t;return Ze(e,o),{path:null,name:e}}async function Xa(e,t,s){const o=new TextEncoder,a=i=>typeof i=="string"?o.encode(i):i;{if(e.length===1)Ze(e[0].name,a(e[0].data));else{const{zipStore:i}=await ja(async()=>{const{zipStore:r}=await import("./zip-DlX9-WSC.js");return{zipStore:r}},[],import.meta.url);Ze(t,i(e.map(r=>({name:r.name,data:a(r.data)}))))}return{folder:null,first:null}}}const Qa=!1;async function Zt(e){await navigator.clipboard.writeText(e)}async function Jt(e){{window.open(e,"_blank","noopener,noreferrer");return}}function Xt(e){return e&&Qa?{label:"Show in folder",run:()=>void 0}:void 0}const fo={mode:"quality",precision:.1,speckleFloor:2,traceSize:2048,timeLimit:0,maxColours:64,colourMerging:.035,flatFills:!1,blackAndWhite:!1,monochrome:!1,cleanUpDamage:"off",matchRepeatedShapes:!0,matchThreshold:.92,fewerPaths:!1,lineArt:!1,repairRings:!0,editability:!1,bezierCost:6,cornerAngle:10,minify:!1,transparentBackground:!1,margin:0,holesAsCutouts:!1,traceTransparency:!0};function ei(e,t,s){const o=e?.presets.find(i=>i.id===s);if(o)return{settings:o.settings,wantsDenoiser:o.wantsDenoiser};const a=t?.saved.find(i=>i.id===s);return a?{settings:a.settings,wantsDenoiser:!1}:null}function ti(e){return/^[0-9]$/.test(e)?(Number(e)+9)%10:null}const ni=8;class si{constructor(t){R(this,"watching",0);R(this,"newest",0);R(this,"early",new Map);R(this,"groupsSent",new Map);R(this,"settleTimer");R(this,"afterDraft",null);this.host=t}async trace(t){this.dropAfterDraft(),await this.begin(t,!1)}open(t){return this.dropAfterDraft(),t?new Promise(s=>{const o={draft:0,resolve:s};this.afterDraft=o,this.begin("draft",!0).then(a=>{a===null&&this.afterDraft===o&&this.dropAfterDraft()})}):this.begin("final",!1).then(()=>{})}async begin(t,s){if(!this.host.hasSource())return null;const o=performance.now();try{const a=this.host.groups(),i=await this.host.start(t,s);if(i<this.newest)return null;this.newest=i,s&&this.afterDraft?.draft===0&&(this.afterDraft.draft=i),this.groupsSent.set(i,a);for(const l of this.groupsSent.keys())l<i-ni&&this.groupsSent.delete(l);this.watching=i,this.host.began(i,t,o);const r=this.early.get(i);for(const l of this.early.keys())l<=i&&this.early.delete(l);for(const l of r?.progress??[])this.progressed(l);return r?.done&&this.landed(r.done,i),i}catch(a){return this.host.failed(a),null}}landed(t,s){this.host.finished(t,s);const o=this.afterDraft;o&&o.draft===s&&(this.afterDraft=null,this.begin("final",!1).then(()=>o.resolve()))}dropAfterDraft(){const t=this.afterDraft;this.afterDraft=null,t?.resolve()}onProgress(t){if(t.generation>this.newest){this.hold(t.generation).progress.push(t);return}this.progressed(t)}onDone(t,s){if(t>this.newest){this.hold(t).done=s;return}const o=this.host.shown();t!==o.generation||!o.tracing||this.landed(s,t)}controlChanged(){this.clearSettle(),this.host.hasSource()&&(this.trace("draft"),this.settleTimer=setTimeout(()=>void this.trace("final"),this.host.settleMs()))}get waitingForDraft(){return this.afterDraft!==null}cancel(){this.clearSettle(),this.host.cancel()}clearSettle(){clearTimeout(this.settleTimer),this.settleTimer=void 0,this.dropAfterDraft()}detach(){this.clearSettle(),this.watching=0}groupsFor(t){return this.groupsSent.get(t)}progressed(t){t.generation===this.watching&&this.host.progressed(t)}hold(t){const s=this.early.get(t)??{progress:[]};return this.early.set(t,s),s}}class oi{constructor(){R(this,"last",0)}take(){return++this.last}isNewest(t){return t===this.last}}function Re(e){const t={...e,cleanUpDamage:"off"};return JSON.stringify(Object.keys(t).sort().map(s=>[s,t[s]]))}class ai{constructor(){R(this,"results",new Map);R(this,"queue",[]);R(this,"running",null);R(this,"epoch",0);R(this,"early",new Map);R(this,"listeners",new Set);Ae.previewDone(({generation:t,outcome:s})=>this.done(t,s))}get(t){return this.results.get(t)}on(t){return this.listeners.add(t),()=>this.listeners.delete(t)}want(t){const s=new Set,o=t.filter(a=>{if(s.has(a.key))return!1;s.add(a.key);const i=this.results.get(a.key)?.state;return i!=="done"&&i!=="running"});if(o.map(a=>a.key).join(`
|
| 7 |
`)!==this.queue.map(a=>a.key).join(`
|
| 8 |
`)){for(const a of this.queue)this.results.get(a.key)?.state==="queued"&&this.results.delete(a.key);this.queue=o;for(const a of this.queue)this.results.set(a.key,{state:"queued"});this.emit(),this.next()}}pause(){this.want([])}reset(){this.epoch++;for(const t of this.results.values())t.state==="done"&&URL.revokeObjectURL(t.url);this.results.clear(),this.queue=[],this.early.clear(),this.running&&_.cancelPreviews().catch(()=>{}),this.running=null,this.emit()}pending(){return this.queue.length+(this.running?1:0)}next(){if(this.running)return;const t=this.queue.shift();if(!t)return;const s=this.epoch;this.running={key:t.key,generation:null,epoch:s},this.results.set(t.key,{state:"running"}),this.emit(),_.startPreview(t.settings).then(o=>{if(this.running?.epoch!==s||this.running.key!==t.key)return;this.running.generation=o;const a=this.early.get(o);a&&(this.early.delete(o),this.done(o,a))},o=>{this.running?.epoch===s&&this.finish(t.key,{state:"failed",message:String(o)})})}done(t,s){const o=this.running;if(o){if(o.generation===null){this.early.set(t,s);return}if(o.generation===t)if(s.state==="traced"){const a=URL.createObjectURL(new Blob([s.svg],{type:"image/svg+xml"}));this.finish(o.key,{state:"done",svg:s.svg,url:a,report:s.report})}else{const a="message"in s?s.message:s.state==="flat"?"one flat colour":s.state==="cancelled"?"stopped":"out of memory";this.finish(o.key,{state:"failed",message:a})}}}finish(t,s){this.results.set(t,s),this.running=null,this.emit(),this.next()}emit(){for(const t of[...this.listeners])t()}}const Ss=400;function ii(e,t,s){let o=e.liveStages,a=e.liveNow;const i=[...e.traceLog],r=c=>{for(let u=i.length-1;u>=0;u--){const d=i[u];if(d.kind==="stage")return d.what===c&&d.ms===void 0?u:-1}return-1};for(const c of t.entries)if(c.kind==="begin")a={stage:c.stage,what:c.what,since:s,step:null},i.push({at:c.at,kind:"stage",stage:c.stage,what:c.what});else if(c.kind==="end"){if(c.stage!=="measure"){const d=o.findIndex(h=>h.name===c.stage);o=d>=0?o.map((h,f)=>f===d?{...h,ms:h.ms+c.ms}:h):[...o,{name:c.stage,ms:c.ms}]}const u=r(c.what);u>=0?i[u]={...i[u],ms:c.ms,step:i[u].step??null}:i.push({at:Math.max(0,c.at-c.ms),kind:"stage",stage:c.stage,what:c.what,ms:c.ms}),a&&a.what===c.what&&(a=null)}else i.push({at:c.at,kind:"note",stage:c.stage,what:c.what,text:c.text});const l=t.step;if(l){!a||a.what!==l.what?a={stage:l.stage,what:l.what,since:s,step:l}:a={...a,step:l};const c=r(l.what);c>=0&&(i[c]={...i[c],step:l})}return{liveStages:o,liveNow:a,traceLog:i.length>Ss?i.slice(i.length-Ss):i}}function Rn(e){return e.total>0?`${e.done} / ${e.total} ${e.unit}`:`${e.unit} ${e.done}`}function Je(e){const t=Math.max(0,e)/1e3;return t<60?`${t.toFixed(1)} s`:`${Math.floor(t/60)} min ${String(Math.floor(t%60)).padStart(2,"0")} s`}function $s(e){return`${(Math.max(0,e)/1e3).toFixed(2)}`}function ri(e,t,s){let o=0;const a=()=>{const r=performance.now(),l=t(),c=s();for(const u of document.querySelectorAll('[data-live="elapsed"]'))u.textContent=Je(r-l);for(const u of document.querySelectorAll('[data-live="stage"]'))u.textContent=c===null?"":Je(r-c)},i=()=>{e()&&!o?(a(),o=window.setInterval(a,100)):!e()&&o&&(window.clearInterval(o),o=0)};return()=>{i(),o&&a()}}function Qt(e){const t=e.liveNow;if(t){const s=t.stage==="measure"?"measuring":t.stage;return t.step?`${s} · ${Rn(t.step)}`:`${s} · ${t.what}`}return e.liveStages[e.liveStages.length-1]?.name??"starting"}function en(e){return Je(performance.now()-e.traceStarted)}const li=["a[href]","button:not([disabled])","input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","iframe","[tabindex]:not([tabindex='-1'])","[contenteditable='true']"].join(","),go="#toasts, #overlays, .tooltip, script, style, link";function Gt(e){return[...e.querySelectorAll(li)].filter(t=>{if(t.closest("[hidden], [inert]"))return!1;const s=t.checkVisibility;return typeof s=="function"?s.call(t):t.getClientRects().length>0})}const Le=[];function ci(e){const t=[];for(let s=e;s&&s!==document.body;s=s.parentElement){const o=s.parentElement;if(!o)break;for(const a of o.children)a!==s&&a instanceof HTMLElement&&!a.matches(go)&&t.push(a)}return t}function Ms(e){const t=Le[Le.length-1];if(!t)return;if(e.key==="Escape"&&t.opts.onEscape){e.preventDefault(),e.stopPropagation(),t.opts.onEscape();return}if(e.key!=="Tab")return;const s=Gt(t.root),o=document.activeElement,a=!!(o&&t.root.contains(o));if(!s.length){e.preventDefault(),t.root.focus();return}const i=s[0],r=s[s.length-1];(!a||e.shiftKey&&o===i||!e.shiftKey&&o===r)&&(e.preventDefault(),(e.shiftKey?r:i).focus())}function Es(e){const t=Le[Le.length-1],s=e.target;!t?.opts.onOutside||!s||t.root.contains(s)||s.closest?.(go)||t.opts.onOutside()}function As(e){e.ctrlKey||e.metaKey||e.key==="Tab"||/^F\d{1,2}$/.test(e.key)||e.stopPropagation()}function tn(e,t={}){const s=document.activeElement,o=s instanceof HTMLElement&&s!==document.body?s:null;e.hasAttribute("tabindex")||e.setAttribute("tabindex","-1");const a=ci(e).filter(c=>!c.inert);for(const c of a)c.inert=!0;const i={root:e,opts:t,opener:o,inerted:a};Le.length||(document.addEventListener("keydown",Ms,!0),document.addEventListener("pointerdown",Es,!0)),Le.push(i),e.addEventListener("keydown",As),(t.initial?.()??Gt(e)[0]??e).focus({preventScroll:!0});let l=!1;return(c=!0)=>{if(l)return;l=!0;const u=Le.indexOf(i);u>=0&&Le.splice(u,1),Le.length||(document.removeEventListener("keydown",Ms,!0),document.removeEventListener("pointerdown",Es,!0)),e.removeEventListener("keydown",As);for(const h of a)h.inert=!1;if(!c)return;(o?.isConnected?o:t.fallback?.())?.focus({preventScroll:!0})}}const Wt=()=>document.getElementById("overlays"),ui=()=>document.getElementById("toasts");function G(e,t={}){const s=t.kind??"plain",o=s==="good"?"checkCircle":s==="bad"?"alert":"info",a=n("div.toast",{role:"status"},n(`span.glyph.${s}`,null,V(o,16)),n("span.text",null,e),t.action&&n("button",{class:"reset",onclick:()=>{t.action?.run(),a.remove()}},t.action.label));ui().append(a),window.setTimeout(()=>a.remove(),6e3)}let He=null,Pn=null;function he(){const e=Wt().contains(document.activeElement);D(Wt()),document.removeEventListener("keydown",Gn,!0);const t=He;He=null,t?.();const s=Pn;Pn=null,s?.isConnected&&(e||document.activeElement===document.body)&&s.focus({preventScroll:!0})}function Gn(e){e.key==="Escape"&&(e.stopPropagation(),he())}let di=0;function ot(e){He?.(!1),He=null;const t=n("div.scrim",{onmousedown:o=>{o.target===t&&he()}});e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true");const s=e.querySelector("h1, h2, h3");s&&!e.hasAttribute("aria-label")&&!e.hasAttribute("aria-labelledby")&&(s.id||=`modal-title-${++di}`,e.setAttribute("aria-labelledby",s.id)),t.append(e),D(Wt(),t),document.removeEventListener("keydown",Gn,!0),He=tn(e,{initial:()=>e.querySelector("button, input, select, textarea, [tabindex]:not([tabindex='-1'])"),onEscape:he})}function nn(e,t,s=[]){return n("div.modal",{tabindex:"-1"},n("h2",null,e),...t.filter(Boolean).map(o=>typeof o=="string"?n("p",null,o):o),s.length?n("div.actions",null,...s):null)}function Wn(e,t){He?.(!1),He=null,Pn=e;const s=n("div.popover",null,t),o=n("div",{style:{position:"fixed",inset:"0",zIndex:"44"},onmousedown:he});D(Wt(),o,s),document.addEventListener("keydown",Gn,!0);const a=e.getBoundingClientRect(),i=s.getBoundingClientRect(),r=8,l=Math.min(Math.max(r,a.left),window.innerWidth-i.width-r),c=a.bottom+6,u=c+i.height+r>window.innerHeight?a.top-i.height-6:c;s.style.left=`${Math.round(l)}px`,s.style.top=`${Math.round(Math.max(r,u))}px`,(s.querySelector("button, input, [tabindex]")??s).focus?.()}let Ue=null,qn=0;function bt(){window.cancelAnimationFrame(qn),Ue?.node.remove(),Ue=null}function mo(){const e=Ue;if(!e)return;if(!(e.el.isConnected&&(e.el.matches(":hover")||e.el.matches(":focus-visible")))){bt();return}qn=window.requestAnimationFrame(mo)}function We(e,t){let s=0;const o=()=>{if(!e.isConnected||Ue?.el===e)return;bt();const i=n("div.tooltip",{role:"tooltip"},t);document.body.append(i);const r=e.getBoundingClientRect(),l=i.getBoundingClientRect(),c=Math.min(Math.max(8,r.left),window.innerWidth-l.width-8),u=r.top-l.height-8;i.style.left=`${Math.round(c)}px`,i.style.top=`${Math.round(u<8?r.bottom+8:u)}px`,Ue={node:i,el:e},qn=window.requestAnimationFrame(mo)},a=()=>{window.clearTimeout(s),Ue?.el===e&&bt()};return e.addEventListener("pointerenter",()=>{window.clearTimeout(s),s=window.setTimeout(o,350)}),e.addEventListener("pointerleave",a),e.addEventListener("pointerdown",a),e.addEventListener("focus",()=>{e.matches(":focus-visible")&&o()}),e.addEventListener("blur",a),e}document.addEventListener("keydown",e=>{e.key==="Escape"&&Ue&&bt()},!0);window.addEventListener("blur",bt);function pi(e,t,s,o,a=!1){ot(nn(e,[t],[n("button.btn",{onclick:he},"Cancel"),n(`button.btn.primary${a?".danger":""}`,{onclick:()=>{he(),o()}},s)]))}function bo(e){const t=e.trim().replace(/^#/,""),s=t.length===3?[...t].map(o=>o+o).join(""):t;return/^[0-9a-fA-F]{6}$/.test(s)?[0,2,4].map(o=>parseInt(s.slice(o,o+2),16)/255):null}function yo([e,t,s]){const o=g=>g<=.04045?g/12.92:((g+.055)/1.055)**2.4,[a,i,r]=[o(e),o(t),o(s)],l=(.4124564*a+.3575761*i+.1804375*r)/.95047,c=.2126729*a+.7151522*i+.072175*r,u=(.0193339*a+.119192*i+.9503041*r)/1.08883,d=g=>g>216/24389?Math.cbrt(g):(24389/27*g+16)/116,[h,f,p]=[d(l),d(c),d(u)];return[116*f-16,500*(h-f),200*(f-p)]}function hi(e,t){const[s,o,a]=e,[i,r,l]=t,c=Math.PI/180,u=Math.hypot(o,a),d=Math.hypot(r,l),h=((u+d)/2)**7,f=.5*(1-Math.sqrt(h/(h+25**7))),p=(1+f)*o,g=(1+f)*r,m=Math.hypot(p,a),k=Math.hypot(g,l),E=(ce,Fe)=>{if(ce===0&&Fe===0)return 0;const ye=Math.atan2(Fe,ce)/c;return ye<0?ye+360:ye},x=E(p,a),$=E(g,l),y=i-s,v=k-m;let M=0;m*k!==0&&(M=$-x,M>180?M-=360:M<-180&&(M+=360));const A=2*Math.sqrt(m*k)*Math.sin(M*c/2),T=(s+i)/2,O=(m+k)/2;let Z=x+$;m*k!==0&&(Z=Math.abs(x-$)<=180?(x+$)/2:x+$<360?(x+$+360)/2:(x+$-360)/2);const te=1-.17*Math.cos((Z-30)*c)+.24*Math.cos(2*Z*c)+.32*Math.cos((3*Z+6)*c)-.2*Math.cos((4*Z-63)*c),P=30*Math.exp(-(((Z-275)/25)**2)),L=O**7,Q=2*Math.sqrt(L/(L+25**7)),U=1+.015*(T-50)**2/Math.sqrt(20+(T-50)**2),W=1+.045*O,ee=1+.015*O*te,K=-Math.sin(2*P*c)*Q,ae=y/U,ie=v/W,ne=A/ee;return Math.sqrt(ae*ae+ie*ie+ne*ne+K*ie*ne)}function qt(e){return e.kind==="gradient"&&e.stops.length>1?e.stops.map(t=>t.toLowerCase()).join(">"):e.traced.toLowerCase()}function Qe(e){return e.split(">").map(t=>t.trim().toLowerCase())}function xt(e){return e.includes(">")}function Hn(e,t=!1){const s=Qe(e);return s.length<2?s[0]??"transparent":t?`radial-gradient(circle, ${s.join(", ")})`:`linear-gradient(90deg, ${s.join(", ")})`}const Et=new Map;function Cs(e){const t=Et.get(e);if(t)return t;const s=bo(e);if(!s)return null;const o=yo(s);return Et.size>4096&&Et.clear(),Et.set(e,o),o}function Un(e,t){const s=Qe(e).map(Cs),o=Qe(t).map(Cs);if(s.some(l=>!l)||o.some(l=>!l)||!s.length||!o.length)return 1/0;const a=s,i=o,r=(l,c)=>l.reduce((u,d)=>u+Math.min(...c.map(h=>hi(d,h))),0)/l.length;return Math.max(r(a,i),r(i,a))}const fi=2;function sn(e,t){const s=xt(e),o=t.find(r=>qt(r)===e);if(o)return o;let a=null,i=fi;for(const r of t){if(r.kind==="gradient"!==s)continue;const l=Un(e,qt(r));l<=i&&(i=l,a=r)}return a}function Ce(e,t){return e===t||Un(e,t)<.5}const gi=2,mi=240;function bi(e,t={}){const s=t.skip??[],o=e.filter(d=>d.share>0),a=[...o].sort((d,h)=>h.share-d.share).slice(0,mi).map(d=>({member:qt(d),share:d.share})).filter(d=>!s.some(h=>Ce(h,d.member))),i=a.length;if(i<2)return[];const r=a.map((d,h)=>a.map((f,p)=>h===p?0:Un(d.member,f.member))),l=a.map((d,h)=>[h]);let c=i;const u=t.count?Math.max(1,Math.round(t.count)-(o.length-i)):null;for(;!(u!==null&&c<=u);){let d=1/0,h=-1,f=-1;for(let p=0;p<i;p++)if(l[p])for(let g=p+1;g<i;g++)l[g]&&r[p][g]<d&&(d=r[p][g],h=p,f=g);if(h<0||u===null&&d>gi)break;l[h]=[...l[h],...l[f]],l[f]=null,c--;for(let p=0;p<i;p++){if(p===h||!l[p])continue;const g=Math.max(r[h][p],r[f][p]);r[h][p]=g,r[p][h]=g}}return l.filter(Boolean).filter(d=>d.length>1).map(d=>d.map(h=>a[h]).sort((h,f)=>f.share-h.share)).sort((d,h)=>h.reduce((f,p)=>f+p.share,0)-d.reduce((f,p)=>f+p.share,0)).map(d=>({members:d.map(h=>h.member),target:null}))}function jn(e){return[...e.members].sort().join(",")}function yi(e){return e.filter(t=>t.trimStart().startsWith("merge colors")).map(t=>{const s=t.trim().replace(/^merge colors\s+/,""),o=/;\s*(?:not found in the trace:|no ink near)\s*(.*)$/.exec(s),a=(o?.[1]??"").split(",").map(i=>i.trim().toLowerCase()).filter(i=>/^#[0-9a-f]{6}(>#[0-9a-f]{6})*$/.test(i));return{line:o?s.slice(0,o.index).trim():s,unmatched:a,leftAlone:s.startsWith("group left alone")}})}function wi(e,t){return e?e.unmatched.some(s=>s===t||Qe(t).includes(s)||Ce(s,t)):!1}function wo(e){const t=(e.groupSuggestions??[]).filter(a=>a.edited),s=[...e.colourGroups.flatMap(a=>a.members),...t.flatMap(a=>a.members)],o=bi(e.palette,{count:e.simplifyTo,skip:s}).filter(a=>!e.dismissedGroups.includes(jn(a)));return[...t,...o]}function vi(e,t){const s=e.members.filter(a=>sn(a,t));if(s.length<2)return null;let o=e.target;if(o?.startsWith("@")){const a=e.members[Number(o.slice(1))-1],i=a?s.indexOf(a):-1;o=i>=0?`@${i+1}`:null}return{...e,members:s,target:o}}function Vn(e){return(e.groupSuggestions??[]).map((t,s)=>({g:vi(t,e.palette),index:s})).filter(t=>t.g!==null)}function vo(e,t){let s=e.target;if(s?.startsWith("@")){const o=Number(s.slice(1))-1;s=o===t?null:o>t?`@${o}`:s}return{...e,members:e.members.filter((o,a)=>a!==t),target:s}}function ke(e,t,s=-1,o=!1){return e.map((a,i)=>{if(i===s)return a;const r=a.members.findIndex(l=>Ce(l,t));return r<0?a:{...vo(a,r),...o?{edited:!0}:{}}})}const et=e=>e.filter(t=>t.members.length>1);function xi(e,t,s,o,a){const i=e.state;let r=i.colourGroups.map(f=>({...f,members:[...f.members]})),l=(i.groupSuggestions??[]).map(f=>({...f,members:[...f.members]}));const c=a?.closest("[data-drop]")??null,u=c?.dataset.drop??null,d=Number(c?.dataset.index??-1);if((u==="group"||u==="sugg")&&o.kind===u&&o.index===d||u==="ink"&&Ce(c?.dataset.member??"",s))return;if(u==="group")r=ke(r,s,d),l=ke(l,s,-1,!0),r[d].members.some(f=>Ce(f,s))||r[d].members.push(s);else if(u==="sugg")r=ke(r,s),l=ke(l,s,d,!0),l[d].members.some(f=>Ce(f,s))||(l[d]={...l[d],members:[...l[d].members,s],edited:!0});else if(u==="ink"){const f=c?.dataset.member??"";r=ke(r,s),l=ke(l,s,-1,!0);const p=r.findIndex(g=>g.members.some(m=>Ce(m,f)));p>=0?r[p].members.push(s):(l=ke(l,f,-1,!0),r.push({members:[f,s],target:null}))}else{if(o.kind==="palette")return;o.kind==="group"?r=ke(r,s):l=ke(l,s,-1,!0)}const h=et(r);e.set({groupSuggestions:et(l),paletteSelection:[]}),JSON.stringify(h)!==JSON.stringify(i.colourGroups)&&t.setColourGroups(h)}function ki(e,t){const s=e.state,o=s.paletteSelection;if(o.length<2)return;let a=s.colourGroups.map(l=>({...l,members:[...l.members]}));const i=a.findIndex(l=>l.members.some(c=>o.some(u=>Ce(u,c))));let r=s.groupSuggestions??[];for(const l of o)a=ke(a,l,i),r=ke(r,l,-1,!0);if(i>=0)for(const l of o)a[i].members.some(c=>Ce(c,l))||a[i].members.push(l);else a.push({members:[...o],target:null});e.set({groupSuggestions:et(r),paletteSelection:[]}),t.setColourGroups(et(a))}const Si=4;function xo(e,t,s,o,a,i){e.addEventListener("pointerdown",r=>{if(r.button!==0)return;const l=r.clientX,c=r.clientY;let u=null,d=null;const h=g=>{g!==d&&(d?.classList.remove("dropping"),d=g,d?.classList.add("dropping"))},f=g=>{if(!u){if(Math.hypot(g.clientX-l,g.clientY-c)<Si)return;u=n("div.dragghost",null,n("span.swatch",null,n("i",{style:{background:Hn(o,i)}}))),document.body.append(u),document.body.classList.add("dragging-ink")}u.style.left=`${g.clientX+8}px`,u.style.top=`${g.clientY+8}px`;const m=document.elementFromPoint(g.clientX,g.clientY);h(m?.closest("[data-drop]")??null)},p=g=>{if(window.removeEventListener("pointermove",f),window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",p),!u)return;u.remove(),document.body.classList.remove("dragging-ink"),h(null);const m=k=>k.stopPropagation();window.addEventListener("click",m,!0),window.setTimeout(()=>window.removeEventListener("click",m,!0),0),g.type!=="pointercancel"&&xi(t,s,o,a,document.elementFromPoint(g.clientX,g.clientY))};window.addEventListener("pointermove",f),window.addEventListener("pointerup",p),window.addEventListener("pointercancel",p)})}function At(e,t){return sn(e,t)?.keys??[]}function ko(e,t){let s=0;const o=()=>{let i=[...e.querySelectorAll("[data-fill]:hover")].pop()??null;if(!i){const l=document.activeElement;l instanceof HTMLElement&&e.contains(l)&&l.matches(":focus-visible")&&(i=l.closest("[data-fill]"))}const r=i?JSON.parse(i.dataset.fill??"[]"):[];return r.length?r:null},a=()=>{const i=o(),r=t.state.hoverFill;(i??[]).join(`
|
| 9 |
`)!==(r??[]).join(`
|
studio/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
| 11 |
<meta name="description" content="Turn a raster logo into an exact SVG, in your browser. Nothing is uploaded." />
|
| 12 |
<link rel="icon" href="./favicon.svg" type="image/svg+xml" />
|
| 13 |
<title>Inkvec Studio Lite</title>
|
| 14 |
-
<script type="module" crossorigin src="./assets/main-
|
| 15 |
<link rel="stylesheet" crossorigin href="./assets/main-CdmTdoOg.css">
|
| 16 |
<link rel="preload" href="./fonts/playfair-latin.woff2" as="font" type="font/woff2" crossorigin />
|
| 17 |
<link rel="preload" href="./fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin />
|
|
@@ -356,7 +356,7 @@ html.boot-go .boot-progress {
|
|
| 356 |
</div>
|
| 357 |
<footer class="boot-foot">
|
| 358 |
<span>Runs in your browser. Your image never leaves this computer.</span>
|
| 359 |
-
<span>Version 0.3.
|
| 360 |
</footer>
|
| 361 |
</div>
|
| 362 |
<div id="app"></div>
|
|
|
|
| 11 |
<meta name="description" content="Turn a raster logo into an exact SVG, in your browser. Nothing is uploaded." />
|
| 12 |
<link rel="icon" href="./favicon.svg" type="image/svg+xml" />
|
| 13 |
<title>Inkvec Studio Lite</title>
|
| 14 |
+
<script type="module" crossorigin src="./assets/main-DBfkyHf-.js"></script>
|
| 15 |
<link rel="stylesheet" crossorigin href="./assets/main-CdmTdoOg.css">
|
| 16 |
<link rel="preload" href="./fonts/playfair-latin.woff2" as="font" type="font/woff2" crossorigin />
|
| 17 |
<link rel="preload" href="./fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin />
|
|
|
|
| 356 |
</div>
|
| 357 |
<footer class="boot-foot">
|
| 358 |
<span>Runs in your browser. Your image never leaves this computer.</span>
|
| 359 |
+
<span>Version 0.3.1 · Apache-2.0 · logolabs.org</span>
|
| 360 |
</footer>
|
| 361 |
</div>
|
| 362 |
<div id="app"></div>
|
studio/pkg-threads/inkvec_studio_wasm.js
CHANGED
|
@@ -445,7 +445,7 @@ function __wbg_get_imports(memory) {
|
|
| 445 |
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
| 446 |
return addHeapObject(ret);
|
| 447 |
}, arguments); },
|
| 448 |
-
|
| 449 |
const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
|
| 450 |
return addHeapObject(ret);
|
| 451 |
}, arguments); },
|
|
|
|
| 445 |
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
| 446 |
return addHeapObject(ret);
|
| 447 |
}, arguments); },
|
| 448 |
+
__wbg_inkvecDenoiseSync_7c6dc8ef696545a2: function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
| 449 |
const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
|
| 450 |
return addHeapObject(ret);
|
| 451 |
}, arguments); },
|
studio/pkg-threads/inkvec_studio_wasm_bg.wasm
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a6405d9325dacf06d7fc60d50eed726853f4ef58ce5cb2a2ad0aadbee8d8ec86
|
| 3 |
+
size 6858009
|
studio/pkg-threads/snippets/wasm-bindgen-rayon-38edf6e439f6d70d/src/workerHelpers.js
CHANGED
|
@@ -51,7 +51,7 @@ waitForMsgType(self, 'wasm_bindgen_worker_init').then(async ({ init, receiver })
|
|
| 51 |
// OTOH, even though it can't be inlined, it should be still reasonably
|
| 52 |
// cheap since the requested file is already in cache (it was loaded by
|
| 53 |
// the main thread).
|
| 54 |
-
const pkg = await import('../../../inkvec_studio_wasm.js?v=
|
| 55 |
await pkg.default(init);
|
| 56 |
postMessage({ type: 'wasm_bindgen_worker_ready' });
|
| 57 |
pkg.wbg_rayon_start_worker(receiver);
|
|
|
|
| 51 |
// OTOH, even though it can't be inlined, it should be still reasonably
|
| 52 |
// cheap since the requested file is already in cache (it was loaded by
|
| 53 |
// the main thread).
|
| 54 |
+
const pkg = await import('../../../inkvec_studio_wasm.js?v=4d6460155cef');
|
| 55 |
await pkg.default(init);
|
| 56 |
postMessage({ type: 'wasm_bindgen_worker_ready' });
|
| 57 |
pkg.wbg_rayon_start_worker(receiver);
|
studio/pkg/inkvec_studio_wasm.js
CHANGED
|
@@ -382,7 +382,7 @@ function __wbg_get_imports() {
|
|
| 382 |
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
| 383 |
return addHeapObject(ret);
|
| 384 |
}, arguments); },
|
| 385 |
-
|
| 386 |
const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
|
| 387 |
return addHeapObject(ret);
|
| 388 |
}, arguments); },
|
|
|
|
| 382 |
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
| 383 |
return addHeapObject(ret);
|
| 384 |
}, arguments); },
|
| 385 |
+
__wbg_inkvecDenoiseSync_7c6dc8ef696545a2: function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
| 386 |
const ret = globalThis.inkvecDenoiseSync(getArrayF32FromWasm0(arg0, arg1), arg2 >>> 0, arg3 >>> 0);
|
| 387 |
return addHeapObject(ret);
|
| 388 |
}, arguments); },
|
studio/pkg/inkvec_studio_wasm_bg.wasm
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8a934a261af54ed9120dcbf0f5570f2ccd29d41a6feae289fc45583f4ba197d7
|
| 3 |
+
size 6806978
|