{"version":3,"file":"AlgorithmCount.2cC1fxKN.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/54ZMLSH6hvlrL6OINDG0/Sk2yWlUxyeOUr6ZVqw29/AlgorithmCount.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef}from\"react\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";/**\n * Keeps \"N algorithms\" copy in step with the Algorithms CMS.\n *\n * Framer text cannot show a CMS count, so the copy is written normally in Framer\n * (e.g. \"Seventeen algorithms in production\") and this invisible component swaps\n * only the number on the live site. Editors can change everything around it.\n *\n * It rewrites text inside its parent layer:\n *   - \"<n> algorithms in production\" and \"<n> jobs across the workflow\" -> total count\n *   - a text that is exactly \"<n> algorithms\" inside a \"Column 0X\" layer -> that column's count\n * Numbers written as words stay words (\"Eighteen\"), digits stay digits.\n *\n * The total comes from the algorithm cards when they are on the page (/technology),\n * otherwise from /sitemap.xml (every published /technology/<slug> page, minus the\n * static technology pages). It is remembered in localStorage between pages.\n */const STATIC_PAGES=[\"interface\",\"infrastructure\",\"security\"];const COLUMN=/^Column \\d+$/;const KEY=\"cc-algorithm-count\";const ONES=[\"zero\",\"one\",\"two\",\"three\",\"four\",\"five\",\"six\",\"seven\",\"eight\",\"nine\",\"ten\",\"eleven\",\"twelve\",\"thirteen\",\"fourteen\",\"fifteen\",\"sixteen\",\"seventeen\",\"eighteen\",\"nineteen\"];const TENS=[\"\",\"\",\"twenty\",\"thirty\",\"forty\",\"fifty\",\"sixty\",\"seventy\",\"eighty\",\"ninety\"];const toWord=n=>n<20?ONES[n]:n<100?TENS[Math.floor(n/10)]+(n%10?\"-\"+ONES[n%10]:\"\"):String(n);const NUM=\"(\\\\d+|(?:twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety)(?:-[a-z]+)?|\"+ONES.join(\"|\")+\")\";const TOTAL_RE=new RegExp(`\\\\b${NUM}(\\\\s+(?:algorithms in production|jobs across the workflow))`,\"gi\");const COLUMN_RE=new RegExp(`^\\\\s*${NUM}(\\\\s+algorithms?)\\\\s*$`,\"i\");// Same form as the editor wrote: digits stay digits, words stay words, capital stays capital.\nfunction format(token,n){if(/^\\d+$/.test(token))return String(n);const w=toWord(n);return token[0]===token[0].toUpperCase()?w[0].toUpperCase()+w.slice(1):w;}function slugOf(href){try{const m=new URL(href,location.href).pathname.match(/^\\/technology\\/([^/]+)\\/?$/);return m&&!STATIC_PAGES.includes(m[1])?m[1]:null;}catch{return null;}}function countIn(el){const slugs=new Set;for(const a of el.querySelectorAll(\"a[href]\")){const s=slugOf(a.getAttribute(\"href\")||\"\");if(s)slugs.add(s);}return slugs.size;}// The cards on /technology are the exact count; this is only non-zero on that page.\nfunction countFromColumns(){const slugs=new Set;for(const col of document.querySelectorAll(\"[data-framer-name]\")){if(!COLUMN.test(col.getAttribute(\"data-framer-name\")||\"\"))continue;for(const a of col.querySelectorAll(\"a[href]\")){const s=slugOf(a.getAttribute(\"href\")||\"\");if(s)slugs.add(s);}}return slugs.size;}let pending=null;function countFromSitemap(){pending??=fetch(\"/sitemap.xml\",{credentials:\"same-origin\"}).then(r=>r.ok?r.text():\"\").then(xml=>{const slugs=new Set;for(const m of xml.matchAll(/<loc>([^<]+)<\\/loc>/g)){const s=slugOf(m[1]);if(s)slugs.add(s);}return slugs.size||null;}).catch(()=>null);return pending;}const remember=n=>{try{localStorage.setItem(KEY,String(n));}catch{}};const recall=()=>{try{return Number(localStorage.getItem(KEY))||18;}catch{return 18;}};function rewrite(scope,total){const walker=document.createTreeWalker(scope,NodeFilter.SHOW_TEXT);for(let node=walker.nextNode();node;node=walker.nextNode()){const text=node.nodeValue||\"\";let next=text;if(total)next=next.replace(TOTAL_RE,(_m,num,rest)=>format(num,total)+rest);let column=node.parentElement;while(column&&!COLUMN.test(column.getAttribute(\"data-framer-name\")||\"\"))column=column.parentElement;if(column&&COLUMN_RE.test(next)){const n=countIn(column);if(n)next=next.replace(COLUMN_RE,(_m,num,rest)=>format(num,n)+rest);}if(next!==text)node.nodeValue=next;}}export default function AlgorithmCount(props){const ref=useRef(null);const onCanvas=RenderTarget.current()===RenderTarget.canvas;useEffect(()=>{const el=ref.current;if(onCanvas||!el)return;// the layer to rewrite: the parent the component was placed in, or further up\nlet scope=el.parentElement;for(let i=1;i<(props.scopeUp??1)&&scope?.parentElement;i++)scope=scope.parentElement;if(!scope)return;let total=recall();let raf=0;const run=()=>{cancelAnimationFrame(raf);raf=requestAnimationFrame(()=>{obs.disconnect();rewrite(scope,total);obs.observe(scope,{childList:true,subtree:true,characterData:true});});};const obs=new MutationObserver(run);const local=countFromColumns();if(local){total=local;remember(local);}run();if(!local)countFromSitemap().then(n=>{if(n){total=n;remember(n);run();}});return()=>{obs.disconnect();cancelAnimationFrame(raf);};},[onCanvas,props.scopeUp]);return /*#__PURE__*/_jsx(\"span\",{ref:ref,\"aria-hidden\":\"true\",style:{display:\"none\"}});}AlgorithmCount.displayName=\"Algorithm Count\";addPropertyControls(AlgorithmCount,{scopeUp:{type:ControlType.Number,title:\"Scope levels\",defaultValue:1,min:1,max:8,step:1,description:\"How many parent layers up to look for count text. 1 = the layer this sits in.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"AlgorithmCount\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./AlgorithmCount.map"],"mappings":"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"}