@zeroxsolutions/zaku 0.0.4 → 0.1.0

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/rules.js CHANGED
@@ -1 +1 @@
1
- "use strict";var zakuRulesLib=(()=>{var B=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var xe=(e,t)=>{for(var n in t)B(e,n,{get:t[n],enumerable:true})};var Ae=(e,t,n,o)=>{if(t&&typeof t==="object"||typeof t==="function"){for(let r of Oe(t))if(!ve.call(e,r)&&r!==n)B(e,r,{get:()=>t[r],enumerable:!(o=Ie(t,r))||o.enumerable})}return e};var Ce=e=>Ae(B({},"__esModule",{value:true}),e);var Ot={};xe(Ot,{REPLY_BYTES:()=>H,scopeNodes:()=>Se,zakuRules:()=>It});var W={locales:["en"],currencies:[]};var q=new Set(["characters","name","componentProperties","componentPropertyReferences","exposedInstances","reactions","transitionNodeID","transitionDuration","transitionEasing"]);var Z=new Set(["primaryAxisSizingMode","counterAxisSizingMode"]);function J(e,t,n){if(!t||!n||e!=="width"&&e!=="height")return false;return Math.abs(t[e]-n[e])<.5}function Q(e){return e.horizontal!=="FIXED"||e.vertical!=="FIXED"}var ee="['’]";var te=[{pattern:/\bdelv(?:e|es|ed|ing)\b/iu,instead:'write "look at" or "read"'},{pattern:/\bleverag(?:e|es|ed|ing)\b/iu,instead:'write "use"'},{pattern:/\butili[sz](?:e|es|ed|ing|ation)\b/iu,instead:'write "use"'},{pattern:/\brobust(?:ly|ness)?\b/iu,instead:"write what it withstands"},{pattern:/\btapestr(?:y|ies)\b/iu,instead:'write "mix", or name the parts'},{pattern:/\btestaments?\b/iu,instead:'write "proof", or the fact itself'},{pattern:/\bvibrant(?:ly)?\b/iu,instead:'write "busy", or what is there'},{pattern:/\bempower(?:s|ed|ing|ment)?\b/iu,instead:'write "let" or "allow"'},{pattern:/\bunlock(?:s|ed|ing)?\b/iu,instead:'write "get" or "open"'},{pattern:/\bunleash(?:es|ed|ing)?\b/iu,instead:'write "use" or "start"'},{pattern:/\bgame[- ]?changers?\b/iu,instead:"write what it changes"},{pattern:/\bsupercharg(?:e|es|ed|ing)\b/iu,instead:'write "speed up", with the figure'},{pattern:new RegExp(`\\blet${ee}s\\b`,"iu"),instead:'write the action itself, such as "Plan a trip"'},{pattern:new RegExp(`\\b(?:it${ee}s|it is) (?:important|worth|crucial) (?:to note|noting)\\b`,"iu"),instead:"delete it"},{pattern:/\bin order to\b/iu,instead:'write "to"'},{pattern:/\bnot (?:just|only|merely)\b[^.!?]{0,80}?\bbut\b/iu,instead:"write the second half on its own"}];var ne={en:te};var Me=/^[\x20-\x7e]$/;var $e=new RegExp(`^[${String.fromCharCode(10,8232)}]$`);var Re=/^[\p{L}\p{M}]$/u;var ke=/^(?=\p{M})\p{Script=Inherited}$/u;var Pe=/^\p{Extended_Pictographic}$/u;var Fe=new RegExp("^[←-⇿⟰-⟿⤀-⥿⬀-⬑]$","u");var ze=new Map([["—",{name:"em dash",instead:'write "-", or two sentences'}],["–",{name:"en dash",instead:'write "-", or two sentences'}],["‘",{name:"left single quotation mark",instead:"write '"}],["’",{name:"right single quotation mark",instead:"write '"}],["“",{name:"left double quotation mark",instead:'write "'}],["”",{name:"right double quotation mark",instead:'write "'}],["…",{name:"horizontal ellipsis",instead:'write "..."'}],["·",{name:"middle dot",instead:'write "-", "," or ":"'}],["•",{name:"bullet",instead:'write "-", "," or ":"'}],["→",{name:"rightwards arrow",instead:'write "->"'}],["←",{name:"leftwards arrow",instead:'write "<-"'}],["×",{name:"multiplication sign",instead:'write "x"'}],[String.fromCharCode(160),{name:"no-break space",instead:"write a space"}],[String.fromCharCode(8203),{name:"zero width space",instead:"write nothing"}],[String.fromCharCode(8204),{name:"zero width non-joiner",instead:"write nothing"}],[String.fromCharCode(8205),{name:"zero width joiner",instead:"write nothing"}],[String.fromCharCode(65279),{name:"zero width no-break space",instead:"write nothing"}]]);var De={Jpan:["Han","Hiragana","Katakana"],Kore:["Hangul","Han"],Hans:["Han"],Hant:["Han"],Hanb:["Han","Bopomofo"]};function Le(e,t){return e.flatMap(n=>["symbol","narrowSymbol"].flatMap(o=>new Intl.NumberFormat(n,{style:"currency",currency:t,currencyDisplay:o}).formatToParts(0).filter(r=>r.type==="currency").map(r=>r.value)))}function He(e){const t=new Set(e.locales.flatMap(n=>{const o=new Intl.Locale(n).maximize().script??"";return De[o]??[o]}));return{scripts:[...t].filter(Boolean),symbols:[...new Set(e.currencies.flatMap(n=>Le(e.locales,n)))],languages:[...new Set(e.locales.map(n=>new Intl.Locale(n).language))]}}function oe(e,t){const n="scripts"in e?e:He(e);return{scripts:n.scripts.map(o=>new RegExp(`^\\p{Script_Extensions=${o}}$`,"u")),extra:new Set([...n.symbols,...t].flatMap(o=>[...o.normalize("NFC")])),tells:n.languages.flatMap(o=>ne[o]??[])}}function _e(e,t){if(Me.test(e)||$e.test(e)||t.extra.has(e))return true;if(!Re.test(e))return false;return ke.test(e)||t.scripts.some(n=>n.test(e))}function L(e){return`U+${(e.codePointAt(0)??0).toString(16).toUpperCase().padStart(4,"0")}`}function Ge(e){const t=ze.get(e);if(t)return`${L(e)} ${t.name}: ${t.instead}`;if(Pe.test(e))return`${L(e)} emoji: write a word, or a library icon`;if(Fe.test(e))return`${L(e)} arrow: write "->" or "<-"`;return`${L(e)} is outside the locales and currencies copy names in zaku.yaml: write it in ASCII, or add its locale or currency there`}function X(e,t){const n=[];const o=new Set;for(const r of e.normalize("NFC")){if(o.has(r)||_e(r,t))continue;o.add(r);n.push({field:"characters",message:Ge(r)})}for(const r of t.tells){const a=r.pattern.exec(e);if(a)n.push({field:"tone",message:`"${a[0]}": ${r.instead}`})}return n}var O={page:"Thumbnail",frame:"Thumbnail",width:1200,height:675,bleeds:"Glow",logo:"Logo",bleed:.25,margin:72};var z="❖ ";var j="Component for Docs";var I=(e,t,n)=>({mode:"VERTICAL",padding:e,gap:t,...n?{align:n}:{}});var x=(e,t,n)=>({mode:"HORIZONTAL",padding:e,gap:t,...n?{align:n}:{}});var T=[0,0,0,0];var D=[{path:["DS/Header"],where:"components",type:"COMPONENT",at:{x:0,y:0},width:1440,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:x([48,40,40,40],48,["SPACE_BETWEEN","MAX"]),properties:[{name:"Eyebrow",type:"TEXT",default:"Components"},{name:"Component name",type:"TEXT",default:"Button"},{name:"Show style",type:"BOOLEAN",default:true},{name:"Definition",type:"TEXT",default:"Short description of the component and when to use it."}],paint:"fill color/background; bottom stroke 1 color/border"},{path:["DS/Header","Glow"],where:"components",type:"FRAME",at:{x:0,y:0},width:1440,height:193,paint:"no fill; absolute, not clipping; two radial ellipses, named and placed under the table"},{path:["DS/Header","Title block"],where:"components",type:"FRAME",sizing:{horizontal:"HUG",vertical:"HUG"},layout:I(T,12)},{path:["DS/Header","Title block","Eyebrow"],where:"components",type:"TEXT",font:{size:14,lineHeight:20,weight:"Regular"},text:"Components",paint:"color/muted-foreground"},{path:["DS/Header","Title block","Title"],where:"components",type:"TEXT",font:{size:36,lineHeight:40,weight:"ExtraBold"},text:"Button",paint:"color/foreground; tracking -2.5%"},{path:["DS/Header","Title block","Badges"],where:"components",type:"FRAME",sizing:{horizontal:"HUG",vertical:"HUG"},layout:x(T,8),paint:"no fill; holds one instance of the library's Badge, secondary, once it exists"},{path:["DS/Header","Description"],where:"components",type:"TEXT",width:480,font:{size:16,lineHeight:28,weight:"Regular"},text:"Short description of the component and when to use it.",paint:"color/muted-foreground"},{path:["DS/Section Heading"],where:"components",type:"COMPONENT",at:{x:0,y:273},width:1200,height:81,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:I(T,8),properties:[{name:"Title",type:"TEXT",default:"Section title"},{name:"Description",type:"TEXT",default:"Section description."},{name:"Show description",type:"BOOLEAN",default:true}],paint:"no fill"},{path:["DS/Section Heading","h2"],where:"components",type:"FRAME",width:1200,height:45,sizing:{horizontal:"FILL",vertical:"HUG"},layout:I([0,0,8,0],0),paint:"bottom stroke 1 color/border, counted in the layout"},{path:["DS/Section Heading","h2","Title"],where:"components",type:"TEXT",font:{size:30,lineHeight:36,weight:"SemiBold"},text:"Section title",paint:"color/foreground; tracking -2.5%"},{path:["DS/Section Heading","Description"],where:"components",type:"TEXT",width:1200,sizing:{horizontal:"FILL"},font:{size:16,lineHeight:28,weight:"Regular"},text:"Section description.",paint:"color/muted-foreground; visible bound to Show description"},{path:["DS/Table Head"],where:"components",type:"COMPONENT",at:{x:0,y:418},width:200,height:40,sizing:{horizontal:"FIXED",vertical:"FIXED"},layout:I([0,8,0,8],0,["CENTER","MIN"]),properties:[{name:"Text",type:"TEXT",default:"Head"}],paint:"no fill"},{path:["DS/Table Head","Text"],where:"components",type:"TEXT",sizing:{horizontal:"FILL"},font:{size:14,lineHeight:20,weight:"Medium"},text:"Head",paint:"color/foreground"},{path:["DS/Table Cell"],where:"components",type:"COMPONENT_SET",at:{x:0,y:522},width:500,height:84,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:{mode:"HORIZONTAL",padding:[24,24,24,24],gap:24,crossGap:24,wrap:true},properties:[{name:"Text",type:"TEXT",default:"Cell"},{name:"Emphasis",type:"VARIANT",default:"primary"}],paint:"radius 5; the dashed border Figma gives a set"},...["primary","muted"].flatMap((e,t)=>[{path:["DS/Table Cell",`Emphasis=${e}`],where:"components",type:"COMPONENT",at:{x:24+t*224,y:24},width:200,height:36,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:I([8,8,8,8],0),paint:"no fill"},{path:["DS/Table Cell",`Emphasis=${e}`,"Text"],where:"components",type:"TEXT",sizing:{horizontal:"FILL"},font:{size:14,lineHeight:20,weight:e==="primary"?"Medium":"Regular"},text:"Cell",paint:e==="primary"?"color/foreground":"color/muted-foreground"}]),{path:["DS/List Item"],where:"components",type:"COMPONENT",at:{x:0,y:812},width:1176,height:28,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:x(T,10),properties:[{name:"Text",type:"TEXT",default:"List item text."}],paint:"no fill"},{path:["DS/List Item","Bullet"],where:"components",type:"TEXT",sizing:{horizontal:"HUG"},font:{size:16,lineHeight:28,weight:"Regular"},text:"•",paint:"color/foreground"},{path:["DS/List Item","Text"],where:"components",type:"TEXT",sizing:{horizontal:"FILL"},font:{size:16,lineHeight:28,weight:"Regular"},text:"List item text.",paint:"color/foreground"},{path:["DS/Matrix Head"],where:"components",type:"COMPONENT",at:{x:0,y:988},width:120,height:40,sizing:{horizontal:"FIXED",vertical:"FIXED"},layout:I([0,8,0,8],0,["CENTER","CENTER"]),properties:[{name:"Text",type:"TEXT",default:"Prop=value"}],paint:"no fill"},{path:["DS/Matrix Head","Text"],where:"components",type:"TEXT",sizing:{horizontal:"HUG"},font:{size:12,lineHeight:16,weight:"Medium"},text:"Prop=value",paint:"color/muted-foreground"},{path:["*"],where:"view",type:"FRAME",width:1440,layout:I(T,0),paint:"fill color/background"},{path:["*","*"],where:"view",type:"INSTANCE",main:"DS/Header",width:1440},{path:["*","Body"],where:"view",type:"FRAME",width:1440,layout:I([48,120,96,120],64),paint:"no fill"},{path:["*","Body","*"],where:"view",type:"FRAME",width:1200,layout:I(T,24),paint:"no fill"},{path:["*","Body","*","Heading"],where:"view",type:"INSTANCE",main:"DS/Section Heading",width:1200},{path:["*","Body","Component","Preview"],where:"view",type:"FRAME",width:1200,layout:[x(T,24),I(T,40)],paint:"fill color/background, radius 14, no stroke; vertical for a set of text styles"},{path:["*","Body","Matrix","Matrix"],where:"view",type:"FRAME",width:1200,layout:I(T,0),paint:"stroke 1 color/border, radius 8"},{path:["*","Body","Matrix","Matrix","TableHeader"],where:"view",type:"FRAME",height:40,layout:x(T,0)},{path:["*","Body","Example","Preview"],where:"view",type:"FRAME",width:1200,layout:{mode:"HORIZONTAL",padding:[40,40,40,40],gap:48,crossGap:24,wrap:true},paint:"fill color/background, stroke 1 color/border, radius 14"},...["Variants","Sizes","Composition"].flatMap(e=>[{path:["*","Body",e,"Preview"],where:"view",type:"FRAME",width:1200,layout:x([40,40,40,40],24,["CENTER","CENTER"]),paint:"fill color/background, stroke 1 color/border, radius 14"},{path:["*","Body",e,"Preview",e],where:"view",type:"FRAME",sizing:{horizontal:"HUG",vertical:"HUG"},layout:{mode:"HORIZONTAL",padding:T,gap:12,crossGap:12,wrap:true,align:["MIN","CENTER"]},paint:"centred in the preview, hugging its row of instances"}]),{path:["*","Body","Anatomy","Anatomy layout"],where:"view",type:"FRAME",width:1200,layout:x(T,16)},{path:["*","Body","Anatomy","Anatomy layout","Preview"],where:"view",type:"FRAME",width:744,sizing:{horizontal:"FILL",vertical:"FILL"},layout:x([24,24,24,24],24,["CENTER","CENTER"]),paint:"fill color/background, stroke 1 color/border, radius 14"},{path:["*","Body","Anatomy","Anatomy layout","Cards"],where:"view",type:"FRAME",width:440,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:{mode:"GRID",padding:T,gap:16,crossGap:16},paint:"one column, one Card per part"},{path:["*","Body","*","Table"],where:"view",type:"FRAME",width:1200,layout:I(T,0),paint:"stroke 1 color/border, radius 8"},{path:["*","Body","*","Table","TableHeader"],where:"view",type:"FRAME",height:40,layout:x(T,0),paint:"bottom stroke 1 color/border"},{path:["*","Body","*","Table","TableRow"],where:"view",type:"FRAME",layout:x(T,0),paint:"bottom stroke 1 color/border, none on the last"},{path:["*","Body","*","Table","TableRow","TableCell"],where:"view",type:"FRAME",layout:[I([8,8,8,8],0,["CENTER","CENTER"]),x([12,8,12,8],0,["MIN","CENTER"])],paint:"a foundation's preview cell, its column's width: vertical for a colour swatch, fill color/background, following the page's mode; horizontal for a spacing bar or a radius square, no fill"},{path:["*","Body","*","List"],where:"view",type:"FRAME",width:1200,layout:I([0,0,0,24],8)},{path:["*","Body","*","List","li"],where:"view",type:"INSTANCE",main:"DS/List Item",width:1176},{path:["*","Body","*","Cards"],where:"view",type:"FRAME",width:1200,layout:{mode:"GRID",padding:T,gap:16,crossGap:16}},{path:["*","Body","*","Cards","Card"],where:"view",type:"INSTANCE",width:592,paint:"the library's Card"},{path:["*","Body","Preview","Theme Preview"],where:"view",type:"FRAME",width:1200,layout:x(T,16)},{path:["*","Body","Preview","Theme Preview","Preview"],where:"view",type:"FRAME",layout:I([40,40,40,40],20),paint:"fill color/background, stroke 1 color/border, radius 14; no mode of its own"}];var Be="Icon";var Xe=["Color","Spacing","Radius"];var U="DS/Header";var ie="Body";var ce="Preview";var R=e=>({name:e,required:true});var M=e=>({name:e});var re={key:"table",label:"the table shape",sections:[R("Example"),M("Properties"),M("Specs"),R("Usage"),R("Accessibility"),R(ce)]};var je={icons:{kind:"icons",noun:"icon set's view",pages:["icon set"],frame:()=>"Icons",eyebrow:"Foundations",eyebrowOwner:"the icon set's view's",badge:{counts:"48 icons, lucide-react"},badgeOwner:"the icon set's view's",shapes:[{label:"the icon set's view",sections:[{name:"Icons section",required:true,repeats:true}]}]},foundation:{kind:"foundation",noun:"foundation view",pages:["foundation"],frame:e=>e,eyebrow:"Foundations",eyebrowOwner:"a foundation's",badge:{counts:"31 tokens, Light and Dark"},badgeOwner:"a foundation view's",shapes:null},foundationGuidance:{kind:"foundationGuidance",noun:"foundation's guidance view",pages:["foundation","icon set"],frame:e=>`${e} / Guidance`,eyebrow:"Foundations",eyebrowOwner:"a foundation's",badge:{reads:"Guidance"},badgeOwner:"a guidance view's",shapes:[re]},component:{kind:"component",noun:"component view",pages:["entry"],frame:e=>e,eyebrow:"Components",eyebrowOwner:"an entry's",badge:{counts:"192 variants"},badgeOwner:"a component view's",shapes:[{label:"a component view",sections:[R("Component"),M("Matrix")]}]},guidance:{kind:"guidance",noun:"guidance view",pages:["entry"],frame:e=>`${e} / Guidance`,eyebrow:"Components",eyebrowOwner:"an entry's",badge:{reads:"Guidance"},badgeOwner:"a guidance view's",shapes:[re,{key:"parts",label:"the parts shape",sections:[M("Anatomy"),M("Variants"),M("Sizes"),M("Composition"),M("Properties"),R("Usage"),M("Behavior & content"),R("Accessibility"),R(ce)]}]}};var Ue=/^[0-9][0-9,.]*\s+\S/;function Ve(e){if(e===Be)return"icon set";return Xe.includes(e)?"foundation":"entry"}function se(e,t){if(!e.startsWith(z))return null;const n=e.slice(z.length);const o=Ve(n);return Object.values(je).find(r=>r.pages.includes(o)&&r.frame(n)===t)??null}var ae=e=>e.sections.map(t=>t.name).join(", ");function Ye(e,t,n){const o=[];const r=l=>t.some(d=>d.sections.some(y=>y.name===l));for(const l of n.filter((d,y)=>!r(d)&&n.indexOf(d)===y)){const d=t.length===1?ae(t[0]):`those of ${t.map(y=>`${y.label} (${ae(y)})`).join(" or of ")}`;o.push(`holds ${l}, which no ${e.noun} holds; its sections are ${d}`)}const a=n.filter(r);const c=l=>t.filter(d=>d.sections.some(y=>y.name===l));const w=a.find(l=>c(l).length===1);const f=(w?c(w)[0]:void 0)??t.find(l=>l.sections.every(d=>!d.required||a.includes(d.name)))??t[0];const h=f.sections.map(l=>l.name);let i=-1;let s="";for(const l of a){const d=h.indexOf(l);if(d===-1){o.push(`holds ${l}, a section of ${c(l)[0]?.label}, beside ${w} of ${f.label}`);continue}const y=d===i&&f.sections[d]?.repeats===true;if(d<i||d===i&&!y)o.push(`holds ${l} after ${s}; ${f.label} orders them ${h.join(", ")}`);else{i=d;s=l}}for(const l of f.sections)if(l.required&&!a.includes(l.name))o.push(`holds no ${l.name}, which ${f.label} always holds`);return o}function le(e,t,n=[]){const o=n.length>1;const r=[];const a=h=>e.filter(i=>i.parentId===h);const c=h=>{const i=[h];if(h.type!=="INSTANCE")for(const s of a(h.id))i.push(...c(s));return i};const w=(h,i)=>{for(let s=t.get(h.parentId??"");s;s=t.get(s.parentId??""))if(s===i)return true;return false};const f=(h,i)=>{const s=[];for(let l=i;l&&l!==h;l=t.get(l.parentId??""))s.unshift(l.name);return[h.name,...s].join(" / ")};for(const h of e){if(h.type!=="FRAME"||!h.page||h.parentId!==h.page.id)continue;const[i="",...s]=h.name.split(" / ");const l=o&&s.length>0&&se(h.page.name,s.join(" / "))!==null;const d=se(h.page.name,l?s.join(" / "):h.name);if(!d)continue;const y=(b,G,K=h)=>{r.push({nodeId:K.id,field:b,message:`${f(h,K)}: ${G}`})};if(l&&!n.includes(i))y("branch",`opens with ${i}, which is not a branch this file holds (${n.join(", ")})`);const g=d.kind==="component"||e.some(b=>(b.type==="COMPONENT"||b.type==="COMPONENT_SET")&&w(b,h));if(o&&!l&&g)y("branch",`names no branch; in a file holding ${n.join(" and ")}, a view drawing a component opens with its branch, as ${n[0]} / ${h.name}`);const p=a(h.id);const m=p[0];if(m&&(m.type!=="INSTANCE"||m.main!==U))y("header",`opens on ${m.name}, and a view opens on a ${U} instance`);const E=p.find(b=>b.type==="INSTANCE"&&b.main===U);const A=E?.values;if(E&&A){const b=A["Eyebrow"];if(b!==void 0&&b!==d.eyebrow)y("eyebrow",`the eyebrow reads "${String(b)}", and ${d.eyebrowOwner} reads "${d.eyebrow}"`);if(A["Show style"]===false)y("show style","the header's Show style is off, and a view's header shows its badge")}const N=E?e.find(b=>b.type==="INSTANCE"&&t.get(b.parentId??"")?.name==="Badges"&&w(b,E)):void 0;const $=N?.values?.["Label"];if(typeof $==="string"){const b=d.badge;if("reads"in b&&$!==b.reads)y("badge",`the badge reads "${$}", and ${d.badgeOwner} reads "${b.reads}"`);if("counts"in b&&!Ue.test($))y("badge",`the badge reads "${$}", and ${d.badgeOwner} counts what it shows ("${b.counts}")`)}const F=p.find(b=>b.type==="FRAME"&&b.name===ie);if(!F){y("sections",`holds no ${ie}, the frame its sections stand in`);continue}const S=a(F.id).filter(b=>b.type==="FRAME");if(d.shapes)for(const b of Ye(d,d.shapes,S.map(G=>G.name)))y("sections",b);for(const b of p.flatMap(c))if(b.modes&&Object.keys(b.modes).length>0)y("mode","sets a variable mode of its own; switch the mode on the page or the view instead",b)}return r}var C=.5;function Ke(e,t){const n=e.page;if(!n)return null;const o=n.name===j?"components":n.name.startsWith(z)?"view":null;if(o===null)return null;const r=[];for(let a=e;a;a=a.parentId?t.get(a.parentId):void 0){r.unshift(a.name);if(a.parentId===n.id){if(o==="view"&&a.type!=="FRAME")return null;return{node:e,path:r,where:o}}}return null}var de=e=>e.path.filter(t=>t!=="*").length;function We(e){const t=D.filter(n=>{if(n.where!==e.where||n.path.length!==e.path.length)return false;if(!n.path.every((r,a)=>r==="*"||r===e.path[a]))return false;const o=n.main!==void 0&&n.path.at(-1)==="*";return!o||e.node.main===n.main});return t.sort((n,o)=>de(o)-de(n))[0]??null}var pe=e=>e.replace(/\s+/g,"").toLowerCase();var k=(e,t)=>Math.abs(e-t)<=C;var ue=e=>e.join(" ");function qe(e,t){const n=[];if(e.layout!==t.mode)n.push(`layout ${e.layout}, not ${t.mode}`);if(!e.padding.every((o,r)=>k(o,t.padding[r]??0)))n.push(`padding ${ue(e.padding)}, not ${ue(t.padding)}`);if(!k(e.gap,t.gap))n.push(`gap ${e.gap}, not ${t.gap}`);if(t.crossGap!==void 0&&!k(e.crossGap,t.crossGap))n.push(`row gap ${e.crossGap}, not ${t.crossGap}`);if(t.wrap!==void 0&&e.wrap!==t.wrap)n.push(t.wrap?"does not wrap, and it wraps":"wraps, and it does not");if(t.align&&(e.align[0]!==t.align[0]||e.align[1]!==t.align[1]))n.push(`aligns ${e.align.join(" ")}, not ${t.align.join(" ")}`);return n}function Ze(e,t,n){const o=[];const r=(c,w)=>{o.push({nodeId:e.id,field:c,message:`${n}: ${w}`})};if(e.type!==t.type)r("type",`is a ${e.type}, and the documentation draws a ${t.type}`);if(t.main!==void 0&&t.path.at(-1)!=="*"&&e.main!==void 0&&e.main!==t.main)r("main",`is an instance of ${e.main??"no component"}, not of ${t.main}`);const a=e.box;if(a){if(t.at&&(!k(a.x,t.at.x)||!k(a.y,t.at.y)))r("at",`sits at ${a.x}, ${a.y}, not ${t.at.x}, ${t.at.y}`);if(t.width!==void 0&&!k(a.width,t.width))r("width",`is ${a.width} wide, not ${t.width}`);if(t.height!==void 0&&!k(a.height,t.height))r("height",`is ${a.height} high, not ${t.height}`);for(const c of["horizontal","vertical"]){const w=t.sizing?.[c];if(w!==void 0&&a.sizing[c]!==w)r(`sizing.${c}`,`sizes ${a.sizing[c]} ${c}ly, not ${w}`)}if(t.layout){const c=Array.isArray(t.layout)?t.layout:[t.layout];const w=c.map(h=>qe(a,h));const f=[...w].sort((h,i)=>h.length-i.length)[0]??[];if(f.length>0)r("layout",f.join("; "))}}if(t.font&&e.font){const{size:c,lineHeight:w,style:f}=e.font;if(c!==t.font.size||w!==t.font.lineHeight)r("font",`is set ${c} / ${w}, not ${t.font.size} / ${t.font.lineHeight}`);if(pe(f)!==pe(t.font.weight))r("weight",`is ${f}, not ${t.font.weight}`)}if(t.text!==void 0&&e.characters!==void 0&&e.characters!==t.text)r("text",`reads "${e.characters}", not "${t.text}"`);if(t.properties&&e.properties){const c=e.properties.map(f=>`${f.name} ${f.type} ${String(f.default)}`).sort();const w=t.properties.map(f=>`${f.name} ${f.type} ${String(f.default)}`).sort();if(c.join("|")!==w.join("|"))r("properties",`has the properties [${c.join(", ")}], not [${w.join(", ")}]`)}return o}function fe(e,t=[]){const n=new Map(e.map(c=>[c.id,c]));const o=[];const r=e.map(c=>Ke(c,n)).filter(c=>c!==null);const a=new Map;for(const c of r){const w=We(c);const f=c.path.join(" / ");if(c.where==="components"&&c.path.length===1){a.set(c.node.name,[...a.get(c.node.name)??[],c.node]);if(!w&&(c.node.type==="COMPONENT"||c.node.type==="COMPONENT_SET"))o.push({nodeId:c.node.id,field:"name",message:`${f}: is not one of the documentation components`})}if(w)o.push(...Ze(c.node,w,f))}for(const[c,w]of a){for(const f of w.slice(1))o.push({nodeId:f.id,field:"name",message:`${c}: a second component of that name`})}for(const c of r){if(c.where!=="components"||c.path.length!==1)continue;const w=e.filter(f=>f.parentId===c.node.id);if(w.length===0)continue;for(const f of D){if(f.where!=="components"||f.path[0]!==c.node.name||f.path.length<2)continue;const h=r.some(i=>i.path.length===f.path.length&&i.path.every((s,l)=>s===f.path[l]));if(!h)o.push({nodeId:c.node.id,field:"layers",message:`${c.node.name}: holds no ${f.path.slice(1).join(" / ")}`})}}o.push(...le(e,n,t));o.push(...Je(e,n));return o}function Je(e,t){const n=new Map;const o=s=>{const l=n.get(s.id);if(l)return l;const d=t.get(s.parentId??"");if(!s.box||!d||d.type==="INSTANCE")return null;let y=s.box.x;let g=s.box.y;let p;let m=[];if(d.parentId===s.page?.id){if(d.name!==O.frame||s.name===O.bleeds)return null;p=[d.name,s.name]}else{const N=o(d);if(!N)return null;y+=N.x;g+=N.y;p=[...N.path,s.name];m=[N,...N.above]}const E=s.type==="INSTANCE"||!e.some(N=>N.parentId===s.id);const A={node:s,x:y,y:g,right:y+s.box.width,bottom:g+s.box.height,path:p,block:E,above:m};n.set(s.id,A);return A};for(const s of e)if(s.page?.name===O.page)o(s);const r=[...n.values()];const a=r.filter(s=>s.block);const c=s=>s-O.width;const w=s=>a.some(l=>Math.abs(l.x-s.x)<=C&&c(l.right)>C&&c(l.right)>=O.bleed*(l.node.box?.width??0));const f=[];const h=(s,l,d)=>{f.push({nodeId:s.node.id,field:l,message:`${s.path.join(" / ")}: ${d}`})};const i=s=>[["left",-s.x],["top",-s.y],["bottom",s.bottom-O.height]].filter(([,l])=>l>C).map(([l,d])=>`reaches ${Math.round(d)} past the cover's ${l} edge`);for(const s of r){const l=i(s);if(l.length>0&&!s.above.some(m=>i(m).length>0))h(s,"bounds",`${l.join(", ")}, which cuts it off`);const d=c(s.right);if(s.block){if(w(s))continue;const m=Math.round(s.node.box?.width??0);if(d>C)h(s,"bounds",`crosses the cover's right edge by ${Math.round(d)} of its ${m}; bleed a quarter of its width past it, or end it ${O.margin} inside`);else if(c(s.right+O.margin)>C)h(s,"bounds",`ends ${Math.round(-d)} inside the cover's right edge, within its ${O.margin} margin`);continue}if(d<=C)continue;const y=r.filter(m=>m.above.includes(s));const g=y.filter(m=>m.block&&c(m.right)>C&&w(m));const p=Math.max(O.width,...g.map(m=>m.right));if(s.right<=p+C)continue;if(y.some(m=>Math.abs(m.right-s.right)<=C))continue;h(s,"bounds",g.length>0?`reaches ${Math.round(s.right-p)} past the layers that bleed from it at the cover's right edge`:`reaches ${Math.round(d)} past the cover's right edge, and nothing in it bleeds`)}return f}var he=new Set(D.filter(e=>e.where==="components"&&e.path.length===1).map(e=>e.path[0]??""));function ge(e){if(e.type!=="TEXT"||e.characters===void 0)return false;if(e.page?.name!==j)return false;return D.some(t=>t.where==="components"&&t.type==="TEXT"&&t.text===e.characters&&t.path[0]===e.frame&&t.path.at(-1)===e.name)}var Qe={FRAME:["Frame"],GROUP:["Group"],SECTION:["Section"],COMPONENT:["Component"],COMPONENT_SET:["Component"],RECTANGLE:["Rectangle"],ELLIPSE:["Ellipse"],LINE:["Line"],POLYGON:["Polygon"],STAR:["Star"],VECTOR:["Vector"],SLICE:["Slice"],BOOLEAN_OPERATION:["Union","Subtract","Intersect","Exclude"]};function me(e,t){const n=/^(.+?)(?: \d+)?$/.exec(t);return n!==null&&(Qe[e]??[]).includes(n[1]??"")}var ye="❖ ";var et=new Set(["Thumbnail","Component for Docs"]);var P=.01;var tt=["data-entry","navigation","feedback","data-display","layout","general"];var nt=new RegExp(`^(${tt.join("|")}) / .+$`);var ot="_components";function it(e){const t=e.page?.name;if(t===void 0)return false;if(et.has(t))return true;if(e.componentSource!==false)return false;return t.startsWith(ye)||nt.test(t)||e.frame===ot}var we=(e,t)=>e.map(n=>n.variable??"").join()===t.map(n=>n.variable??"").join();function rt(e,t){const n=Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x);const o=Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y);return n>P&&o>P}function st(e){const t=e.box;if(e.type!=="FRAME"||!t||t.children!==0)return false;if(e.fills.length>0||e.strokes.length>0)return false;return t.width>1&&t.height>1}function at(e,t,n){return e.x<-P||e.y<-P||e.x+e.width>t+P||e.y+e.height>n+P}function V(e,t=W,n={}){const o=oe(t,e.flatMap(i=>i.main&&he.has(i.main)?[]:i.instance?.carried??[]));const r=[];const a=new Map(e.map(i=>[i.id,i]));const c=i=>{for(let s=a.get(a.get(i)?.parentId??"");s;s=a.get(s.parentId??"")){const l=s.type==="INSTANCE"?s.mainId:void 0;if(!l)continue;for(let d=a.get(s.parentId??"");d;d=a.get(d.parentId??""))if(d.swaps?.includes(l))return true}return false};const w=new Set(e.flatMap(i=>i.instance?.overrides.map(s=>s.nodeId)??[]));const f=i=>{if(i.page?.name!==O.page)return false;for(let s=a.get(i.parentId??"");s;s=a.get(s.parentId??""))if(s.name===O.logo)return true;return false};for(const i of e){const s=`${i.name} (${i.type.toLowerCase()})`;const l=(g,p,m,E=i.id)=>{r.push({check:g,nodeId:E,...p?{field:p}:{},...i.frame?{frame:i.frame}:{},message:m})};const d=it(i);const y=f(i);if(!y&&i.fills.some(g=>!g.bound))l("binding","fill",`${s}: fill is a raw value`);if(!y&&i.strokes.some(g=>!g.bound))l("binding","stroke",`${s}: stroke is a raw value`);if(i.type==="TEXT"&&i.textStyleId===null&&!d)l("binding","textStyle",`${s}: text has no library text style`);for(const g of d?[]:i.spacing){if(g.value>0&&!g.bound)l("binding",g.field,`${s}: ${g.field} ${g.value} is not a spacing variable`)}if((i.type==="COMPONENT"||i.type==="COMPONENT_SET")&&i.page?.name.startsWith(ye)&&i.parentId===i.page.id)l("placement",void 0,`${s}: sits on the page, outside its entry's component view`);if(i.set){const{width:g,height:p,variants:m}=i.set;m.forEach((E,A)=>{for(const N of m.slice(A+1)){if(rt(E,N))l("overlap",void 0,`${i.name}: ${E.name} overlaps ${N.name}`,E.id)}if(at(E,g,p))l("overlap",void 0,`${i.name}: ${E.name} reaches past the set, which cuts it off`,E.id)})}if(i.characters!==void 0&&!ge(i)){for(const g of X(i.characters,o))l("copy",g.field,`${s}: ${g.message}`)}if(i.instance){for(const g of i.instance.overrides){if(g.characters!==void 0){for(const p of X(g.characters,o))l("copy",p.field,`${i.name}: ${p.message}`,g.nodeId)}for(const p of g.fields){if(q.has(p))continue;if(p==="fills"&&g.picture)continue;const m=g.nodeId===i.id;if(!m&&(p==="fills"||p==="strokes")&&i.componentSource===true)continue;if(!m&&(p==="fills"||p==="strokes")&&c(g.nodeId))continue;const E=a.get(g.nodeId);if(!m&&(p==="fills"||p==="strokes")&&E?.source){if(we(E[p],E.source[p]))continue}if(m&&(p==="width"||p==="height")&&d)continue;if(m&&(p==="width"||p==="height")&&i.componentSource===true)continue;if(m&&p==="width"&&i.instance.sizing.horizontal!=="FIXED")continue;if(m&&p==="height"&&i.instance.sizing.vertical!=="FIXED")continue;if(m&&Z.has(p)&&Q(i.instance.sizing))continue;if(m&&J(p,i.box,i.instance.main))continue;l("overrides",p,`${p} overridden inside an instance of ${i.name}`,g.nodeId)}}}if(st(i))l("empty",void 0,`${i.name}: an empty frame ${Math.round(i.box?.width??0)}x${Math.round(i.box?.height??0)} that shows nothing; it holds no layer, so remove it or put in what it was made for`);if(me(i.type,i.name))l("naming",void 0,`${i.name} keeps a default name`);if(i.source){const g=["fills","strokes"].filter(p=>!we(i[p],i.source?.[p]??[]));if(g.length>0&&!w.has(i.id))l("binding",g[0]==="fills"?"fill":"stroke",`${s}: paints with another colour than the same layer in its component (${(i.source[g[0]??"fills"]??[]).map(p=>p.variable??"raw").join(", ")}), which an icon swap dropped`)}}const h=new Map(e.map(i=>[i.id,i.frame]));for(const{nodeId:i,field:s,message:l}of fe(e,n.branches)){const d=h.get(i);r.push({check:"documentation",nodeId:i,field:s,...d?{frame:d}:{},message:l})}return r}var H=18e3;function be(e){return encodeURIComponent(JSON.stringify(e)).replace(/%[0-9A-F]{2}/g,"x").length}function Y(e,t,n=H){const o={};for(const c of t)o[c.check]=(o[c.check]??0)+1;const r={checked:e,total:t.length,counts:o,findings:[],cut:false};let a=be(r);for(const c of t){a+=be(c)+1;if(a>n){r.cut=true;break}r.findings.push(c)}return r}function u(e,t){try{return e[t]}catch{return void 0}}var ct=["paddingTop","paddingRight","paddingBottom","paddingLeft","itemSpacing"];function _(e){if(!Array.isArray(e))return[];return e.filter(t=>t.type==="SOLID"&&t.visible!==false&&(t.opacity??1)>0).map(t=>{const n=t.boundVariables?.color?.id;return{bound:Boolean(t.boundVariables?.color),...typeof n==="string"?{variable:n}:{}}})}function Ee(e,t){if(e.id===t)return e;const n=u(e,"findOne");return n?n.call(e,o=>o.id===t):null}function Te(e,t){const n=t.get(e.id);if(n)return n;const o=e.parent??null;const r=o?Te(o,t):null;const a={frame:o?.type==="PAGE"?e.name:r?.frame??null,page:e.type==="PAGE"?{id:e.id,name:e.name}:r?.page??null,componentSource:e.type==="COMPONENT"||e.type==="COMPONENT_SET"||(r?.componentSource??false),insideInstance:o?.type==="INSTANCE"||(r?.insideInstance??false)};t.set(e.id,a);return a}var lt=new Set(["VECTOR","BOOLEAN_OPERATION","ELLIPSE","RECTANGLE","LINE","STAR","POLYGON"]);function dt(e){if(!e.startsWith("I"))return null;const t=e.slice(1).split(";").slice(1);if(t.length===0)return null;return t.length===1?t[0]??null:`I${t.join(";")}`}function pt(e){const t=u(e,"children")??[];return{width:Number(u(e,"width")??0),height:Number(u(e,"height")??0),variants:t.map(({id:n,name:o,x:r,y:a,width:c,height:w})=>({id:n,name:o,x:r,y:a,width:c,height:w}))}}function ut(e,t){const n=u(e,"findAll");if(!n)return[];return n.call(e,o=>o.type==="TEXT"&&!t.has(o.id)).map(o=>typeof o.characters==="string"?o.characters:"")}function ft(e){const t=e?u(e,"fills"):void 0;return Array.isArray(t)&&t.some(n=>n.type==="IMAGE")}var ht=new Set(["FRAME","COMPONENT","COMPONENT_SET","INSTANCE","TEXT"]);var v=e=>typeof e==="number"?e:0;function gt(e){const t=u(e,"layoutMode");const n=typeof t==="string"?t:"NONE";const o=u(e,"children");const r=n==="GRID";return{x:v(u(e,"x")),y:v(u(e,"y")),width:v(u(e,"width")),height:v(u(e,"height")),sizing:{horizontal:String(u(e,"layoutSizingHorizontal")??"FIXED"),vertical:String(u(e,"layoutSizingVertical")??"FIXED")},layout:n,wrap:u(e,"layoutWrap")==="WRAP",padding:[v(u(e,"paddingTop")),v(u(e,"paddingRight")),v(u(e,"paddingBottom")),v(u(e,"paddingLeft"))],gap:r?v(u(e,"gridColumnGap")):v(u(e,"itemSpacing")),crossGap:r?v(u(e,"gridRowGap")):v(u(e,"counterAxisSpacing")),align:[String(u(e,"primaryAxisAlignItems")??"MIN"),String(u(e,"counterAxisAlignItems")??"MIN")],children:Array.isArray(o)?o.length:0}}function mt(e,t){const n=u(e,"fontSize");const o=u(e,"lineHeight");const r=u(e,"fontName");const a=typeof n==="number"?n:0;return{size:n===t?"mixed":a,lineHeight:o===t||typeof o!=="object"?"mixed":o.unit==="AUTO"?"auto":o.unit==="PERCENT"?a*v(o.value)/100:v(o.value),style:r===t||typeof r!=="object"?"mixed":String(r.style??"")}}function wt(e){if(e.type!=="COMPONENT_SET"&&(e.type!=="COMPONENT"||e.parent?.type==="COMPONENT_SET"))return void 0;const t=u(e,"componentPropertyDefinitions");if(!t)return void 0;return Object.entries(t).map(([n,{type:o,defaultValue:r}])=>({name:n.split("#")[0]??n,type:o,default:r}))}async function yt(e){const t=u(e,"getMainComponentAsync");return t?await t.call(e):null}function bt(e){if(!e)return null;return e.parent?.type==="COMPONENT_SET"?e.parent.name:e.name}function Et(e,t,n){const o=n.find(r=>r.id===e);if(!o?.overriddenFields.some(r=>r==="width"||r==="height"))return null;return typeof t?.width==="number"&&typeof t.height==="number"?{width:t.width,height:t.height}:null}function Tt(e){const t=u(e,"componentProperties");if(!t||typeof t!=="object")return[];return Object.values(t).flatMap(n=>n?.type==="INSTANCE_SWAP"&&typeof n.value==="string"?[n.value]:[])}function Nt(e){const t=u(e,"componentProperties");if(!t||typeof t!=="object")return void 0;const n={};for(const[o,r]of Object.entries(t)){const a=r?.value;if(typeof a==="string"||typeof a==="boolean")n[o.split("#")[0]??o]=a}return n}function St(e){const t=u(e,"explicitVariableModes");if(!t||typeof t!=="object")return void 0;const n=Object.entries(t).filter(o=>typeof o[1]==="string");return n.length>0?Object.fromEntries(n):void 0}async function Ne(e,t,n=typeof figma==="undefined"?Symbol("mixed"):figma.mixed,o=new Map,r=a=>figma.getNodeByIdAsync(a)){const a=e;const c=u(a,"textStyleId");const w=u(a,"boundVariables");const f=u(a,"overrides")??[];const h=new Set(f.filter(S=>S.overriddenFields.includes("characters")).map(S=>S.id));const i=e.type==="INSTANCE"?ut(e,h):[];const s=u(a,"layoutMode");const l=typeof s==="string"&&s!=="NONE";const d=Te(e,o);const y=lt.has(e.type)&&d.insideInstance&&!d.componentSource?dt(e.id):null;const g=y?await r(y):null;const p=e.type==="INSTANCE"?await yt(a):null;const m=e.type==="INSTANCE"?Et(e.id,p,f):null;const E=wt(a);const A=e.type==="INSTANCE"?Nt(e):void 0;const N=e.type==="INSTANCE"?Tt(e):[];const $=typeof p?.id==="string"?p.id:void 0;const F=St(e);return{id:e.id,name:e.name,type:e.type,parentId:a.parent?.id??null,frame:d.frame,created:t,fills:_(u(a,"fills")),strokes:_(u(a,"strokes")),textStyleId:e.type!=="TEXT"?null:c===n?"mixed":typeof c==="string"&&c?c:null,...e.type==="TEXT"&&!d.insideInstance?{characters:String(u(a,"characters")??"")}:{},instance:e.type==="INSTANCE"?{overrides:f.map(S=>({nodeId:S.id,fields:S.overriddenFields,...S.overriddenFields.includes("fills")&&ft(Ee(e,S.id))?{picture:true}:{},...h.has(S.id)?{characters:String(u(Ee(e,S.id),"characters")??"")}:{}})),...i.length>0?{carried:i}:{},sizing:{horizontal:String(u(a,"layoutSizingHorizontal")??"FIXED"),vertical:String(u(a,"layoutSizingVertical")??"FIXED")},...m?{main:m}:{}}:null,spacing:l?ct.map(S=>({field:S,value:Number(u(a,S)??0),bound:Boolean(w?.[S])})):[],...g?{source:{fills:_(u(g,"fills")),strokes:_(u(g,"strokes"))}}:{},page:d.page,componentSource:d.componentSource,...ht.has(e.type)?{box:gt(a)}:{},...e.type==="TEXT"?{font:mt(a,n)}:{},...E?{properties:E}:{},...e.type==="INSTANCE"?{main:bt(p)}:{},...$?{mainId:$}:{},...N.length>0?{swaps:N}:{},...A?{values:A}:{},...F?{modes:F}:{},...e.type==="COMPONENT_SET"?{set:pt(a)}:{}}}async function Se(e,t){if("nodeId"in t){const n=await e.getNodeByIdAsync(t.nodeId);if(!n||n.type==="PAGE"||n.type==="DOCUMENT")return[];return"findAll"in n?[n,...n.findAll()]:[n]}if(t.page!==true){const n=t.page;const o=e.root.children;const r=o.find(a=>a.id===n||a.name===n);if(!r)throw new Error(`no page ${n}; the pages are ${o.map(a=>a.name).join(", ")}`);if(r!==e.currentPage)await e.setCurrentPageAsync(r)}return e.currentPage.findAll()}async function It(e,t){const n=await Se(e,t.scope);const o=new Map;const r=await Promise.all(n.map(a=>Ne(a,false,e.mixed,o)));return Y(r.length,V(r,t.copy,{branches:t.branches??[]}))}return Ce(Ot);})();
1
+ "use strict";var zakuRulesLib=(()=>{var B=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var xe=(e,t)=>{for(var n in t)B(e,n,{get:t[n],enumerable:true})};var Ae=(e,t,n,i)=>{if(t&&typeof t==="object"||typeof t==="function"){for(let r of Oe(t))if(!ve.call(e,r)&&r!==n)B(e,r,{get:()=>t[r],enumerable:!(i=Ie(t,r))||i.enumerable})}return e};var Ce=e=>Ae(B({},"__esModule",{value:true}),e);var Ot={};xe(Ot,{REPLY_BYTES:()=>H,scopeNodes:()=>Se,zakuRules:()=>It});var W={locales:["en"],currencies:[]};var q=new Set(["characters","name","componentProperties","componentPropertyReferences","exposedInstances","reactions","transitionNodeID","transitionDuration","transitionEasing"]);var Z=new Set(["primaryAxisSizingMode","counterAxisSizingMode"]);function J(e,t,n){if(!t||!n||e!=="width"&&e!=="height")return false;return Math.abs(t[e]-n[e])<.5}function Q(e){return e.horizontal!=="FIXED"||e.vertical!=="FIXED"}var ee="['’]";var te=[{pattern:/\bdelv(?:e|es|ed|ing)\b/iu,instead:'write "look at" or "read"'},{pattern:/\bleverag(?:e|es|ed|ing)\b/iu,instead:'write "use"'},{pattern:/\butili[sz](?:e|es|ed|ing|ation)\b/iu,instead:'write "use"'},{pattern:/\brobust(?:ly|ness)?\b/iu,instead:"write what it withstands"},{pattern:/\btapestr(?:y|ies)\b/iu,instead:'write "mix", or name the parts'},{pattern:/\btestaments?\b/iu,instead:'write "proof", or the fact itself'},{pattern:/\bvibrant(?:ly)?\b/iu,instead:'write "busy", or what is there'},{pattern:/\bempower(?:s|ed|ing|ment)?\b/iu,instead:'write "let" or "allow"'},{pattern:/\bunlock(?:s|ed|ing)?\b/iu,instead:'write "get" or "open"'},{pattern:/\bunleash(?:es|ed|ing)?\b/iu,instead:'write "use" or "start"'},{pattern:/\bgame[- ]?changers?\b/iu,instead:"write what it changes"},{pattern:/\bsupercharg(?:e|es|ed|ing)\b/iu,instead:'write "speed up", with the figure'},{pattern:new RegExp(`\\blet${ee}s\\b`,"iu"),instead:'write the action itself, such as "Plan a trip"'},{pattern:new RegExp(`\\b(?:it${ee}s|it is) (?:important|worth|crucial) (?:to note|noting)\\b`,"iu"),instead:"delete it"},{pattern:/\bin order to\b/iu,instead:'write "to"'},{pattern:/\bnot (?:just|only|merely)\b[^.!?]{0,80}?\bbut\b/iu,instead:"write the second half on its own"}];var ne={en:te};var Me=/^[\x20-\x7e]$/;var $e=new RegExp(`^[${String.fromCharCode(10,8232)}]$`);var Re=/^[\p{L}\p{M}]$/u;var ke=/^(?=\p{M})\p{Script=Inherited}$/u;var Pe=/^\p{Extended_Pictographic}$/u;var Fe=new RegExp("^[←-⇿⟰-⟿⤀-⥿⬀-⬑]$","u");var ze=new Map([["—",{name:"em dash",instead:'write "-", or two sentences'}],["–",{name:"en dash",instead:'write "-", or two sentences'}],["‘",{name:"left single quotation mark",instead:"write '"}],["’",{name:"right single quotation mark",instead:"write '"}],["“",{name:"left double quotation mark",instead:'write "'}],["”",{name:"right double quotation mark",instead:'write "'}],["…",{name:"horizontal ellipsis",instead:'write "..."'}],["·",{name:"middle dot",instead:'write "-", "," or ":"'}],["•",{name:"bullet",instead:'write "-", "," or ":"'}],["→",{name:"rightwards arrow",instead:'write "->"'}],["←",{name:"leftwards arrow",instead:'write "<-"'}],["×",{name:"multiplication sign",instead:'write "x"'}],[String.fromCharCode(160),{name:"no-break space",instead:"write a space"}],[String.fromCharCode(8203),{name:"zero width space",instead:"write nothing"}],[String.fromCharCode(8204),{name:"zero width non-joiner",instead:"write nothing"}],[String.fromCharCode(8205),{name:"zero width joiner",instead:"write nothing"}],[String.fromCharCode(65279),{name:"zero width no-break space",instead:"write nothing"}]]);var De={Jpan:["Han","Hiragana","Katakana"],Kore:["Hangul","Han"],Hans:["Han"],Hant:["Han"],Hanb:["Han","Bopomofo"]};function Le(e,t){return e.flatMap(n=>["symbol","narrowSymbol"].flatMap(i=>new Intl.NumberFormat(n,{style:"currency",currency:t,currencyDisplay:i}).formatToParts(0).filter(r=>r.type==="currency").map(r=>r.value)))}function He(e){const t=new Set(e.locales.flatMap(n=>{const i=new Intl.Locale(n).maximize().script??"";return De[i]??[i]}));return{scripts:[...t].filter(Boolean),symbols:[...new Set(e.currencies.flatMap(n=>Le(e.locales,n)))],languages:[...new Set(e.locales.map(n=>new Intl.Locale(n).language))]}}function ie(e,t){const n="scripts"in e?e:He(e);return{scripts:n.scripts.map(i=>new RegExp(`^\\p{Script_Extensions=${i}}$`,"u")),extra:new Set([...n.symbols,...t].flatMap(i=>[...i.normalize("NFC")])),tells:n.languages.flatMap(i=>ne[i]??[])}}function _e(e,t){if(Me.test(e)||$e.test(e)||t.extra.has(e))return true;if(!Re.test(e))return false;return ke.test(e)||t.scripts.some(n=>n.test(e))}function L(e){return`U+${(e.codePointAt(0)??0).toString(16).toUpperCase().padStart(4,"0")}`}function Ge(e){const t=ze.get(e);if(t)return`${L(e)} ${t.name}: ${t.instead}`;if(Pe.test(e))return`${L(e)} emoji: write a word, or a library icon`;if(Fe.test(e))return`${L(e)} arrow: write "->" or "<-"`;return`${L(e)} is outside the locales and currencies copy names in zaku.yaml: write it in ASCII, or add its locale or currency there`}function X(e,t){const n=[];const i=new Set;for(const r of e.normalize("NFC")){if(i.has(r)||_e(r,t))continue;i.add(r);n.push({field:"characters",message:Ge(r)})}for(const r of t.tells){const a=r.pattern.exec(e);if(a)n.push({field:"tone",message:`"${a[0]}": ${r.instead}`})}return n}var O={page:"Thumbnail",frame:"Thumbnail",width:1200,height:675,bleeds:"Glow",logo:"Logo",bleed:.25,margin:72};var z="❖ ";var j="Component for Docs";var I=(e,t,n)=>({mode:"VERTICAL",padding:e,gap:t,...n?{align:n}:{}});var x=(e,t,n)=>({mode:"HORIZONTAL",padding:e,gap:t,...n?{align:n}:{}});var T=[0,0,0,0];var D=[{path:["DS/Header"],where:"components",type:"COMPONENT",at:{x:0,y:0},width:1440,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:x([48,40,40,40],48,["SPACE_BETWEEN","MAX"]),properties:[{name:"Eyebrow",type:"TEXT",default:"Components"},{name:"Component name",type:"TEXT",default:"Button"},{name:"Show style",type:"BOOLEAN",default:true},{name:"Definition",type:"TEXT",default:"Short description of the component and when to use it."}],paint:"fill color/background; bottom stroke 1 color/border"},{path:["DS/Header","Glow"],where:"components",type:"FRAME",at:{x:0,y:0},width:1440,height:193,paint:"no fill; absolute, not clipping; two radial ellipses, named and placed under the table"},{path:["DS/Header","Title block"],where:"components",type:"FRAME",sizing:{horizontal:"HUG",vertical:"HUG"},layout:I(T,12)},{path:["DS/Header","Title block","Eyebrow"],where:"components",type:"TEXT",font:{size:14,lineHeight:20,weight:"Regular"},text:"Components",paint:"color/muted-foreground"},{path:["DS/Header","Title block","Title"],where:"components",type:"TEXT",font:{size:36,lineHeight:40,weight:"ExtraBold"},text:"Button",paint:"color/foreground; tracking -2.5%"},{path:["DS/Header","Title block","Badges"],where:"components",type:"FRAME",sizing:{horizontal:"HUG",vertical:"HUG"},layout:x(T,8),paint:"no fill; holds one instance of the library's Badge, secondary, once it exists"},{path:["DS/Header","Description"],where:"components",type:"TEXT",width:480,font:{size:16,lineHeight:28,weight:"Regular"},text:"Short description of the component and when to use it.",paint:"color/muted-foreground"},{path:["DS/Section Heading"],where:"components",type:"COMPONENT",at:{x:0,y:273},width:1200,height:81,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:I(T,8),properties:[{name:"Title",type:"TEXT",default:"Section title"},{name:"Description",type:"TEXT",default:"Section description."},{name:"Show description",type:"BOOLEAN",default:true}],paint:"no fill"},{path:["DS/Section Heading","h2"],where:"components",type:"FRAME",width:1200,height:45,sizing:{horizontal:"FILL",vertical:"HUG"},layout:I([0,0,8,0],0),paint:"bottom stroke 1 color/border, counted in the layout"},{path:["DS/Section Heading","h2","Title"],where:"components",type:"TEXT",font:{size:30,lineHeight:36,weight:"SemiBold"},text:"Section title",paint:"color/foreground; tracking -2.5%"},{path:["DS/Section Heading","Description"],where:"components",type:"TEXT",width:1200,sizing:{horizontal:"FILL"},font:{size:16,lineHeight:28,weight:"Regular"},text:"Section description.",paint:"color/muted-foreground; visible bound to Show description"},{path:["DS/Table Head"],where:"components",type:"COMPONENT",at:{x:0,y:418},width:200,height:40,sizing:{horizontal:"FIXED",vertical:"FIXED"},layout:I([0,8,0,8],0,["CENTER","MIN"]),properties:[{name:"Text",type:"TEXT",default:"Head"}],paint:"no fill"},{path:["DS/Table Head","Text"],where:"components",type:"TEXT",sizing:{horizontal:"FILL"},font:{size:14,lineHeight:20,weight:"Medium"},text:"Head",paint:"color/foreground"},{path:["DS/Table Cell"],where:"components",type:"COMPONENT_SET",at:{x:0,y:522},width:500,height:84,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:{mode:"HORIZONTAL",padding:[24,24,24,24],gap:24,crossGap:24,wrap:true},properties:[{name:"Text",type:"TEXT",default:"Cell"},{name:"Emphasis",type:"VARIANT",default:"primary"}],paint:"radius 5; the dashed border Figma gives a set"},...["primary","muted"].flatMap((e,t)=>[{path:["DS/Table Cell",`Emphasis=${e}`],where:"components",type:"COMPONENT",at:{x:24+t*224,y:24},width:200,height:36,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:I([8,8,8,8],0),paint:"no fill"},{path:["DS/Table Cell",`Emphasis=${e}`,"Text"],where:"components",type:"TEXT",sizing:{horizontal:"FILL"},font:{size:14,lineHeight:20,weight:e==="primary"?"Medium":"Regular"},text:"Cell",paint:e==="primary"?"color/foreground":"color/muted-foreground"}]),{path:["DS/List Item"],where:"components",type:"COMPONENT",at:{x:0,y:812},width:1176,height:28,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:x(T,10),properties:[{name:"Text",type:"TEXT",default:"List item text."}],paint:"no fill"},{path:["DS/List Item","Bullet"],where:"components",type:"TEXT",sizing:{horizontal:"HUG"},font:{size:16,lineHeight:28,weight:"Regular"},text:"•",paint:"color/foreground"},{path:["DS/List Item","Text"],where:"components",type:"TEXT",sizing:{horizontal:"FILL"},font:{size:16,lineHeight:28,weight:"Regular"},text:"List item text.",paint:"color/foreground"},{path:["DS/Matrix Head"],where:"components",type:"COMPONENT",at:{x:0,y:988},width:120,height:40,sizing:{horizontal:"FIXED",vertical:"FIXED"},layout:I([0,8,0,8],0,["CENTER","CENTER"]),properties:[{name:"Text",type:"TEXT",default:"Prop=value"}],paint:"no fill"},{path:["DS/Matrix Head","Text"],where:"components",type:"TEXT",sizing:{horizontal:"HUG"},font:{size:12,lineHeight:16,weight:"Medium"},text:"Prop=value",paint:"color/muted-foreground"},{path:["*"],where:"view",type:"FRAME",width:1440,layout:I(T,0),paint:"fill color/background"},{path:["*","*"],where:"view",type:"INSTANCE",main:"DS/Header",width:1440},{path:["*","Body"],where:"view",type:"FRAME",width:1440,layout:I([48,120,96,120],64),paint:"no fill"},{path:["*","Body","*"],where:"view",type:"FRAME",width:1200,layout:I(T,24),paint:"no fill"},{path:["*","Body","*","Heading"],where:"view",type:"INSTANCE",main:"DS/Section Heading",width:1200},{path:["*","Body","Component","Preview"],where:"view",type:"FRAME",width:1200,layout:[x(T,24),I(T,40)],paint:"fill color/background, radius 14, no stroke; vertical for a set of text styles"},{path:["*","Body","Matrix","Matrix"],where:"view",type:"FRAME",width:1200,layout:I(T,0),paint:"stroke 1 color/border, radius 8"},{path:["*","Body","Matrix","Matrix","TableHeader"],where:"view",type:"FRAME",height:40,layout:x(T,0)},{path:["*","Body","Example","Preview"],where:"view",type:"FRAME",width:1200,layout:{mode:"HORIZONTAL",padding:[40,40,40,40],gap:48,crossGap:24,wrap:true},paint:"fill color/background, stroke 1 color/border, radius 14"},...["Variants","Sizes","Composition"].flatMap(e=>[{path:["*","Body",e,"Preview"],where:"view",type:"FRAME",width:1200,layout:x([40,40,40,40],24,["CENTER","CENTER"]),paint:"fill color/background, stroke 1 color/border, radius 14"},{path:["*","Body",e,"Preview",e],where:"view",type:"FRAME",sizing:{horizontal:"HUG",vertical:"HUG"},layout:{mode:"HORIZONTAL",padding:T,gap:12,crossGap:12,wrap:true,align:["MIN","CENTER"]},paint:"centred in the preview, hugging its row of instances"}]),{path:["*","Body","Anatomy","Anatomy layout"],where:"view",type:"FRAME",width:1200,layout:x(T,16)},{path:["*","Body","Anatomy","Anatomy layout","Preview"],where:"view",type:"FRAME",width:744,sizing:{horizontal:"FILL",vertical:"FILL"},layout:x([24,24,24,24],24,["CENTER","CENTER"]),paint:"fill color/background, stroke 1 color/border, radius 14"},{path:["*","Body","Anatomy","Anatomy layout","Cards"],where:"view",type:"FRAME",width:440,sizing:{horizontal:"FIXED",vertical:"HUG"},layout:{mode:"GRID",padding:T,gap:16,crossGap:16},paint:"one column, one Card per part"},{path:["*","Body","*","Table"],where:"view",type:"FRAME",width:1200,layout:I(T,0),paint:"stroke 1 color/border, radius 8"},{path:["*","Body","*","Table","TableHeader"],where:"view",type:"FRAME",height:40,layout:x(T,0),paint:"bottom stroke 1 color/border"},{path:["*","Body","*","Table","TableRow"],where:"view",type:"FRAME",layout:x(T,0),paint:"bottom stroke 1 color/border, none on the last"},{path:["*","Body","*","Table","TableRow","TableCell"],where:"view",type:"FRAME",layout:[I([8,8,8,8],0,["CENTER","CENTER"]),x([12,8,12,8],0,["MIN","CENTER"])],paint:"a foundation's preview cell, its column's width: vertical for a colour swatch, fill color/background, following the page's mode; horizontal for a spacing bar or a radius square, no fill"},{path:["*","Body","*","List"],where:"view",type:"FRAME",width:1200,layout:I([0,0,0,24],8)},{path:["*","Body","*","List","li"],where:"view",type:"INSTANCE",main:"DS/List Item",width:1176},{path:["*","Body","*","Cards"],where:"view",type:"FRAME",width:1200,layout:{mode:"GRID",padding:T,gap:16,crossGap:16}},{path:["*","Body","*","Cards","Card"],where:"view",type:"INSTANCE",width:592,paint:"the library's Card"},{path:["*","Body","Preview","Theme Preview"],where:"view",type:"FRAME",width:1200,layout:x(T,16)},{path:["*","Body","Preview","Theme Preview","Preview"],where:"view",type:"FRAME",layout:I([40,40,40,40],20),paint:"fill color/background, stroke 1 color/border, radius 14; no mode of its own"}];var Be="Icon";var Xe=["Color","Spacing","Radius"];var U="DS/Header";var oe="Body";var ce="Preview";var R=e=>({name:e,required:true});var M=e=>({name:e});var re={key:"table",label:"the table shape",sections:[R("Example"),M("Properties"),M("Specs"),R("Usage"),R("Accessibility"),R(ce)]};var je={icons:{kind:"icons",noun:"icon set's view",pages:["icon set"],frame:()=>"Icons",eyebrow:"Foundations",eyebrowOwner:"the icon set's view's",badge:{counts:"48 icons, lucide-react"},badgeOwner:"the icon set's view's",shapes:[{label:"the icon set's view",sections:[{name:"Icons section",required:true,repeats:true}]}]},foundation:{kind:"foundation",noun:"foundation view",pages:["foundation"],frame:e=>e,eyebrow:"Foundations",eyebrowOwner:"a foundation's",badge:{counts:"31 tokens, Light and Dark"},badgeOwner:"a foundation view's",shapes:null},foundationGuidance:{kind:"foundationGuidance",noun:"foundation's guidance view",pages:["foundation","icon set"],frame:e=>`${e} / Guidance`,eyebrow:"Foundations",eyebrowOwner:"a foundation's",badge:{reads:"Guidance"},badgeOwner:"a guidance view's",shapes:[re]},component:{kind:"component",noun:"component view",pages:["entry"],frame:e=>e,eyebrow:"Components",eyebrowOwner:"an entry's",badge:{counts:"192 variants"},badgeOwner:"a component view's",shapes:[{label:"a component view",sections:[R("Component"),M("Matrix")]}]},guidance:{kind:"guidance",noun:"guidance view",pages:["entry"],frame:e=>`${e} / Guidance`,eyebrow:"Components",eyebrowOwner:"an entry's",badge:{reads:"Guidance"},badgeOwner:"a guidance view's",shapes:[re,{key:"parts",label:"the parts shape",sections:[M("Anatomy"),M("Variants"),M("Sizes"),M("Composition"),M("Properties"),R("Usage"),M("Behavior & content"),R("Accessibility"),R(ce)]}]}};var Ue=/^[0-9][0-9,.]*\s+\S/;function Ve(e){if(e===Be)return"icon set";return Xe.includes(e)?"foundation":"entry"}function se(e,t){if(!e.startsWith(z))return null;const n=e.slice(z.length);const i=Ve(n);return Object.values(je).find(r=>r.pages.includes(i)&&r.frame(n)===t)??null}var ae=e=>e.sections.map(t=>t.name).join(", ");function Ye(e,t,n){const i=[];const r=l=>t.some(d=>d.sections.some(y=>y.name===l));for(const l of n.filter((d,y)=>!r(d)&&n.indexOf(d)===y)){const d=t.length===1?ae(t[0]):`those of ${t.map(y=>`${y.label} (${ae(y)})`).join(" or of ")}`;i.push(`holds ${l}, which no ${e.noun} holds; its sections are ${d}`)}const a=n.filter(r);const c=l=>t.filter(d=>d.sections.some(y=>y.name===l));const w=a.find(l=>c(l).length===1);const f=(w?c(w)[0]:void 0)??t.find(l=>l.sections.every(d=>!d.required||a.includes(d.name)))??t[0];const h=f.sections.map(l=>l.name);let o=-1;let s="";for(const l of a){const d=h.indexOf(l);if(d===-1){i.push(`holds ${l}, a section of ${c(l)[0]?.label}, beside ${w} of ${f.label}`);continue}const y=d===o&&f.sections[d]?.repeats===true;if(d<o||d===o&&!y)i.push(`holds ${l} after ${s}; ${f.label} orders them ${h.join(", ")}`);else{o=d;s=l}}for(const l of f.sections)if(l.required&&!a.includes(l.name))i.push(`holds no ${l.name}, which ${f.label} always holds`);return i}function le(e,t,n=[]){const i=n.length>1;const r=[];const a=h=>e.filter(o=>o.parentId===h);const c=h=>{const o=[h];if(h.type!=="INSTANCE")for(const s of a(h.id))o.push(...c(s));return o};const w=(h,o)=>{for(let s=t.get(h.parentId??"");s;s=t.get(s.parentId??""))if(s===o)return true;return false};const f=(h,o)=>{const s=[];for(let l=o;l&&l!==h;l=t.get(l.parentId??""))s.unshift(l.name);return[h.name,...s].join(" / ")};for(const h of e){if(h.type!=="FRAME"||!h.page||h.parentId!==h.page.id)continue;const[o="",...s]=h.name.split(" / ");const l=i&&s.length>0&&se(h.page.name,s.join(" / "))!==null;const d=se(h.page.name,l?s.join(" / "):h.name);if(!d)continue;const y=(b,G,K=h)=>{r.push({nodeId:K.id,field:b,message:`${f(h,K)}: ${G}`})};if(l&&!n.includes(o))y("branch",`opens with ${o}, which is not a branch this file holds (${n.join(", ")})`);const g=d.kind==="component"||e.some(b=>(b.type==="COMPONENT"||b.type==="COMPONENT_SET")&&w(b,h));if(i&&!l&&g)y("branch",`names no branch; in a file holding ${n.join(" and ")}, a view drawing a component opens with its branch, as ${n[0]} / ${h.name}`);const p=a(h.id);const m=p[0];if(m&&(m.type!=="INSTANCE"||m.main!==U))y("header",`opens on ${m.name}, and a view opens on a ${U} instance`);const E=p.find(b=>b.type==="INSTANCE"&&b.main===U);const A=E?.values;if(E&&A){const b=A["Eyebrow"];if(b!==void 0&&b!==d.eyebrow)y("eyebrow",`the eyebrow reads "${String(b)}", and ${d.eyebrowOwner} reads "${d.eyebrow}"`);if(A["Show style"]===false)y("show style","the header's Show style is off, and a view's header shows its badge")}const N=E?e.find(b=>b.type==="INSTANCE"&&t.get(b.parentId??"")?.name==="Badges"&&w(b,E)):void 0;const $=N?.values?.["Label"];if(typeof $==="string"){const b=d.badge;if("reads"in b&&$!==b.reads)y("badge",`the badge reads "${$}", and ${d.badgeOwner} reads "${b.reads}"`);if("counts"in b&&!Ue.test($))y("badge",`the badge reads "${$}", and ${d.badgeOwner} counts what it shows ("${b.counts}")`)}const F=p.find(b=>b.type==="FRAME"&&b.name===oe);if(!F){y("sections",`holds no ${oe}, the frame its sections stand in`);continue}const S=a(F.id).filter(b=>b.type==="FRAME");if(d.shapes)for(const b of Ye(d,d.shapes,S.map(G=>G.name)))y("sections",b);for(const b of p.flatMap(c))if(b.modes&&Object.keys(b.modes).length>0)y("mode","sets a variable mode of its own; switch the mode on the page or the view instead",b)}return r}var C=.5;function Ke(e,t){const n=e.page;if(!n)return null;const i=n.name===j?"components":n.name.startsWith(z)?"view":null;if(i===null)return null;const r=[];for(let a=e;a;a=a.parentId?t.get(a.parentId):void 0){r.unshift(a.name);if(a.parentId===n.id){if(i==="view"&&a.type!=="FRAME")return null;return{node:e,path:r,where:i}}}return null}var de=e=>e.path.filter(t=>t!=="*").length;function We(e){const t=D.filter(n=>{if(n.where!==e.where||n.path.length!==e.path.length)return false;if(!n.path.every((r,a)=>r==="*"||r===e.path[a]))return false;const i=n.main!==void 0&&n.path.at(-1)==="*";return!i||e.node.main===n.main});return t.sort((n,i)=>de(i)-de(n))[0]??null}var pe=e=>e.replace(/\s+/g,"").toLowerCase();var k=(e,t)=>Math.abs(e-t)<=C;var ue=e=>e.join(" ");function qe(e,t){const n=[];if(e.layout!==t.mode)n.push(`layout ${e.layout}, not ${t.mode}`);if(!e.padding.every((i,r)=>k(i,t.padding[r]??0)))n.push(`padding ${ue(e.padding)}, not ${ue(t.padding)}`);if(!k(e.gap,t.gap))n.push(`gap ${e.gap}, not ${t.gap}`);if(t.crossGap!==void 0&&!k(e.crossGap,t.crossGap))n.push(`row gap ${e.crossGap}, not ${t.crossGap}`);if(t.wrap!==void 0&&e.wrap!==t.wrap)n.push(t.wrap?"does not wrap, and it wraps":"wraps, and it does not");if(t.align&&(e.align[0]!==t.align[0]||e.align[1]!==t.align[1]))n.push(`aligns ${e.align.join(" ")}, not ${t.align.join(" ")}`);return n}function Ze(e,t,n){const i=[];const r=(c,w)=>{i.push({nodeId:e.id,field:c,message:`${n}: ${w}`})};if(e.type!==t.type)r("type",`is a ${e.type}, and the documentation draws a ${t.type}`);if(t.main!==void 0&&t.path.at(-1)!=="*"&&e.main!==void 0&&e.main!==t.main)r("main",`is an instance of ${e.main??"no component"}, not of ${t.main}`);const a=e.box;if(a){if(t.at&&(!k(a.x,t.at.x)||!k(a.y,t.at.y)))r("at",`sits at ${a.x}, ${a.y}, not ${t.at.x}, ${t.at.y}`);if(t.width!==void 0&&!k(a.width,t.width))r("width",`is ${a.width} wide, not ${t.width}`);if(t.height!==void 0&&!k(a.height,t.height))r("height",`is ${a.height} high, not ${t.height}`);for(const c of["horizontal","vertical"]){const w=t.sizing?.[c];if(w!==void 0&&a.sizing[c]!==w)r(`sizing.${c}`,`sizes ${a.sizing[c]} ${c}ly, not ${w}`)}if(t.layout){const c=Array.isArray(t.layout)?t.layout:[t.layout];const w=c.map(h=>qe(a,h));const f=[...w].sort((h,o)=>h.length-o.length)[0]??[];if(f.length>0)r("layout",f.join("; "))}}if(t.font&&e.font){const{size:c,lineHeight:w,style:f}=e.font;if(c!==t.font.size||w!==t.font.lineHeight)r("font",`is set ${c} / ${w}, not ${t.font.size} / ${t.font.lineHeight}`);if(pe(f)!==pe(t.font.weight))r("weight",`is ${f}, not ${t.font.weight}`)}if(t.text!==void 0&&e.characters!==void 0&&e.characters!==t.text)r("text",`reads "${e.characters}", not "${t.text}"`);if(t.properties&&e.properties){const c=e.properties.map(f=>`${f.name} ${f.type} ${String(f.default)}`).sort();const w=t.properties.map(f=>`${f.name} ${f.type} ${String(f.default)}`).sort();if(c.join("|")!==w.join("|"))r("properties",`has the properties [${c.join(", ")}], not [${w.join(", ")}]`)}return i}function fe(e,t=[]){const n=new Map(e.map(c=>[c.id,c]));const i=[];const r=e.map(c=>Ke(c,n)).filter(c=>c!==null);const a=new Map;for(const c of r){const w=We(c);const f=c.path.join(" / ");if(c.where==="components"&&c.path.length===1){a.set(c.node.name,[...a.get(c.node.name)??[],c.node]);if(!w&&(c.node.type==="COMPONENT"||c.node.type==="COMPONENT_SET"))i.push({nodeId:c.node.id,field:"name",message:`${f}: is not one of the documentation components`})}if(w)i.push(...Ze(c.node,w,f))}for(const[c,w]of a){for(const f of w.slice(1))i.push({nodeId:f.id,field:"name",message:`${c}: a second component of that name`})}for(const c of r){if(c.where!=="components"||c.path.length!==1)continue;const w=e.filter(f=>f.parentId===c.node.id);if(w.length===0)continue;for(const f of D){if(f.where!=="components"||f.path[0]!==c.node.name||f.path.length<2)continue;const h=r.some(o=>o.path.length===f.path.length&&o.path.every((s,l)=>s===f.path[l]));if(!h)i.push({nodeId:c.node.id,field:"layers",message:`${c.node.name}: holds no ${f.path.slice(1).join(" / ")}`})}}i.push(...le(e,n,t));i.push(...Je(e,n));return i}function Je(e,t){const n=new Map;const i=s=>{const l=n.get(s.id);if(l)return l;const d=t.get(s.parentId??"");if(!s.box||!d||d.type==="INSTANCE")return null;let y=s.box.x;let g=s.box.y;let p;let m=[];if(d.parentId===s.page?.id){if(d.name!==O.frame||s.name===O.bleeds)return null;p=[d.name,s.name]}else{const N=i(d);if(!N)return null;y+=N.x;g+=N.y;p=[...N.path,s.name];m=[N,...N.above]}const E=s.type==="INSTANCE"||!e.some(N=>N.parentId===s.id);const A={node:s,x:y,y:g,right:y+s.box.width,bottom:g+s.box.height,path:p,block:E,above:m};n.set(s.id,A);return A};for(const s of e)if(s.page?.name===O.page)i(s);const r=[...n.values()];const a=r.filter(s=>s.block);const c=s=>s-O.width;const w=s=>a.some(l=>Math.abs(l.x-s.x)<=C&&c(l.right)>C&&c(l.right)>=O.bleed*(l.node.box?.width??0));const f=[];const h=(s,l,d)=>{f.push({nodeId:s.node.id,field:l,message:`${s.path.join(" / ")}: ${d}`})};const o=s=>[["left",-s.x],["top",-s.y],["bottom",s.bottom-O.height]].filter(([,l])=>l>C).map(([l,d])=>`reaches ${Math.round(d)} past the cover's ${l} edge`);for(const s of r){const l=o(s);if(l.length>0&&!s.above.some(m=>o(m).length>0))h(s,"bounds",`${l.join(", ")}, which cuts it off`);const d=c(s.right);if(s.block){if(w(s))continue;const m=Math.round(s.node.box?.width??0);if(d>C)h(s,"bounds",`crosses the cover's right edge by ${Math.round(d)} of its ${m}; bleed a quarter of its width past it, or end it ${O.margin} inside`);else if(c(s.right+O.margin)>C)h(s,"bounds",`ends ${Math.round(-d)} inside the cover's right edge, within its ${O.margin} margin`);continue}if(d<=C)continue;const y=r.filter(m=>m.above.includes(s));const g=y.filter(m=>m.block&&c(m.right)>C&&w(m));const p=Math.max(O.width,...g.map(m=>m.right));if(s.right<=p+C)continue;if(y.some(m=>Math.abs(m.right-s.right)<=C))continue;h(s,"bounds",g.length>0?`reaches ${Math.round(s.right-p)} past the layers that bleed from it at the cover's right edge`:`reaches ${Math.round(d)} past the cover's right edge, and nothing in it bleeds`)}return f}var he=new Set(D.filter(e=>e.where==="components"&&e.path.length===1).map(e=>e.path[0]??""));function ge(e){if(e.type!=="TEXT"||e.characters===void 0)return false;if(e.page?.name!==j)return false;return D.some(t=>t.where==="components"&&t.type==="TEXT"&&t.text===e.characters&&t.path[0]===e.frame&&t.path.at(-1)===e.name)}var Qe={FRAME:["Frame"],GROUP:["Group"],SECTION:["Section"],COMPONENT:["Component"],COMPONENT_SET:["Component"],RECTANGLE:["Rectangle"],ELLIPSE:["Ellipse"],LINE:["Line"],POLYGON:["Polygon"],STAR:["Star"],VECTOR:["Vector"],SLICE:["Slice"],BOOLEAN_OPERATION:["Union","Subtract","Intersect","Exclude"]};function me(e,t){const n=/^(.+?)(?: \d+)?$/.exec(t);return n!==null&&(Qe[e]??[]).includes(n[1]??"")}var ye="❖ ";var et=new Set(["Thumbnail","Component for Docs"]);var P=.01;var tt=["data-entry","navigation","feedback","data-display","layout","general"];var nt=new RegExp(`^(${tt.join("|")}) / .+$`);var it="_components";function ot(e){const t=e.page?.name;if(t===void 0)return false;if(et.has(t))return true;if(e.componentSource!==false)return false;return t.startsWith(ye)||nt.test(t)||e.frame===it}var we=(e,t)=>e.map(n=>n.variable??"").join()===t.map(n=>n.variable??"").join();function rt(e,t){const n=Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x);const i=Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y);return n>P&&i>P}function st(e){const t=e.box;if(e.type!=="FRAME"||!t||t.children!==0)return false;if(e.fills.length>0||e.strokes.length>0)return false;return t.width>1&&t.height>1}function at(e,t,n){return e.x<-P||e.y<-P||e.x+e.width>t+P||e.y+e.height>n+P}function V(e,t=W,n={}){const i=ie(t,e.flatMap(o=>o.main&&he.has(o.main)?[]:o.instance?.carried??[]));const r=[];const a=new Map(e.map(o=>[o.id,o]));const c=o=>{for(let s=a.get(a.get(o)?.parentId??"");s;s=a.get(s.parentId??"")){const l=s.type==="INSTANCE"?s.mainId:void 0;if(!l)continue;for(let d=a.get(s.parentId??"");d;d=a.get(d.parentId??""))if(d.swaps?.includes(l))return true}return false};const w=new Set(e.flatMap(o=>o.instance?.overrides.map(s=>s.nodeId)??[]));const f=o=>{if(o.page?.name!==O.page)return false;for(let s=a.get(o.parentId??"");s;s=a.get(s.parentId??""))if(s.name===O.logo)return true;return false};for(const o of e){const s=`${o.name} (${o.type.toLowerCase()})`;const l=(g,p,m,E=o.id)=>{r.push({check:g,nodeId:E,...p?{field:p}:{},...o.frame?{frame:o.frame}:{},message:m})};const d=ot(o);const y=f(o);if(!y&&o.fills.some(g=>!g.bound))l("binding","fill",`${s}: fill is a raw value`);if(!y&&o.strokes.some(g=>!g.bound))l("binding","stroke",`${s}: stroke is a raw value`);if(o.type==="TEXT"&&o.textStyleId===null&&!d)l("binding","textStyle",`${s}: text has no library text style`);for(const g of d?[]:o.spacing){if(g.value>0&&!g.bound)l("binding",g.field,`${s}: ${g.field} ${g.value} is not a spacing variable`)}if((o.type==="COMPONENT"||o.type==="COMPONENT_SET")&&o.page?.name.startsWith(ye)&&o.parentId===o.page.id)l("placement",void 0,`${s}: sits on the page, outside its entry's component view`);if(o.set){const{width:g,height:p,variants:m}=o.set;m.forEach((E,A)=>{for(const N of m.slice(A+1)){if(rt(E,N))l("overlap",void 0,`${o.name}: ${E.name} overlaps ${N.name}`,E.id)}if(at(E,g,p))l("overlap",void 0,`${o.name}: ${E.name} reaches past the set, which cuts it off`,E.id)})}if(o.characters!==void 0&&!ge(o)){for(const g of X(o.characters,i))l("copy",g.field,`${s}: ${g.message}`)}if(o.instance){for(const g of o.instance.overrides){if(g.characters!==void 0){for(const p of X(g.characters,i))l("copy",p.field,`${o.name}: ${p.message}`,g.nodeId)}for(const p of g.fields){if(q.has(p))continue;if(p==="fills"&&g.picture)continue;const m=g.nodeId===o.id;if(!m&&(p==="fills"||p==="strokes")&&o.componentSource===true)continue;if(!m&&(p==="fills"||p==="strokes")&&c(g.nodeId))continue;const E=a.get(g.nodeId);if(!m&&(p==="fills"||p==="strokes")&&E?.source){if(we(E[p],E.source[p]))continue}if(m&&(p==="width"||p==="height")&&d)continue;if(m&&(p==="width"||p==="height")&&o.componentSource===true)continue;if(m&&p==="width"&&o.instance.sizing.horizontal!=="FIXED")continue;if(m&&p==="height"&&o.instance.sizing.vertical!=="FIXED")continue;if(m&&Z.has(p)&&Q(o.instance.sizing))continue;if(m&&J(p,o.box,o.instance.main))continue;l("overrides",p,`${p} overridden inside an instance of ${o.name}`,g.nodeId)}}}if(st(o))l("empty",void 0,`${o.name}: an empty frame ${Math.round(o.box?.width??0)}x${Math.round(o.box?.height??0)} that shows nothing; it holds no layer, so remove it or put in what it was made for`);if(me(o.type,o.name))l("naming",void 0,`${o.name} keeps a default name`);if(o.source){const g=["fills","strokes"].filter(p=>!we(o[p],o.source?.[p]??[]));if(g.length>0&&!w.has(o.id))l("binding",g[0]==="fills"?"fill":"stroke",`${s}: paints with another colour than the same layer in its component (${(o.source[g[0]??"fills"]??[]).map(p=>p.variable??"raw").join(", ")}), which an icon swap dropped`)}}const h=new Map(e.map(o=>[o.id,o.frame]));for(const{nodeId:o,field:s,message:l}of fe(e,n.branches)){const d=h.get(o);r.push({check:"documentation",nodeId:o,field:s,...d?{frame:d}:{},message:l})}return r}var H=18e3;function be(e){return encodeURIComponent(JSON.stringify(e)).replace(/%[0-9A-F]{2}/g,"x").length}function Y(e,t,n=H){const i={};for(const c of t)i[c.check]=(i[c.check]??0)+1;const r={checked:e,total:t.length,counts:i,findings:[],cut:false};let a=be(r);for(const c of t){a+=be(c)+1;if(a>n){r.cut=true;break}r.findings.push(c)}return r}function u(e,t){try{return e[t]}catch{return void 0}}var ct=["paddingTop","paddingRight","paddingBottom","paddingLeft","itemSpacing"];function _(e){if(!Array.isArray(e))return[];return e.filter(t=>t.type==="SOLID"&&t.visible!==false&&(t.opacity??1)>0).map(t=>{const n=t.boundVariables?.color?.id;return{bound:Boolean(t.boundVariables?.color),...typeof n==="string"?{variable:n}:{}}})}function Ee(e,t){if(e.id===t)return e;const n=u(e,"findOne");return n?n.call(e,i=>i.id===t):null}function Te(e,t){const n=t.get(e.id);if(n)return n;const i=e.parent??null;const r=i?Te(i,t):null;const a={frame:i?.type==="PAGE"?e.name:r?.frame??null,page:e.type==="PAGE"?{id:e.id,name:e.name}:r?.page??null,componentSource:e.type==="COMPONENT"||e.type==="COMPONENT_SET"||(r?.componentSource??false),insideInstance:i?.type==="INSTANCE"||(r?.insideInstance??false)};t.set(e.id,a);return a}var lt=new Set(["VECTOR","BOOLEAN_OPERATION","ELLIPSE","RECTANGLE","LINE","STAR","POLYGON"]);function dt(e){if(!e.startsWith("I"))return null;const t=e.slice(1).split(";").slice(1);if(t.length===0)return null;return t.length===1?t[0]??null:`I${t.join(";")}`}function pt(e){const t=u(e,"children")??[];return{width:Number(u(e,"width")??0),height:Number(u(e,"height")??0),variants:t.map(({id:n,name:i,x:r,y:a,width:c,height:w})=>({id:n,name:i,x:r,y:a,width:c,height:w}))}}function ut(e,t){const n=u(e,"findAll");if(!n)return[];return n.call(e,i=>i.type==="TEXT"&&!t.has(i.id)).map(i=>typeof i.characters==="string"?i.characters:"")}function ft(e){const t=e?u(e,"fills"):void 0;return Array.isArray(t)&&t.some(n=>n.type==="IMAGE")}var ht=new Set(["FRAME","COMPONENT","COMPONENT_SET","INSTANCE","TEXT"]);var v=e=>typeof e==="number"?e:0;function gt(e){const t=u(e,"layoutMode");const n=typeof t==="string"?t:"NONE";const i=u(e,"children");const r=n==="GRID";return{x:v(u(e,"x")),y:v(u(e,"y")),width:v(u(e,"width")),height:v(u(e,"height")),sizing:{horizontal:String(u(e,"layoutSizingHorizontal")??"FIXED"),vertical:String(u(e,"layoutSizingVertical")??"FIXED")},layout:n,wrap:u(e,"layoutWrap")==="WRAP",padding:[v(u(e,"paddingTop")),v(u(e,"paddingRight")),v(u(e,"paddingBottom")),v(u(e,"paddingLeft"))],gap:r?v(u(e,"gridColumnGap")):v(u(e,"itemSpacing")),crossGap:r?v(u(e,"gridRowGap")):v(u(e,"counterAxisSpacing")),align:[String(u(e,"primaryAxisAlignItems")??"MIN"),String(u(e,"counterAxisAlignItems")??"MIN")],children:Array.isArray(i)?i.length:0}}function mt(e,t){const n=u(e,"fontSize");const i=u(e,"lineHeight");const r=u(e,"fontName");const a=typeof n==="number"?n:0;return{size:n===t?"mixed":a,lineHeight:i===t||typeof i!=="object"?"mixed":i.unit==="AUTO"?"auto":i.unit==="PERCENT"?a*v(i.value)/100:v(i.value),style:r===t||typeof r!=="object"?"mixed":String(r.style??"")}}function wt(e){if(e.type!=="COMPONENT_SET"&&(e.type!=="COMPONENT"||e.parent?.type==="COMPONENT_SET"))return void 0;const t=u(e,"componentPropertyDefinitions");if(!t)return void 0;return Object.entries(t).map(([n,{type:i,defaultValue:r}])=>({name:n.split("#")[0]??n,type:i,default:r}))}async function yt(e){const t=u(e,"getMainComponentAsync");return t?await t.call(e):null}function bt(e){if(!e)return null;return e.parent?.type==="COMPONENT_SET"?e.parent.name:e.name}function Et(e,t,n){const i=n.find(r=>r.id===e);if(!i?.overriddenFields.some(r=>r==="width"||r==="height"))return null;return typeof t?.width==="number"&&typeof t.height==="number"?{width:t.width,height:t.height}:null}function Tt(e){const t=u(e,"componentProperties");if(!t||typeof t!=="object")return[];return Object.values(t).flatMap(n=>n?.type==="INSTANCE_SWAP"&&typeof n.value==="string"?[n.value]:[])}function Nt(e){const t=u(e,"componentProperties");if(!t||typeof t!=="object")return void 0;const n={};for(const[i,r]of Object.entries(t)){const a=r?.value;if(typeof a==="string"||typeof a==="boolean")n[i.split("#")[0]??i]=a}return n}function St(e){const t=u(e,"explicitVariableModes");if(!t||typeof t!=="object")return void 0;const n=Object.entries(t).filter(i=>typeof i[1]==="string");return n.length>0?Object.fromEntries(n):void 0}async function Ne(e,t,n=typeof figma==="undefined"?Symbol("mixed"):figma.mixed,i=new Map,r=a=>figma.getNodeByIdAsync(a)){const a=e;const c=u(a,"textStyleId");const w=u(a,"boundVariables");const f=u(a,"overrides")??[];const h=new Set(f.filter(S=>S.overriddenFields.includes("characters")).map(S=>S.id));const o=e.type==="INSTANCE"?ut(e,h):[];const s=u(a,"layoutMode");const l=typeof s==="string"&&s!=="NONE";const d=Te(e,i);const y=lt.has(e.type)&&d.insideInstance&&!d.componentSource?dt(e.id):null;const g=y?await r(y):null;const p=e.type==="INSTANCE"?await yt(a):null;const m=e.type==="INSTANCE"?Et(e.id,p,f):null;const E=wt(a);const A=e.type==="INSTANCE"?Nt(e):void 0;const N=e.type==="INSTANCE"?Tt(e):[];const $=typeof p?.id==="string"?p.id:void 0;const F=St(e);return{id:e.id,name:e.name,type:e.type,parentId:a.parent?.id??null,frame:d.frame,created:t,fills:_(u(a,"fills")),strokes:_(u(a,"strokes")),textStyleId:e.type!=="TEXT"?null:c===n?"mixed":typeof c==="string"&&c?c:null,...e.type==="TEXT"&&!d.insideInstance?{characters:String(u(a,"characters")??"")}:{},instance:e.type==="INSTANCE"?{overrides:f.map(S=>({nodeId:S.id,fields:S.overriddenFields,...S.overriddenFields.includes("fills")&&ft(Ee(e,S.id))?{picture:true}:{},...h.has(S.id)?{characters:String(u(Ee(e,S.id),"characters")??"")}:{}})),...o.length>0?{carried:o}:{},sizing:{horizontal:String(u(a,"layoutSizingHorizontal")??"FIXED"),vertical:String(u(a,"layoutSizingVertical")??"FIXED")},...m?{main:m}:{}}:null,spacing:l?ct.map(S=>({field:S,value:Number(u(a,S)??0),bound:Boolean(w?.[S])})):[],...g?{source:{fills:_(u(g,"fills")),strokes:_(u(g,"strokes"))}}:{},page:d.page,componentSource:d.componentSource,...ht.has(e.type)?{box:gt(a)}:{},...e.type==="TEXT"?{font:mt(a,n)}:{},...E?{properties:E}:{},...e.type==="INSTANCE"?{main:bt(p)}:{},...$?{mainId:$}:{},...N.length>0?{swaps:N}:{},...A?{values:A}:{},...F?{modes:F}:{},...e.type==="COMPONENT_SET"?{set:pt(a)}:{}}}async function Se(e,t){if("nodeId"in t){const n=await e.getNodeByIdAsync(t.nodeId);if(!n||n.type==="PAGE"||n.type==="DOCUMENT")return[];return"findAll"in n?[n,...n.findAll()]:[n]}if(t.page!==true){const n=t.page;const i=e.root.children;const r=i.find(a=>a.id===n||a.name===n);if(!r)throw new Error(`no page ${n}; the pages are ${i.map(a=>a.name).join(", ")}`);if(r!==e.currentPage)await e.setCurrentPageAsync(r)}return e.currentPage.findAll()}async function It(e,t){const n=await Se(e,t.scope);const i=new Map;const r=await Promise.all(n.map(a=>Ne(a,false,e.mixed,i)));return Y(r.length,V(r,t.copy,{branches:t.branches??[]}))}return Ce(Ot);})();
package/dist/zaku.mjs CHANGED
@@ -44639,21 +44639,15 @@ function defaultBranch(family) {
44639
44639
  return "ui";
44640
44640
  return DESKTOP_FAMILIES.has(family) ? void 0 : "native";
44641
44641
  }
44642
- function defaultPlatform(family) {
44643
- if (family === "web")
44644
- return "web-app";
44645
- return DESKTOP_FAMILIES.has(family) ? "desktop" : "mobile";
44646
- }
44647
44642
  var branchOf = (target) => target.branch ?? defaultBranch(target.family);
44648
- var platformOf = (target) => target.platform ?? defaultPlatform(target.family);
44649
44643
  var unique = (values) => [...new Set(values)];
44650
44644
  function legacyFiles(config2) {
44651
44645
  const branches = unique(config2.targets.flatMap((target) => branchOf(target) ?? []));
44652
- const platforms = unique(config2.targets.map(platformOf));
44646
+ const families2 = unique(config2.targets.map((target) => target.family));
44653
44647
  const { library, product } = config2.figma;
44654
44648
  return {
44655
44649
  libraries: library === void 0 ? [] : [{ key: library, layer: "foundations", branches: branches.length > 0 ? branches : ["ui"], extends: [] }],
44656
- products: product === void 0 ? [] : platforms.map((platform) => ({ key: product, platform }))
44650
+ products: product === void 0 ? [] : families2.map((family) => ({ key: product, family }))
44657
44651
  };
44658
44652
  }
44659
44653
  function designGraph(config2) {
@@ -44682,7 +44676,7 @@ function designGraph(config2) {
44682
44676
  prototypes,
44683
44677
  legacy,
44684
44678
  branchOf,
44685
- platformOf,
44679
+ targetsOf: (family) => config2.targets.filter((target) => target.family === family),
44686
44680
  librariesFor: (target) => {
44687
44681
  if (legacy)
44688
44682
  return libraries;
@@ -44694,7 +44688,7 @@ function designGraph(config2) {
44694
44688
  multiBranch: (key) => (byKey.get(key)?.branches.length ?? 0) > 1,
44695
44689
  productOf: (prototypeKey) => {
44696
44690
  const prototype2 = prototypes.find((candidate) => candidate.key === prototypeKey);
44697
- return prototype2?.product ?? (products.length === 1 ? products[0]?.key : void 0);
44691
+ return products.find((product) => product.family === prototype2?.family)?.key;
44698
44692
  }
44699
44693
  };
44700
44694
  }
@@ -44726,7 +44720,6 @@ function snapshotsFor(input2, target) {
44726
44720
  var PLATFORM_FAMILIES = ["web", "ios", "android", "macos", "windows", "gnome", "kde"];
44727
44721
  var LAYERS = ["foundations", "components"];
44728
44722
  var BRANCHES = ["ui", "native"];
44729
- var PLATFORMS = ["web-app", "mobile", "desktop"];
44730
44723
  var DEFAULT_INTERACTIVE = [
44731
44724
  "Button",
44732
44725
  "Button Group",
@@ -44755,9 +44748,7 @@ var targetSchema = external_exports.object({
44755
44748
  /** The frame size every frame of this target is drawn at; the frame check compares it. */
44756
44749
  size: external_exports.object({ width: external_exports.number().positive(), height: external_exports.number().positive() }).strict().optional(),
44757
44750
  /** The renderer whose libraries its frames draw from; `defaultBranch` in the design graph gives it when left out. */
44758
- branch: external_exports.enum(BRANCHES).optional(),
44759
- /** What its frames serve; `defaultPlatform` in the design graph gives it when left out. */
44760
- platform: external_exports.enum(PLATFORMS).optional()
44751
+ branch: external_exports.enum(BRANCHES).optional()
44761
44752
  }).strict();
44762
44753
  var DEFAULT_SYSTEM_BARS = {
44763
44754
  web: [],
@@ -44786,13 +44777,8 @@ var librarySchema = external_exports.object({
44786
44777
  /** The libraries and kits this one is built on, by key. */
44787
44778
  extends: external_exports.array(fileKey).default([])
44788
44779
  }).strict();
44789
- var productSchema = external_exports.object({ key: fileKey, platform: external_exports.enum(PLATFORMS) }).strict();
44790
- var prototypeSchema = external_exports.object({
44791
- key: fileKey,
44792
- platform: external_exports.enum(PLATFORMS),
44793
- /** The product file its frames are copied from; required when there are several. */
44794
- product: fileKey.optional()
44795
- }).strict();
44780
+ var productSchema = external_exports.object({ key: fileKey, family: external_exports.enum(PLATFORM_FAMILIES) }).strict();
44781
+ var prototypeSchema = external_exports.object({ key: fileKey, family: external_exports.enum(PLATFORM_FAMILIES) }).strict();
44796
44782
  var files = external_exports.object({
44797
44783
  library: fileKey.optional(),
44798
44784
  product: fileKey.optional(),
@@ -44941,23 +44927,28 @@ function refineFilesByRole(config2, ctx) {
44941
44927
  const cycle = findCycle(libraries);
44942
44928
  if (cycle)
44943
44929
  ctx.addIssue({ code: "custom", path: ["figma", "libraries"], message: `extends comes back: ${cycle}` });
44930
+ for (const [list, entries] of [
44931
+ ["products", products],
44932
+ ["prototypes", figma.prototypes ?? []]
44933
+ ]) {
44934
+ const families2 = /* @__PURE__ */ new Set();
44935
+ entries.forEach((entry, index) => {
44936
+ if (families2.has(entry.family))
44937
+ ctx.addIssue({
44938
+ code: "custom",
44939
+ path: ["figma", list, index, "family"],
44940
+ message: `a second ${list === "products" ? "product" : "prototype"} file for ${entry.family}`
44941
+ });
44942
+ families2.add(entry.family);
44943
+ });
44944
+ }
44944
44945
  (figma.prototypes ?? []).forEach((prototype2, index) => {
44945
- const path2 = ["figma", "prototypes", index];
44946
- if (prototype2.product === void 0) {
44947
- if (products.length > 1)
44948
- ctx.addIssue({ code: "custom", path: [...path2, "product"], message: "name the product its frames come from" });
44949
- return;
44950
- }
44951
- const product = products.find((candidate) => candidate.key === prototype2.product);
44952
- if (!product) {
44953
- ctx.addIssue({ code: "custom", path: [...path2, "product"], message: `no product with key ${prototype2.product}` });
44954
- } else if (product.platform !== prototype2.platform) {
44946
+ if (!products.some((product) => product.family === prototype2.family))
44955
44947
  ctx.addIssue({
44956
44948
  code: "custom",
44957
- path: [...path2, "platform"],
44958
- message: `${prototype2.platform}, and its product serves ${product.platform}`
44949
+ path: ["figma", "prototypes", index, "family"],
44950
+ message: `no product file for ${prototype2.family} to copy its frames from`
44959
44951
  });
44960
- }
44961
44952
  });
44962
44953
  config2.targets.forEach((target, index) => {
44963
44954
  const branch = target.branch ?? defaultBranch(target.family);
@@ -46609,7 +46600,7 @@ var screenOutlineSchema = external_exports.preprocess(legacyVersion, external_ex
46609
46600
  mapDigest: external_exports.string(),
46610
46601
  /** The version of each library snapshot the frames were read against, by key. */
46611
46602
  libraryVersions: external_exports.record(external_exports.string(), external_exports.string()),
46612
- /** The version of every product file zaku.yaml lists, when it lists them by platform. */
46603
+ /** The version of every product file zaku.yaml lists, when it lists them by family. */
46613
46604
  fileVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
46614
46605
  frames: external_exports.array(frameOutlineSchema)
46615
46606
  }).strict());
@@ -46755,14 +46746,14 @@ function productFiles(config2) {
46755
46746
  return config2.figma.product === void 0 ? [] : [{ key: config2.figma.product, targets: config2.targets }];
46756
46747
  return graph.products.map((product) => ({
46757
46748
  key: product.key,
46758
- targets: config2.targets.filter((target) => graph.platformOf(target) === product.platform)
46749
+ targets: graph.targetsOf(product.family)
46759
46750
  }));
46760
46751
  }
46761
46752
  async function runOutline(options) {
46762
46753
  const paths = designPaths(options.root);
46763
46754
  const config2 = await readDesignFile(paths.config, zakuConfigSchema);
46764
- const { libraries: listed, kits, products: byPlatform, prototypes: flows } = config2.figma;
46765
- const legacy = [listed, kits, byPlatform, flows].every((files2) => files2 === void 0);
46755
+ const { libraries: listed, kits, products: byFamily, prototypes: flows } = config2.figma;
46756
+ const legacy = [listed, kits, byFamily, flows].every((files2) => files2 === void 0);
46766
46757
  const products = productFiles(config2);
46767
46758
  if (products.length === 0)
46768
46759
  throw new FigmaFileKeyMissing(legacy ? "figma.product" : "figma.products");
@@ -46815,7 +46806,7 @@ ${frame.page}`;
46815
46806
  for (const file2 of legacy ? [] : graph.prototypes) {
46816
46807
  const read = await options.rest.file(file2.key, INDEX_DEPTH);
46817
46808
  versions[file2.key] = read.version;
46818
- const targets = config2.targets.filter((target) => graph.platformOf(target) === file2.platform);
46809
+ const targets = graph.targetsOf(file2.family);
46819
46810
  for (const frame of listFrames(read.document).filter((candidate) => holdsScreens(candidate.page)))
46820
46811
  flowFrame(file2.key, frame, targets);
46821
46812
  }
@@ -47159,7 +47150,8 @@ function printGraph(config2, snapshots) {
47159
47150
  ...graph.kitsFor(target).map((kit) => `${kit.key} ${kit.family} kit`)
47160
47151
  ];
47161
47152
  const branch = graph.branchOf(target);
47162
- lines.push(` ${target.name} (${target.id}, ${branch ? `branch ${branch}` : "no branch"}, ${graph.platformOf(target)}): ${files2.join(", ") || "nothing"}`);
47153
+ const product = graph.products.find((file2) => file2.family === target.family)?.key;
47154
+ lines.push(` ${target.name} (${target.id}, ${branch ? `branch ${branch}` : "no branch"}, ${product ? `product ${product}` : "no product"}): ${files2.join(", ") || "nothing"}`);
47163
47155
  }
47164
47156
  lines.push("files");
47165
47157
  const extendedBy = (key) => graph.libraries.filter((library) => library.extends.includes(key)).map((library) => library.key).join(", ") || "nothing";
@@ -48482,8 +48474,8 @@ var component = ({ config: config2, outlines, productComponents }) => {
48482
48474
  const findings = [];
48483
48475
  const graph = designGraph(config2);
48484
48476
  for (const drawn of productComponents) {
48485
- const platform = graph.products.find((product) => product.key === drawn.source)?.platform;
48486
- const branches = new Set(config2.targets.filter((target) => graph.platformOf(target) === platform).flatMap((target) => graph.branchOf(target) ?? []));
48477
+ const families2 = graph.products.filter((product) => product.key === drawn.source).map((product) => product.family);
48478
+ const branches = new Set(families2.flatMap((family) => graph.targetsOf(family)).flatMap((target) => graph.branchOf(target) ?? []));
48487
48479
  const homes = graph.libraries.filter((library) => library.layer === "components" && library.branches.some((branch) => branches.has(branch))).map((library) => library.key);
48488
48480
  findings.push({
48489
48481
  check: "component",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxsolutions/zaku",
3
- "version": "0.0.4",
3
+ "version": "0.1.0",
4
4
  "private": false,
5
5
  "description": "zaku's checker: checks a product's design data against its code and prints the rules script every Figma write runs.",
6
6
  "license": "MIT",
@@ -37,13 +37,13 @@
37
37
  "@modelcontextprotocol/sdk": "1.32.2",
38
38
  "@types/node": "^24.19.1",
39
39
  "@zeroxsolutions/cosmic": "0.3.4",
40
+ "@zeroxsolutions/zaku-core": "0.0.1",
40
41
  "commander": "15.0.0",
41
42
  "playwright": "1.64.0",
42
43
  "reflect-metadata": "0.2.2",
43
44
  "tsyringe": "4.10.0",
44
45
  "vitest": "5.0.3",
45
- "zod": "4.6.5",
46
- "@zeroxsolutions/zaku-core": "0.0.1"
46
+ "zod": "4.6.5"
47
47
  },
48
48
  "nx": {
49
49
  "targets": {