@squinch/core 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -169,7 +169,11 @@ export async function renderProject(input, opts = {}) {
169
169
  loc: { from: 0, to: 0, line: 1, col: 1 },
170
170
  };
171
171
  }
172
- const themeName = opts.theme ?? view.theme ?? built.model.fileTheme ?? "light";
172
+ // Dark is the default render. The one exception is an adaptive render with
173
+ // no theme named anywhere: an adaptive file is a light render carrying a
174
+ // dark override (the media query is `prefers-color-scheme: dark`), so its
175
+ // base has to be light — naming `dark` for it is still the error below.
176
+ const themeName = opts.theme ?? view.theme ?? built.model.fileTheme ?? (opts.adaptive ? "light" : "dark");
173
177
  const theme = themes[themeName];
174
178
  const diagnostics = [...built.diagnostics];
175
179
  if (!theme)
@@ -1 +1 @@
1
- export declare const RUNTIME_JS = "\"use strict\";(()=>{var Q={ms:460,ease:\"cubic-bezier(.32,.72,0,1)\"},X={ms:240,ease:\"cubic-bezier(.4,0,.2,1)\"},K=e=>({x:e.x+e.w/2,y:e.y+e.h/2}),Y=(e,n,i)=>Math.min(i,Math.max(n,e)),Z=(e,n)=>Y(Math.min(e.w/n.w,e.h/n.h),1.15,3.2);function U(e){let{view:n,ghostBox:i,liveBox:a,anchor:p,dir:o}=e,{ms:l,ease:d}=p?Q:X;if(!p)return{ms:l,ease:d,gOrigin:\"50% 50%\",lOrigin:\"50% 50%\",gEnd:\"scale(.97)\",lStart:\"scale(1.03)\"};let f=Z(n,p),T=1+(f-1)*.62,E=K(p),h=K(n),y=h.x-E.x,w=h.y-E.y,x=o===\"in\",g=x?E:h,k=x?h:E;return{ms:l,ease:d,gOrigin:`${g.x-i.x}px ${g.y-i.y}px`,lOrigin:`${k.x-a.x}px ${k.y-a.y}px`,gEnd:x?`translate(${y}px, ${w}px) scale(${f})`:`translate(${-y}px, ${-w}px) scale(${1/f})`,lStart:x?`translate(${-y}px, ${-w}px) scale(${1/T})`:`translate(${y}px, ${w}px) scale(${T})`}}function W(e,n){if(n){if(!e)return n.split(\".\")[0];if(!(n===e||!n.startsWith(`${e}.`)))return`${e}.${n.slice(e.length+1).split(\".\")[0]}`}}function ee(e){if(!e)return[];let n=e.split(\".\");return n.map((i,a)=>n.slice(0,a+1).join(\".\"))}function O(e,n,i){return e.find(a=>a.scope===i&&a.name!==n)}function _(e,n,i){let a=e.find(d=>d.name===n)?.scope,p=e.find(d=>d.name===i)?.scope,o=W(a,p);if(o)return{dir:\"in\",anchor:o};let l=W(p,a);return l?{dir:\"out\",anchor:l}:{dir:\"in\"}}function te(e,n){let i=[],a=e.find(o=>!o.scope);if(a&&i.push({label:\"landscape\",view:a.name}),!n)return i;let p=n.split(\".\");for(let[o,l]of ee(n).entries())i.push({label:p[o],view:e.find(d=>d.scope===l)?.name});return i}function S(e,n,i){return[...te(e,i)].reverse().find(a=>a.view&&a.view!==n)?.view}var L=e=>document.querySelector(e);function j(){let e=JSON.parse(L(\"#sq-data\").textContent||\"{}\"),n=L(\"#sq-live\"),i=L(\"#sq-ghost\"),a=L(\"#sq-stage\"),p=()=>matchMedia(\"(prefers-reduced-motion: reduce)\").matches,o=e.entry,l=e.themes[0],d=0,f=!1;if(e.themes.length>1&&matchMedia(\"(prefers-color-scheme: dark)\").matches){let t=e.themes.find(s=>s.includes(\"dark\"));t&&(l=t)}let T=`${e.entry}|${e.themes[0]}`,E=n.firstElementChild?.cloneNode(!0)??null,h=(t,s,c=0)=>{let r=c?`${t}|${s}|${c}`:`${t}|${s}`;if(r===T)return E?.cloneNode(!0)??null;let u=document.querySelector(`template[data-key=\"${CSS.escape(r)}\"]`);return u?u.content.cloneNode(!0):null},y=t=>e.views.find(s=>s.name===t)?.scope,w=t=>{let s=t.getBoundingClientRect(),c=a.getBoundingClientRect();return{x:s.left-c.left,y:s.top-c.top,w:s.width,h:s.height}};function x(){document.title=e.views.find(r=>r.name===o)?.title??document.title;let t=document.querySelector(\"#sq-tabs\");if(t){t.replaceChildren();for(let r of e.views){let u=document.createElement(\"button\");u.type=\"button\",u.className=r.name===o?\"on\":\"\",u.textContent=r.name,u.title=r.title??r.name,u.onclick=()=>g(r.name),t.append(u)}t.querySelector(\".on\")?.scrollIntoView?.({block:\"nearest\",inline:\"nearest\"})}for(let r of n.querySelectorAll(\"[data-path]\")){let u=r.getAttribute(\"data-path\");r.classList.toggle(\"sq-zoom\",!!(u&&O(e.views,o,u)))}let s=document.querySelector(\"#sq-step\"),c=e.flows[o]??0;s&&(s.textContent=f&&c?`${d||1} / ${c}`:\"\")}function g(t,s=!1){if(!t||t===o)return;let c=f&&e.flows[t]?s?e.flows[t]:1:0,r=h(t,l,c);if(!r)return;d=c;let{dir:u,anchor:v}=_(e.views,o,t),C=w(n),H=n.firstElementChild;if(p()||!H){n.replaceChildren(r),o=t,x();return}i.replaceChildren(H.cloneNode(!0)),i.style.cssText=`position:absolute;left:${C.x}px;top:${C.y}px;width:${C.w}px;height:${C.h}px;z-index:1;pointer-events:none`,n.replaceChildren(r),o=t,x();let G=w(n),P=v?(u===\"in\"?i:n).querySelector(`[data-path=\"${CSS.escape(v)}\"]`):null,m=U({view:{x:0,y:0,w:a.clientWidth,h:a.clientHeight},ghostBox:C,liveBox:G,anchor:P?w(P):void 0,dir:u}),b=i.style,$=n.style;b.transition=\"none\",b.transformOrigin=m.gOrigin,b.transform=\"none\",b.opacity=\"1\",$.transition=\"none\",$.transformOrigin=m.lOrigin,$.transform=m.lStart,$.opacity=\"0\",n.offsetHeight,b.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.55)}ms ${m.ease}`,$.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.6)}ms ${m.ease} ${Math.round(m.ms*.25)}ms`,b.transform=m.gEnd,b.opacity=\"0\",$.transform=\"none\",$.opacity=\"1\";let I=!1,q=0,R=()=>{I||(I=!0,cancelAnimationFrame(q),i.replaceChildren(),i.removeAttribute(\"style\"),n.removeAttribute(\"style\"))},z=()=>{getComputedStyle(n).transform===\"none\"?R():q=requestAnimationFrame(z)};q=requestAnimationFrame(z),setTimeout(R,m.ms+1e3)}function k(t){let s=t===l?null:h(o,t,d);s&&(l=t,document.documentElement.dataset.theme=t,n.replaceChildren(s))}function M(t){let s=e.flows[o]??0,c=d+t;if(s&&c>=1&&c<=s){let v=h(o,l,c);v&&(d=c,n.replaceChildren(v),x());return}let r=e.views.findIndex(v=>v.name===o),u=e.views[r+t];u&&g(u.name,t<0)}n.addEventListener(\"click\",t=>{let c=t.target.closest?.(\"[data-path]\")?.getAttribute(\"data-path\");if(c){let r=O(e.views,o,c);if(r)return g(r.name)}if(!c){let r=S(e.views,o,y(o));r&&g(r)}});let A=document.querySelector(\"#sq-theme\");A&&(A.onclick=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]));function B(t){if(t!==f){if(f=t,document.body.classList.toggle(\"presenting\",t),t){if(document.documentElement.requestFullscreen?.().catch(()=>{}),(e.flows[o]??0)&&!d){let c=h(o,l,1);c&&(d=1,n.replaceChildren(c))}}else if(document.fullscreenElement&&document.exitFullscreen?.().catch(()=>{}),d){let s=h(o,l,0);s&&(d=0,n.replaceChildren(s))}x()}}let N,V=()=>{document.body.classList.remove(\"idle\"),clearTimeout(N),f&&(N=setTimeout(()=>document.body.classList.add(\"idle\"),3500))};addEventListener(\"mousemove\",V),addEventListener(\"keydown\",V);let J=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]);addEventListener(\"keydown\",t=>{if(!(t.metaKey||t.ctrlKey||t.altKey))switch(t.key){case\"ArrowRight\":case\"PageDown\":case\" \":case\"Enter\":t.preventDefault(),M(1);break;case\"ArrowLeft\":case\"PageUp\":t.preventDefault(),M(-1);break;case\"ArrowUp\":case\"Backspace\":{let s=S(e.views,o,y(o));s&&(t.preventDefault(),g(s));break}case\"Home\":t.preventDefault(),g(e.views[0].name);break;case\"End\":t.preventDefault(),g(e.views[e.views.length-1].name,!0);break;case\"Escape\":f&&(t.preventDefault(),B(!1));break;case\"p\":case\"P\":B(!f);break;case\"f\":case\"F\":document.fullscreenElement?document.exitFullscreen?.().catch(()=>{}):document.documentElement.requestFullscreen?.().catch(()=>{});break;case\"t\":case\"T\":e.themes.length>1&&J();break}}),addEventListener(\"fullscreenchange\",()=>{!document.fullscreenElement&&f&&B(!1)});let D=document.querySelector(\"#sq-present\");D&&(D.onclick=()=>B(!f));let F=()=>{let t=decodeURIComponent(location.hash.slice(1));t&&t!==o&&e.views.some(s=>s.name===t)&&g(t)};if(addEventListener(\"hashchange\",F),document.documentElement.dataset.theme=l,l!==e.themes[0]){let t=h(o,l);t&&n.replaceChildren(t)}x(),F()}document.readyState===\"loading\"?addEventListener(\"DOMContentLoaded\",j):j();})();";
1
+ export declare const RUNTIME_JS = "\"use strict\";(()=>{var Q={ms:460,ease:\"cubic-bezier(.32,.72,0,1)\"},X={ms:240,ease:\"cubic-bezier(.4,0,.2,1)\"},K=e=>({x:e.x+e.w/2,y:e.y+e.h/2}),Y=(e,n,c)=>Math.min(c,Math.max(n,e)),Z=(e,n)=>Y(Math.min(e.w/n.w,e.h/n.h),1.15,3.2);function U(e){let{view:n,ghostBox:c,liveBox:a,anchor:p,dir:o}=e,{ms:l,ease:d}=p?Q:X;if(!p)return{ms:l,ease:d,gOrigin:\"50% 50%\",lOrigin:\"50% 50%\",gEnd:\"scale(.97)\",lStart:\"scale(1.03)\"};let f=Z(n,p),T=1+(f-1)*.62,E=K(p),h=K(n),y=h.x-E.x,w=h.y-E.y,x=o===\"in\",g=x?E:h,k=x?h:E;return{ms:l,ease:d,gOrigin:`${g.x-c.x}px ${g.y-c.y}px`,lOrigin:`${k.x-a.x}px ${k.y-a.y}px`,gEnd:x?`translate(${y}px, ${w}px) scale(${f})`:`translate(${-y}px, ${-w}px) scale(${1/f})`,lStart:x?`translate(${-y}px, ${-w}px) scale(${1/T})`:`translate(${y}px, ${w}px) scale(${T})`}}function W(e,n){if(n){if(!e)return n.split(\".\")[0];if(!(n===e||!n.startsWith(`${e}.`)))return`${e}.${n.slice(e.length+1).split(\".\")[0]}`}}function ee(e){if(!e)return[];let n=e.split(\".\");return n.map((c,a)=>n.slice(0,a+1).join(\".\"))}function O(e,n,c){return e.find(a=>a.scope===c&&a.name!==n)}function _(e,n,c){let a=e.find(d=>d.name===n)?.scope,p=e.find(d=>d.name===c)?.scope,o=W(a,p);if(o)return{dir:\"in\",anchor:o};let l=W(p,a);return l?{dir:\"out\",anchor:l}:{dir:\"in\"}}function te(e,n){let c=[],a=e.find(o=>!o.scope);if(a&&c.push({label:\"landscape\",view:a.name}),!n)return c;let p=n.split(\".\");for(let[o,l]of ee(n).entries())c.push({label:p[o],view:e.find(d=>d.scope===l)?.name});return c}function S(e,n,c){return[...te(e,c)].reverse().find(a=>a.view&&a.view!==n)?.view}var L=e=>document.querySelector(e);function j(){let e=JSON.parse(L(\"#sq-data\").textContent||\"{}\"),n=L(\"#sq-live\"),c=L(\"#sq-ghost\"),a=L(\"#sq-stage\"),p=()=>matchMedia(\"(prefers-reduced-motion: reduce)\").matches,o=e.entry,l=e.themes[0],d=0,f=!1;if(e.themes.length>1){let t=matchMedia(\"(prefers-color-scheme: dark)\").matches,s=e.themes.find(r=>r.includes(\"dark\")===t);s&&(l=s)}let T=`${e.entry}|${e.themes[0]}`,E=n.firstElementChild?.cloneNode(!0)??null,h=(t,s,r=0)=>{let i=r?`${t}|${s}|${r}`:`${t}|${s}`;if(i===T)return E?.cloneNode(!0)??null;let u=document.querySelector(`template[data-key=\"${CSS.escape(i)}\"]`);return u?u.content.cloneNode(!0):null},y=t=>e.views.find(s=>s.name===t)?.scope,w=t=>{let s=t.getBoundingClientRect(),r=a.getBoundingClientRect();return{x:s.left-r.left,y:s.top-r.top,w:s.width,h:s.height}};function x(){document.title=e.views.find(i=>i.name===o)?.title??document.title;let t=document.querySelector(\"#sq-tabs\");if(t){t.replaceChildren();for(let i of e.views){let u=document.createElement(\"button\");u.type=\"button\",u.className=i.name===o?\"on\":\"\",u.textContent=i.name,u.title=i.title??i.name,u.onclick=()=>g(i.name),t.append(u)}t.querySelector(\".on\")?.scrollIntoView?.({block:\"nearest\",inline:\"nearest\"})}for(let i of n.querySelectorAll(\"[data-path]\")){let u=i.getAttribute(\"data-path\");i.classList.toggle(\"sq-zoom\",!!(u&&O(e.views,o,u)))}let s=document.querySelector(\"#sq-step\"),r=e.flows[o]??0;s&&(s.textContent=f&&r?`${d||1} / ${r}`:\"\")}function g(t,s=!1){if(!t||t===o)return;let r=f&&e.flows[t]?s?e.flows[t]:1:0,i=h(t,l,r);if(!i)return;d=r;let{dir:u,anchor:v}=_(e.views,o,t),C=w(n),H=n.firstElementChild;if(p()||!H){n.replaceChildren(i),o=t,x();return}c.replaceChildren(H.cloneNode(!0)),c.style.cssText=`position:absolute;left:${C.x}px;top:${C.y}px;width:${C.w}px;height:${C.h}px;z-index:1;pointer-events:none`,n.replaceChildren(i),o=t,x();let G=w(n),P=v?(u===\"in\"?c:n).querySelector(`[data-path=\"${CSS.escape(v)}\"]`):null,m=U({view:{x:0,y:0,w:a.clientWidth,h:a.clientHeight},ghostBox:C,liveBox:G,anchor:P?w(P):void 0,dir:u}),b=c.style,$=n.style;b.transition=\"none\",b.transformOrigin=m.gOrigin,b.transform=\"none\",b.opacity=\"1\",$.transition=\"none\",$.transformOrigin=m.lOrigin,$.transform=m.lStart,$.opacity=\"0\",n.offsetHeight,b.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.55)}ms ${m.ease}`,$.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.6)}ms ${m.ease} ${Math.round(m.ms*.25)}ms`,b.transform=m.gEnd,b.opacity=\"0\",$.transform=\"none\",$.opacity=\"1\";let I=!1,q=0,R=()=>{I||(I=!0,cancelAnimationFrame(q),c.replaceChildren(),c.removeAttribute(\"style\"),n.removeAttribute(\"style\"))},z=()=>{getComputedStyle(n).transform===\"none\"?R():q=requestAnimationFrame(z)};q=requestAnimationFrame(z),setTimeout(R,m.ms+1e3)}function k(t){let s=t===l?null:h(o,t,d);s&&(l=t,document.documentElement.dataset.theme=t,n.replaceChildren(s))}function M(t){let s=e.flows[o]??0,r=d+t;if(s&&r>=1&&r<=s){let v=h(o,l,r);v&&(d=r,n.replaceChildren(v),x());return}let i=e.views.findIndex(v=>v.name===o),u=e.views[i+t];u&&g(u.name,t<0)}n.addEventListener(\"click\",t=>{let r=t.target.closest?.(\"[data-path]\")?.getAttribute(\"data-path\");if(r){let i=O(e.views,o,r);if(i)return g(i.name)}if(!r){let i=S(e.views,o,y(o));i&&g(i)}});let A=document.querySelector(\"#sq-theme\");A&&(A.onclick=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]));function B(t){if(t!==f){if(f=t,document.body.classList.toggle(\"presenting\",t),t){if(document.documentElement.requestFullscreen?.().catch(()=>{}),(e.flows[o]??0)&&!d){let r=h(o,l,1);r&&(d=1,n.replaceChildren(r))}}else if(document.fullscreenElement&&document.exitFullscreen?.().catch(()=>{}),d){let s=h(o,l,0);s&&(d=0,n.replaceChildren(s))}x()}}let N,V=()=>{document.body.classList.remove(\"idle\"),clearTimeout(N),f&&(N=setTimeout(()=>document.body.classList.add(\"idle\"),3500))};addEventListener(\"mousemove\",V),addEventListener(\"keydown\",V);let J=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]);addEventListener(\"keydown\",t=>{if(!(t.metaKey||t.ctrlKey||t.altKey))switch(t.key){case\"ArrowRight\":case\"PageDown\":case\" \":case\"Enter\":t.preventDefault(),M(1);break;case\"ArrowLeft\":case\"PageUp\":t.preventDefault(),M(-1);break;case\"ArrowUp\":case\"Backspace\":{let s=S(e.views,o,y(o));s&&(t.preventDefault(),g(s));break}case\"Home\":t.preventDefault(),g(e.views[0].name);break;case\"End\":t.preventDefault(),g(e.views[e.views.length-1].name,!0);break;case\"Escape\":f&&(t.preventDefault(),B(!1));break;case\"p\":case\"P\":B(!f);break;case\"f\":case\"F\":document.fullscreenElement?document.exitFullscreen?.().catch(()=>{}):document.documentElement.requestFullscreen?.().catch(()=>{});break;case\"t\":case\"T\":e.themes.length>1&&J();break}}),addEventListener(\"fullscreenchange\",()=>{!document.fullscreenElement&&f&&B(!1)});let D=document.querySelector(\"#sq-present\");D&&(D.onclick=()=>B(!f));let F=()=>{let t=decodeURIComponent(location.hash.slice(1));t&&t!==o&&e.views.some(s=>s.name===t)&&g(t)};if(addEventListener(\"hashchange\",F),document.documentElement.dataset.theme=l,l!==e.themes[0]){let t=h(o,l);t&&n.replaceChildren(t)}x(),F()}document.readyState===\"loading\"?addEventListener(\"DOMContentLoaded\",j):j();})();";
@@ -3,4 +3,4 @@
3
3
  // output cannot drift with an esbuild upgrade; CI re-runs the generator and
4
4
  // diffs. It bundles view/dive.ts and view/navigate.ts, which is what makes
5
5
  // "the export moves exactly like the playground" true by construction.
6
- export const RUNTIME_JS = "\"use strict\";(()=>{var Q={ms:460,ease:\"cubic-bezier(.32,.72,0,1)\"},X={ms:240,ease:\"cubic-bezier(.4,0,.2,1)\"},K=e=>({x:e.x+e.w/2,y:e.y+e.h/2}),Y=(e,n,i)=>Math.min(i,Math.max(n,e)),Z=(e,n)=>Y(Math.min(e.w/n.w,e.h/n.h),1.15,3.2);function U(e){let{view:n,ghostBox:i,liveBox:a,anchor:p,dir:o}=e,{ms:l,ease:d}=p?Q:X;if(!p)return{ms:l,ease:d,gOrigin:\"50% 50%\",lOrigin:\"50% 50%\",gEnd:\"scale(.97)\",lStart:\"scale(1.03)\"};let f=Z(n,p),T=1+(f-1)*.62,E=K(p),h=K(n),y=h.x-E.x,w=h.y-E.y,x=o===\"in\",g=x?E:h,k=x?h:E;return{ms:l,ease:d,gOrigin:`${g.x-i.x}px ${g.y-i.y}px`,lOrigin:`${k.x-a.x}px ${k.y-a.y}px`,gEnd:x?`translate(${y}px, ${w}px) scale(${f})`:`translate(${-y}px, ${-w}px) scale(${1/f})`,lStart:x?`translate(${-y}px, ${-w}px) scale(${1/T})`:`translate(${y}px, ${w}px) scale(${T})`}}function W(e,n){if(n){if(!e)return n.split(\".\")[0];if(!(n===e||!n.startsWith(`${e}.`)))return`${e}.${n.slice(e.length+1).split(\".\")[0]}`}}function ee(e){if(!e)return[];let n=e.split(\".\");return n.map((i,a)=>n.slice(0,a+1).join(\".\"))}function O(e,n,i){return e.find(a=>a.scope===i&&a.name!==n)}function _(e,n,i){let a=e.find(d=>d.name===n)?.scope,p=e.find(d=>d.name===i)?.scope,o=W(a,p);if(o)return{dir:\"in\",anchor:o};let l=W(p,a);return l?{dir:\"out\",anchor:l}:{dir:\"in\"}}function te(e,n){let i=[],a=e.find(o=>!o.scope);if(a&&i.push({label:\"landscape\",view:a.name}),!n)return i;let p=n.split(\".\");for(let[o,l]of ee(n).entries())i.push({label:p[o],view:e.find(d=>d.scope===l)?.name});return i}function S(e,n,i){return[...te(e,i)].reverse().find(a=>a.view&&a.view!==n)?.view}var L=e=>document.querySelector(e);function j(){let e=JSON.parse(L(\"#sq-data\").textContent||\"{}\"),n=L(\"#sq-live\"),i=L(\"#sq-ghost\"),a=L(\"#sq-stage\"),p=()=>matchMedia(\"(prefers-reduced-motion: reduce)\").matches,o=e.entry,l=e.themes[0],d=0,f=!1;if(e.themes.length>1&&matchMedia(\"(prefers-color-scheme: dark)\").matches){let t=e.themes.find(s=>s.includes(\"dark\"));t&&(l=t)}let T=`${e.entry}|${e.themes[0]}`,E=n.firstElementChild?.cloneNode(!0)??null,h=(t,s,c=0)=>{let r=c?`${t}|${s}|${c}`:`${t}|${s}`;if(r===T)return E?.cloneNode(!0)??null;let u=document.querySelector(`template[data-key=\"${CSS.escape(r)}\"]`);return u?u.content.cloneNode(!0):null},y=t=>e.views.find(s=>s.name===t)?.scope,w=t=>{let s=t.getBoundingClientRect(),c=a.getBoundingClientRect();return{x:s.left-c.left,y:s.top-c.top,w:s.width,h:s.height}};function x(){document.title=e.views.find(r=>r.name===o)?.title??document.title;let t=document.querySelector(\"#sq-tabs\");if(t){t.replaceChildren();for(let r of e.views){let u=document.createElement(\"button\");u.type=\"button\",u.className=r.name===o?\"on\":\"\",u.textContent=r.name,u.title=r.title??r.name,u.onclick=()=>g(r.name),t.append(u)}t.querySelector(\".on\")?.scrollIntoView?.({block:\"nearest\",inline:\"nearest\"})}for(let r of n.querySelectorAll(\"[data-path]\")){let u=r.getAttribute(\"data-path\");r.classList.toggle(\"sq-zoom\",!!(u&&O(e.views,o,u)))}let s=document.querySelector(\"#sq-step\"),c=e.flows[o]??0;s&&(s.textContent=f&&c?`${d||1} / ${c}`:\"\")}function g(t,s=!1){if(!t||t===o)return;let c=f&&e.flows[t]?s?e.flows[t]:1:0,r=h(t,l,c);if(!r)return;d=c;let{dir:u,anchor:v}=_(e.views,o,t),C=w(n),H=n.firstElementChild;if(p()||!H){n.replaceChildren(r),o=t,x();return}i.replaceChildren(H.cloneNode(!0)),i.style.cssText=`position:absolute;left:${C.x}px;top:${C.y}px;width:${C.w}px;height:${C.h}px;z-index:1;pointer-events:none`,n.replaceChildren(r),o=t,x();let G=w(n),P=v?(u===\"in\"?i:n).querySelector(`[data-path=\"${CSS.escape(v)}\"]`):null,m=U({view:{x:0,y:0,w:a.clientWidth,h:a.clientHeight},ghostBox:C,liveBox:G,anchor:P?w(P):void 0,dir:u}),b=i.style,$=n.style;b.transition=\"none\",b.transformOrigin=m.gOrigin,b.transform=\"none\",b.opacity=\"1\",$.transition=\"none\",$.transformOrigin=m.lOrigin,$.transform=m.lStart,$.opacity=\"0\",n.offsetHeight,b.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.55)}ms ${m.ease}`,$.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.6)}ms ${m.ease} ${Math.round(m.ms*.25)}ms`,b.transform=m.gEnd,b.opacity=\"0\",$.transform=\"none\",$.opacity=\"1\";let I=!1,q=0,R=()=>{I||(I=!0,cancelAnimationFrame(q),i.replaceChildren(),i.removeAttribute(\"style\"),n.removeAttribute(\"style\"))},z=()=>{getComputedStyle(n).transform===\"none\"?R():q=requestAnimationFrame(z)};q=requestAnimationFrame(z),setTimeout(R,m.ms+1e3)}function k(t){let s=t===l?null:h(o,t,d);s&&(l=t,document.documentElement.dataset.theme=t,n.replaceChildren(s))}function M(t){let s=e.flows[o]??0,c=d+t;if(s&&c>=1&&c<=s){let v=h(o,l,c);v&&(d=c,n.replaceChildren(v),x());return}let r=e.views.findIndex(v=>v.name===o),u=e.views[r+t];u&&g(u.name,t<0)}n.addEventListener(\"click\",t=>{let c=t.target.closest?.(\"[data-path]\")?.getAttribute(\"data-path\");if(c){let r=O(e.views,o,c);if(r)return g(r.name)}if(!c){let r=S(e.views,o,y(o));r&&g(r)}});let A=document.querySelector(\"#sq-theme\");A&&(A.onclick=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]));function B(t){if(t!==f){if(f=t,document.body.classList.toggle(\"presenting\",t),t){if(document.documentElement.requestFullscreen?.().catch(()=>{}),(e.flows[o]??0)&&!d){let c=h(o,l,1);c&&(d=1,n.replaceChildren(c))}}else if(document.fullscreenElement&&document.exitFullscreen?.().catch(()=>{}),d){let s=h(o,l,0);s&&(d=0,n.replaceChildren(s))}x()}}let N,V=()=>{document.body.classList.remove(\"idle\"),clearTimeout(N),f&&(N=setTimeout(()=>document.body.classList.add(\"idle\"),3500))};addEventListener(\"mousemove\",V),addEventListener(\"keydown\",V);let J=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]);addEventListener(\"keydown\",t=>{if(!(t.metaKey||t.ctrlKey||t.altKey))switch(t.key){case\"ArrowRight\":case\"PageDown\":case\" \":case\"Enter\":t.preventDefault(),M(1);break;case\"ArrowLeft\":case\"PageUp\":t.preventDefault(),M(-1);break;case\"ArrowUp\":case\"Backspace\":{let s=S(e.views,o,y(o));s&&(t.preventDefault(),g(s));break}case\"Home\":t.preventDefault(),g(e.views[0].name);break;case\"End\":t.preventDefault(),g(e.views[e.views.length-1].name,!0);break;case\"Escape\":f&&(t.preventDefault(),B(!1));break;case\"p\":case\"P\":B(!f);break;case\"f\":case\"F\":document.fullscreenElement?document.exitFullscreen?.().catch(()=>{}):document.documentElement.requestFullscreen?.().catch(()=>{});break;case\"t\":case\"T\":e.themes.length>1&&J();break}}),addEventListener(\"fullscreenchange\",()=>{!document.fullscreenElement&&f&&B(!1)});let D=document.querySelector(\"#sq-present\");D&&(D.onclick=()=>B(!f));let F=()=>{let t=decodeURIComponent(location.hash.slice(1));t&&t!==o&&e.views.some(s=>s.name===t)&&g(t)};if(addEventListener(\"hashchange\",F),document.documentElement.dataset.theme=l,l!==e.themes[0]){let t=h(o,l);t&&n.replaceChildren(t)}x(),F()}document.readyState===\"loading\"?addEventListener(\"DOMContentLoaded\",j):j();})();";
6
+ export const RUNTIME_JS = "\"use strict\";(()=>{var Q={ms:460,ease:\"cubic-bezier(.32,.72,0,1)\"},X={ms:240,ease:\"cubic-bezier(.4,0,.2,1)\"},K=e=>({x:e.x+e.w/2,y:e.y+e.h/2}),Y=(e,n,c)=>Math.min(c,Math.max(n,e)),Z=(e,n)=>Y(Math.min(e.w/n.w,e.h/n.h),1.15,3.2);function U(e){let{view:n,ghostBox:c,liveBox:a,anchor:p,dir:o}=e,{ms:l,ease:d}=p?Q:X;if(!p)return{ms:l,ease:d,gOrigin:\"50% 50%\",lOrigin:\"50% 50%\",gEnd:\"scale(.97)\",lStart:\"scale(1.03)\"};let f=Z(n,p),T=1+(f-1)*.62,E=K(p),h=K(n),y=h.x-E.x,w=h.y-E.y,x=o===\"in\",g=x?E:h,k=x?h:E;return{ms:l,ease:d,gOrigin:`${g.x-c.x}px ${g.y-c.y}px`,lOrigin:`${k.x-a.x}px ${k.y-a.y}px`,gEnd:x?`translate(${y}px, ${w}px) scale(${f})`:`translate(${-y}px, ${-w}px) scale(${1/f})`,lStart:x?`translate(${-y}px, ${-w}px) scale(${1/T})`:`translate(${y}px, ${w}px) scale(${T})`}}function W(e,n){if(n){if(!e)return n.split(\".\")[0];if(!(n===e||!n.startsWith(`${e}.`)))return`${e}.${n.slice(e.length+1).split(\".\")[0]}`}}function ee(e){if(!e)return[];let n=e.split(\".\");return n.map((c,a)=>n.slice(0,a+1).join(\".\"))}function O(e,n,c){return e.find(a=>a.scope===c&&a.name!==n)}function _(e,n,c){let a=e.find(d=>d.name===n)?.scope,p=e.find(d=>d.name===c)?.scope,o=W(a,p);if(o)return{dir:\"in\",anchor:o};let l=W(p,a);return l?{dir:\"out\",anchor:l}:{dir:\"in\"}}function te(e,n){let c=[],a=e.find(o=>!o.scope);if(a&&c.push({label:\"landscape\",view:a.name}),!n)return c;let p=n.split(\".\");for(let[o,l]of ee(n).entries())c.push({label:p[o],view:e.find(d=>d.scope===l)?.name});return c}function S(e,n,c){return[...te(e,c)].reverse().find(a=>a.view&&a.view!==n)?.view}var L=e=>document.querySelector(e);function j(){let e=JSON.parse(L(\"#sq-data\").textContent||\"{}\"),n=L(\"#sq-live\"),c=L(\"#sq-ghost\"),a=L(\"#sq-stage\"),p=()=>matchMedia(\"(prefers-reduced-motion: reduce)\").matches,o=e.entry,l=e.themes[0],d=0,f=!1;if(e.themes.length>1){let t=matchMedia(\"(prefers-color-scheme: dark)\").matches,s=e.themes.find(r=>r.includes(\"dark\")===t);s&&(l=s)}let T=`${e.entry}|${e.themes[0]}`,E=n.firstElementChild?.cloneNode(!0)??null,h=(t,s,r=0)=>{let i=r?`${t}|${s}|${r}`:`${t}|${s}`;if(i===T)return E?.cloneNode(!0)??null;let u=document.querySelector(`template[data-key=\"${CSS.escape(i)}\"]`);return u?u.content.cloneNode(!0):null},y=t=>e.views.find(s=>s.name===t)?.scope,w=t=>{let s=t.getBoundingClientRect(),r=a.getBoundingClientRect();return{x:s.left-r.left,y:s.top-r.top,w:s.width,h:s.height}};function x(){document.title=e.views.find(i=>i.name===o)?.title??document.title;let t=document.querySelector(\"#sq-tabs\");if(t){t.replaceChildren();for(let i of e.views){let u=document.createElement(\"button\");u.type=\"button\",u.className=i.name===o?\"on\":\"\",u.textContent=i.name,u.title=i.title??i.name,u.onclick=()=>g(i.name),t.append(u)}t.querySelector(\".on\")?.scrollIntoView?.({block:\"nearest\",inline:\"nearest\"})}for(let i of n.querySelectorAll(\"[data-path]\")){let u=i.getAttribute(\"data-path\");i.classList.toggle(\"sq-zoom\",!!(u&&O(e.views,o,u)))}let s=document.querySelector(\"#sq-step\"),r=e.flows[o]??0;s&&(s.textContent=f&&r?`${d||1} / ${r}`:\"\")}function g(t,s=!1){if(!t||t===o)return;let r=f&&e.flows[t]?s?e.flows[t]:1:0,i=h(t,l,r);if(!i)return;d=r;let{dir:u,anchor:v}=_(e.views,o,t),C=w(n),H=n.firstElementChild;if(p()||!H){n.replaceChildren(i),o=t,x();return}c.replaceChildren(H.cloneNode(!0)),c.style.cssText=`position:absolute;left:${C.x}px;top:${C.y}px;width:${C.w}px;height:${C.h}px;z-index:1;pointer-events:none`,n.replaceChildren(i),o=t,x();let G=w(n),P=v?(u===\"in\"?c:n).querySelector(`[data-path=\"${CSS.escape(v)}\"]`):null,m=U({view:{x:0,y:0,w:a.clientWidth,h:a.clientHeight},ghostBox:C,liveBox:G,anchor:P?w(P):void 0,dir:u}),b=c.style,$=n.style;b.transition=\"none\",b.transformOrigin=m.gOrigin,b.transform=\"none\",b.opacity=\"1\",$.transition=\"none\",$.transformOrigin=m.lOrigin,$.transform=m.lStart,$.opacity=\"0\",n.offsetHeight,b.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.55)}ms ${m.ease}`,$.transition=`transform ${m.ms}ms ${m.ease}, opacity ${Math.round(m.ms*.6)}ms ${m.ease} ${Math.round(m.ms*.25)}ms`,b.transform=m.gEnd,b.opacity=\"0\",$.transform=\"none\",$.opacity=\"1\";let I=!1,q=0,R=()=>{I||(I=!0,cancelAnimationFrame(q),c.replaceChildren(),c.removeAttribute(\"style\"),n.removeAttribute(\"style\"))},z=()=>{getComputedStyle(n).transform===\"none\"?R():q=requestAnimationFrame(z)};q=requestAnimationFrame(z),setTimeout(R,m.ms+1e3)}function k(t){let s=t===l?null:h(o,t,d);s&&(l=t,document.documentElement.dataset.theme=t,n.replaceChildren(s))}function M(t){let s=e.flows[o]??0,r=d+t;if(s&&r>=1&&r<=s){let v=h(o,l,r);v&&(d=r,n.replaceChildren(v),x());return}let i=e.views.findIndex(v=>v.name===o),u=e.views[i+t];u&&g(u.name,t<0)}n.addEventListener(\"click\",t=>{let r=t.target.closest?.(\"[data-path]\")?.getAttribute(\"data-path\");if(r){let i=O(e.views,o,r);if(i)return g(i.name)}if(!r){let i=S(e.views,o,y(o));i&&g(i)}});let A=document.querySelector(\"#sq-theme\");A&&(A.onclick=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]));function B(t){if(t!==f){if(f=t,document.body.classList.toggle(\"presenting\",t),t){if(document.documentElement.requestFullscreen?.().catch(()=>{}),(e.flows[o]??0)&&!d){let r=h(o,l,1);r&&(d=1,n.replaceChildren(r))}}else if(document.fullscreenElement&&document.exitFullscreen?.().catch(()=>{}),d){let s=h(o,l,0);s&&(d=0,n.replaceChildren(s))}x()}}let N,V=()=>{document.body.classList.remove(\"idle\"),clearTimeout(N),f&&(N=setTimeout(()=>document.body.classList.add(\"idle\"),3500))};addEventListener(\"mousemove\",V),addEventListener(\"keydown\",V);let J=()=>k(e.themes[(e.themes.indexOf(l)+1)%e.themes.length]);addEventListener(\"keydown\",t=>{if(!(t.metaKey||t.ctrlKey||t.altKey))switch(t.key){case\"ArrowRight\":case\"PageDown\":case\" \":case\"Enter\":t.preventDefault(),M(1);break;case\"ArrowLeft\":case\"PageUp\":t.preventDefault(),M(-1);break;case\"ArrowUp\":case\"Backspace\":{let s=S(e.views,o,y(o));s&&(t.preventDefault(),g(s));break}case\"Home\":t.preventDefault(),g(e.views[0].name);break;case\"End\":t.preventDefault(),g(e.views[e.views.length-1].name,!0);break;case\"Escape\":f&&(t.preventDefault(),B(!1));break;case\"p\":case\"P\":B(!f);break;case\"f\":case\"F\":document.fullscreenElement?document.exitFullscreen?.().catch(()=>{}):document.documentElement.requestFullscreen?.().catch(()=>{});break;case\"t\":case\"T\":e.themes.length>1&&J();break}}),addEventListener(\"fullscreenchange\",()=>{!document.fullscreenElement&&f&&B(!1)});let D=document.querySelector(\"#sq-present\");D&&(D.onclick=()=>B(!f));let F=()=>{let t=decodeURIComponent(location.hash.slice(1));t&&t!==o&&e.views.some(s=>s.name===t)&&g(t)};if(addEventListener(\"hashchange\",F),document.documentElement.dataset.theme=l,l!==e.themes[0]){let t=h(o,l);t&&n.replaceChildren(t)}x(),F()}document.readyState===\"loading\"?addEventListener(\"DOMContentLoaded\",j):j();})();";
@@ -25,11 +25,15 @@ function boot() {
25
25
  let step = 0;
26
26
  let presenting = false;
27
27
  // The reader's own preference wins over the author's, when the file carries
28
- // a palette that matches it — the same rule an adaptive SVG follows.
29
- if (data.themes.length > 1 && matchMedia("(prefers-color-scheme: dark)").matches) {
30
- const dark = data.themes.find((t) => t.includes("dark"));
31
- if (dark)
32
- theme = dark;
28
+ // a palette that matches it — the same rule an adaptive SVG follows. Both
29
+ // directions: a light-mode reader of a dark-entry file gets light, not just
30
+ // the reverse (the entry is dark by default now, so one-way promotion would
31
+ // have made the system setting a no-op for half of readers).
32
+ if (data.themes.length > 1) {
33
+ const wantDark = matchMedia("(prefers-color-scheme: dark)").matches;
34
+ const match = data.themes.find((t) => t.includes("dark") === wantDark);
35
+ if (match)
36
+ theme = match;
33
37
  }
34
38
  // The entry view is inline rather than in a <template>, so that a reader
35
39
  // whose browser never runs this script still sees a diagram. That means it is
@@ -66,8 +66,11 @@ export async function exportHTML(files, opts = {}) {
66
66
  // A document has one palette at a time and a button to change it, so the
67
67
  // theme is the document's rather than each view's — a per-view `theme` is
68
68
  // deliberately overridden here, the way `--theme` overrides it elsewhere.
69
- const base = opts.themes?.[0] ?? built.model.fileTheme ?? "light";
70
- const palette = opts.themes ?? [base, themes[base]?.pairsWith].filter(Boolean);
69
+ const base = opts.themes?.[0] ?? built.model.fileTheme ?? "dark";
70
+ // the counterpart pairs in either direction: light names dark, and dark is
71
+ // found by being named — so a dark entry still bundles light for the toggle
72
+ const mate = themes[base]?.pairsWith ?? Object.values(themes).find((t) => t.pairsWith === base)?.name;
73
+ const palette = opts.themes ?? [base, mate].filter(Boolean);
71
74
  for (const name of palette)
72
75
  if (!themes[name])
73
76
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squinch/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "The Squinch engine: parse, model, layout and deterministic SVG rendering for architecture diagrams as code.",
5
5
  "keywords": [
6
6
  "architecture",
@@ -33,11 +33,11 @@
33
33
  "@lezer/lr": "^1.4.10",
34
34
  "elkjs": "^0.12.0",
35
35
  "fast-xml-parser": "^5.10.1",
36
- "@squinch/pack-aws": "0.1.0",
37
- "@squinch/pack-azure": "0.1.0",
38
- "@squinch/pack-k8s": "0.1.0",
39
- "@squinch/pack-logos": "0.1.0",
40
- "@squinch/pack-sys": "0.1.0"
36
+ "@squinch/pack-aws": "0.1.1",
37
+ "@squinch/pack-logos": "0.1.1",
38
+ "@squinch/pack-sys": "0.1.1",
39
+ "@squinch/pack-k8s": "0.1.1",
40
+ "@squinch/pack-azure": "0.1.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@fontsource/ibm-plex-mono": "^5.3.0",