vanilla-breeze 0.1.1 → 0.1.2
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/cdn/components/analytics-panel.js +34 -0
- package/dist/cdn/components/author-index.js +3 -0
- package/dist/cdn/components/brand-mark.js +2 -0
- package/dist/cdn/components/carousel-wc.js +1 -1
- package/dist/cdn/components/color-palette.js +13 -7
- package/dist/cdn/components/comment-wc.js +2 -0
- package/dist/cdn/components/consent-banner.js +1 -1
- package/dist/cdn/components/content-lens.js +2 -0
- package/dist/cdn/components/font-pairer.js +108 -0
- package/dist/cdn/components/geo-map.js +7 -7
- package/dist/cdn/components/gradient-builder.js +52 -0
- package/dist/cdn/components/highlight-wc.js +3 -0
- package/dist/cdn/components/manifest.json +93 -21
- package/dist/cdn/components/markdown-viewer.js +3 -3
- package/dist/cdn/components/motion-specimen.js +21 -0
- package/dist/cdn/components/note-wc.js +3 -0
- package/dist/cdn/components/notification-wc.js +37 -0
- package/dist/cdn/components/page-info.js +55 -24
- package/dist/cdn/components/page-toc.js +1 -1
- package/dist/cdn/components/popularity-index.js +9 -0
- package/dist/cdn/components/print-page.js +1 -1
- package/dist/cdn/components/recently-visited.js +3 -0
- package/dist/cdn/components/review-surface.js +11 -11
- package/dist/cdn/components/selection-menu.js +2 -0
- package/dist/cdn/components/semantic-palette.js +30 -0
- package/dist/cdn/components/settings-panel.js +55 -51
- package/dist/cdn/components/share-wc.js +2 -2
- package/dist/cdn/components/spacing-specimen.js +5 -5
- package/dist/cdn/components/split-surface.js +1 -1
- package/dist/cdn/components/text-reader.js +2 -2
- package/dist/cdn/components/theme-export.js +18 -0
- package/dist/cdn/components/theme-picker.js +58 -58
- package/dist/cdn/components/token-specimen.js +25 -20
- package/dist/cdn/components/topic-map.js +3 -0
- package/dist/cdn/components/trust-filter.js +4 -0
- package/dist/cdn/components/type-specimen.js +16 -13
- package/dist/cdn/components/watch-wc.js +3 -0
- package/dist/cdn/packs/design-system.full.js +124 -47
- package/dist/cdn/packs/effects.full.js +1 -1
- package/dist/cdn/packs/kawaii.full.css +1 -1
- package/dist/cdn/packs/kawaii.full.js +1 -1
- package/dist/cdn/packs/kawaii.theme.css +1 -1
- package/dist/cdn/packs/manifest.json +8 -38
- package/dist/cdn/packs/ui.full.css +1 -1
- package/dist/cdn/packs/ui.full.js +50 -50
- package/dist/cdn/packs/ux-planning.full.js +36 -36
- package/dist/cdn/themes/alpha1999.css +1 -1
- package/dist/cdn/themes/brutalist.css +1 -1
- package/dist/cdn/themes/claymorphism.css +1 -1
- package/dist/cdn/themes/genai.css +1 -1
- package/dist/cdn/themes/kawaii.css +1 -1
- package/dist/cdn/themes/magna.css +1 -1
- package/dist/cdn/themes/manifest.json +12 -12
- package/dist/cdn/themes/nes.css +1 -1
- package/dist/cdn/themes/neumorphism.css +1 -1
- package/dist/cdn/themes/rough.css +1 -1
- package/dist/cdn/themes/startup.css +1 -1
- package/dist/cdn/themes/super2026.css +1 -1
- package/dist/cdn/themes/win9x.css +1 -1
- package/dist/cdn/vanilla-breeze-core.css +1 -1
- package/dist/cdn/vanilla-breeze-core.js +119 -47
- package/dist/cdn/vanilla-breeze-extras.js +154 -74
- package/dist/cdn/vanilla-breeze.css +1 -1
- package/dist/cdn/vanilla-breeze.js +605 -249
- package/package.json +8 -6
- package/dist/cdn/packs/retro.bundle.js +0 -2
- package/dist/cdn/packs/retro.components.js +0 -1
- package/dist/cdn/packs/retro.effects.css +0 -2
- package/dist/cdn/packs/retro.effects.js +0 -16
- package/dist/cdn/packs/retro.full.css +0 -5
- package/dist/cdn/packs/retro.full.js +0 -16
- package/dist/cdn/packs/retro.theme.css +0 -2
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var B=window.matchMedia("(prefers-reduced-motion: reduce)");var k=new Map;function E(s,t,e={}){let i=e.priority??10,n={impl:t,bundle:e.bundle,contract:e.contract,priority:i},a=k.get(s);if(customElements.get(s)){if(!a||a.priority>=i){a&&a.priority===i&&a.impl!==t&&console.warn(`[VB Bundle] Tag <${s}> already registered by "${a.bundle}" (priority ${a.priority}). Skipping "${e.bundle}".`);return}console.warn(`[VB Bundle] Tag <${s}> defined by "${a.bundle}" cannot be replaced (customElements.define is permanent). "${e.bundle}" has higher priority but arrived late.`);return}if(a&&a.priority>=i){a.priority===i&&console.warn(`[VB Bundle] Tag <${s}> already registered by "${a.bundle}". Skipping "${e.bundle}" (first wins at equal priority).`);return}k.set(s,n),customElements.define(s,t)}var y=class extends HTMLElement{#i=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let t of this.#i)t();this.#i=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(t,e,i,n){t.addEventListener(e,i,n),this.#i.push(()=>t.removeEventListener(e,i,n))}setup(){}teardown(){}};function q(){let s=globalThis.localStorage;if(!s)throw new Error("VBStore: localStorage is not available in this environment");return{async getRaw(t){return s.getItem(t)},async setRaw(t,e){s.setItem(t,e)},async removeRaw(t){s.removeItem(t)},async keys(t){let e=[];for(let i=0;i<s.length;i++){let n=s.key(i);n&&n.startsWith(t)&&e.push(n)}return e}}}var m=null;function u(){return m||(m=q()),m}function g(s,t){if(typeof s!="string"||!s)throw new TypeError("VBStore: namespace must be a non-empty string");if(typeof t!="string"||!t)throw new TypeError("VBStore: key must be a non-empty string");return`vb:${s}:${t}`}function A(s){if(typeof s!="string"||!s)throw new TypeError("VBStore: namespace must be a non-empty string");return`vb:${s}:`}function $(s){try{let t=JSON.parse(s);if(t&&typeof t=="object"&&typeof t.timestamp=="number")return t}catch{}return null}var h={configure(s={}){m=s.backend??null},async set(s,t,e){let i={data:e,timestamp:Date.now()};await u().setRaw(g(s,t),JSON.stringify(i))},async get(s,t,e){let i=await u().getRaw(g(s,t));if(i==null)return null;let n=$(i);return!n||e?.maxAge!=null&&Date.now()-n.timestamp>e.maxAge?null:n.data},async remove(s,t){await u().removeRaw(g(s,t))},async list(s){let t=A(s),e=await u().keys(t),i=[];for(let n of e){let a=await u().getRaw(n);if(a==null)continue;let r=$(a);r&&i.push({key:n.slice(t.length),data:r.data,timestamp:r.timestamp})}return i},async clear(s){let t=A(s),e=await u().keys(t);for(let i of e)await u().removeRaw(i)},async clearAll(){let s=await u().keys("vb:");for(let t of s)await u().removeRaw(t)},async setMany(s,t){for(let[e,i]of t)await h.set(s,e,i)}};var d={baseUrl:"/go",headers:{},services:{}},b=class extends Error{constructor(t,e,i,n){super(`VBService(${i}): ${t} ${n}`),this.name="VBServiceError",this.status=t,this.body=e,this.role=i,this.path=n}};function C(s,t){if(!t)return s;let e=s??new URLSearchParams;for(let[i,n]of Object.entries(t))n!=null&&e.set(i,String(n));return e}async function x(s){if((s.headers.get("content-type")??"").includes("application/json"))try{return await s.json()}catch{return null}try{return await s.text()}catch{return null}}var w=class s{static configure(t={}){d={baseUrl:t.baseUrl??d.baseUrl,headers:{...d.headers,...t.headers??{}},services:{...d.services,...t.services??{}}}}static resolve(t){if(!t||typeof t!="string")throw new TypeError("VBService: role must be a non-empty string");return d.services[t]?T(d.services[t]):d.baseUrl?`${T(d.baseUrl)}/${t}`:`/go/${t}`}static _reset(){d={baseUrl:"/go",headers:{},services:{}}}constructor(t){if(!t||typeof t!="string")throw new TypeError("VBService: role must be a non-empty string");this.role=t}async get(t,e){return this.#i("GET",t,{params:e})}async post(t,e){return this.#i("POST",t,{body:e})}async patch(t,e){return this.#i("PATCH",t,{body:e})}async delete(t){return this.#i("DELETE",t,{})}async#i(t,e,i){let n=s.resolve(this.role),a=e?e.startsWith("/")?e:`/${e}`:"",r=new URL(`${n}${a}`,globalThis.location?.origin??"http://localhost"),l=C(r.searchParams,i.params);l&&(r.search=l.toString());let o={method:t,headers:{...d.headers}};i.body!==void 0&&(o.body=JSON.stringify(i.body),o.headers["content-type"]="application/json");let p=r.toString(),f=await fetch(p,o),S=await x(f);if(!f.ok)throw new b(f.status,S,this.role,`${a||"/"}`);return S}};function T(s){return s.endsWith("/")?s.slice(0,-1):s}var N={update:"package",alert:"alert-triangle",watch:"eye",system:"settings",message:"mail",stewardship:"shield"};function c(s){return String(s??"").replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t])}var v=class extends y{#i="panel";#w=null;#e=null;#t=null;#a=null;#s=new Set;#f=[];#o=!1;#r=null;#g=new Set;#p="all";#n=[];setup(){return this.#i=this.getAttribute("mode")==="banner"?"banner":"panel",this.#i==="banner"?this.#v():this.#k()}teardown(){this.#r!=null&&(clearInterval(this.#r),this.#r=null)}async#v(){let t=this.getAttribute("persist");if(t||console.warn("[notification-wc] banner mode requires a persist attribute"),this.dataset.mode="banner",this.dataset.variant=this.getAttribute("variant")||"info",this.dataset.position=this.getAttribute("position")||"top",t){let i=Number(this.getAttribute("expires")??""),n=Number.isFinite(i)&&i>0?i*864e5:void 0,a=await h.get("notifications",t,n?{maxAge:n}:void 0);if(a&&a.dismissed){this.hidden=!0;return}}let e=this.querySelector('[value="dismiss"], [data-dismiss]');e&&(this.#w=e,this.listen(e,"click",this.#S))}#S=async t=>{t.preventDefault();let e=this.getAttribute("persist");e&&await h.set("notifications",e,{dismissed:!0}),this.dispatchEvent(new CustomEvent("notification-wc:dismiss",{bubbles:!0,composed:!0,detail:{id:e}})),this.hidden=!0};async#k(){if(this.dataset.mode="panel",await this.#E(),this.#A(),this.#$(),await this.#c(),this.#u(),this.listen(document,"click",this.#B),this.listen(document,"keydown",this.#L),this.listen(document,"page-watch:add",()=>this.#c()),this.listen(document,"page-watch:remove",()=>this.#c()),this.getAttribute("src")){await this.#m();let t=Number(this.getAttribute("poll"));Number.isFinite(t)&&t>0&&(this.#r=setInterval(()=>this.#m(),t))}}async#E(){let t=this.getAttribute("storage-key")||"notifications",e=await h.get(t,"read-ids");Array.isArray(e)&&(this.#s=new Set(e.filter(i=>typeof i=="string")))}async#b(){let t=this.getAttribute("storage-key")||"notifications";await h.set(t,"read-ids",Array.from(this.#s))}#A(){if(this.#e=this.querySelector(":scope > [data-trigger]"),this.#e){let t=this.#e.querySelector(".notification-badge");t||(t=document.createElement("span"),t.className="notification-badge",t.hidden=!0,this.#e.appendChild(t))}else{let t=document.createElement("button");t.type="button",t.setAttribute("data-trigger",""),t.className="notification-trigger",t.setAttribute("aria-label","Notifications"),t.innerHTML='<icon-wc name="bell" size="sm"></icon-wc><span class="notification-badge" hidden>0</span>',this.#e=t,this.prepend(t)}this.#a=this.#e.querySelector(".notification-badge"),this.#e.setAttribute("aria-haspopup","dialog"),this.#e.setAttribute("aria-expanded","false"),this.listen(this.#e,"click",this.#N)}#$(){this.#t=document.createElement("div"),this.#t.className="notification-panel",this.#t.setAttribute("role","dialog"),this.#t.setAttribute("aria-label","Notifications"),this.#t.hidden=!0;let t=`notification-panel-${crypto.randomUUID().slice(0,8)}`;this.#t.id=t,this.#e?.setAttribute("aria-controls",t),this.#t.innerHTML=`
|
|
2
|
+
<header class="notification-header">
|
|
3
|
+
<strong>Notifications</strong>
|
|
4
|
+
<button type="button" class="notification-mark-all">Mark all read</button>
|
|
5
|
+
</header>
|
|
6
|
+
<nav class="notification-tabs" role="tablist" aria-label="Notification categories">
|
|
7
|
+
<button type="button" role="tab" data-tab="all" aria-selected="true">All</button>
|
|
8
|
+
<button type="button" role="tab" data-tab="watching" aria-selected="false">Watching <span class="notification-tab-count" hidden>0</span></button>
|
|
9
|
+
</nav>
|
|
10
|
+
<ul class="notification-list" role="list" data-tab-panel="all"></ul>
|
|
11
|
+
<ul class="notification-watch-list" role="list" data-tab-panel="watching" hidden></ul>
|
|
12
|
+
<footer class="notification-footer" hidden>
|
|
13
|
+
<em>No notifications</em>
|
|
14
|
+
</footer>
|
|
15
|
+
`,this.appendChild(this.#t);let e=this.#t.querySelector(".notification-mark-all");e&&this.listen(e,"click",this.#R);for(let i of this.#t.querySelectorAll('[role="tab"]'))this.listen(i,"click",this.#C);this.#d()}#l(){let t=Array.from(this.querySelectorAll(":scope > article")),e=new Map;for(let i of t){let n=i.getAttribute("data-id")||i.id||`static-${e.size}`,a=i.getAttribute("data-type")||"update",r=i.getAttribute("data-date")||"",l=i.querySelector("h1, h2, h3, h4, h5, h6")?.textContent?.trim()||n,p=i.querySelector("p")?.textContent?.trim()||"",f=i.querySelector("a");e.set(n,{id:n,type:a,date:r,title:l,body:p,url:f?.getAttribute("href")||null,source:"static"})}for(let i of this.#f)if(!(!i||typeof i.id!="string")){if(i.dismissed){e.delete(i.id);continue}e.set(i.id,{...e.get(i.id),...i,source:"dynamic"})}return Array.from(e.values()).sort((i,n)=>{let a=i.date?Date.parse(i.date):0;return(n.date?Date.parse(n.date):0)-a})}#d(){if(!this.#t)return;let t=this.#t.querySelector(".notification-list"),e=this.#t.querySelector(".notification-footer");if(!t)return;let i=this.#l();t.innerHTML=i.map(n=>this.#T(n)).join(""),e&&(e.hidden=i.length>0);for(let n of t.querySelectorAll("[data-notification-id]"))this.listen(n,"click",this.#M);this.#u()}#T(t){let e=N[t.type]||"bell",i=this.#s.has(t.id),n=t.date?new Date(t.date).toLocaleString():"",a=`
|
|
16
|
+
<icon-wc class="notification-type-icon" name="${c(e)}" size="sm"></icon-wc>
|
|
17
|
+
<div class="notification-body">
|
|
18
|
+
<h4>${c(t.title)}</h4>
|
|
19
|
+
${t.body?`<p>${c(t.body)}</p>`:""}
|
|
20
|
+
${n?`<time datetime="${c(t.date)}">${c(n)}</time>`:""}
|
|
21
|
+
</div>
|
|
22
|
+
`,r=t.url?"a":"button",l=t.url?`href="${c(t.url)}"`:'type="button"';return`<li role="listitem" data-notification-id="${c(t.id)}" data-type="${c(t.type||"update")}"${i?" data-read":""}>
|
|
23
|
+
<${r} class="notification-row" ${l}>${a}</${r}>
|
|
24
|
+
</li>`}#u(){if(!this.#a)return;let e=this.#l().filter(i=>!this.#s.has(i.id)).length;e>0?(this.#a.textContent=String(e),this.#a.hidden=!1,this.#e?.querySelector("icon-wc")?.setAttribute("name","bell-dot")):(this.#a.hidden=!0,this.#e?.querySelector("icon-wc")?.setAttribute("name","bell"))}async#c(){try{this.#n=await h.list("watches")}catch{this.#n=[]}this.#y()}#y(){if(!this.#t)return;let t=this.#t.querySelector(".notification-watch-list"),e=this.#t.querySelector(".notification-tab-count");if(t){if(t.innerHTML=this.#n.map(i=>this.#q(i)).join("")||`<li class="notification-empty"><em>You aren't watching any pages yet. Use the “Watch” button on a page to start.</em></li>`,e){let i=this.#n.length;i>0?(e.textContent=String(i),e.hidden=!1):e.hidden=!0}for(let i of t.querySelectorAll("[data-watch-unwatch]"))this.listen(i,"click",this.#x)}}#q(t){let e=t.data||{},i=e.url||t.key,n=e.title||i,a=e.lastChecked?new Date(e.lastChecked).toLocaleString():"\u2014",r=!!e.lastChanged;return`<li class="notification-watch-item"${r?" data-changed":""}>
|
|
25
|
+
<a class="notification-watch-row" href="${c(i)}">
|
|
26
|
+
<icon-wc class="notification-type-icon" name="eye" size="sm"></icon-wc>
|
|
27
|
+
<div class="notification-body">
|
|
28
|
+
<h4>${c(n)}${r?' <span class="notification-changed-badge">Changed</span>':""}</h4>
|
|
29
|
+
<p>${c(i)}</p>
|
|
30
|
+
<time>Last checked: ${c(a)}</time>
|
|
31
|
+
</div>
|
|
32
|
+
</a>
|
|
33
|
+
<button type="button" class="notification-unwatch" data-watch-unwatch data-watch-key="${c(t.key)}" aria-label="Unwatch ${c(n)}">
|
|
34
|
+
<icon-wc name="x" size="xs"></icon-wc>
|
|
35
|
+
</button>
|
|
36
|
+
</li>`}#C=t=>{let e=t.currentTarget.dataset.tab;if(!e||e===this.#p||(this.#p=e,!this.#t))return;for(let n of this.#t.querySelectorAll('[role="tab"]')){let a=n.dataset.tab===e;n.setAttribute("aria-selected",a?"true":"false")}for(let n of this.#t.querySelectorAll("[data-tab-panel]"))n.hidden=n.dataset.tabPanel!==e;let i=this.#t.querySelector(".notification-footer");i&&(i.hidden=!0)};#x=async t=>{t.preventDefault(),t.stopPropagation();let i=t.currentTarget.getAttribute("data-watch-key");if(!i)return;let n=this.#n.find(a=>a.key===i);await h.remove("watches",i),this.#n=this.#n.filter(a=>a.key!==i),this.#y(),this.dispatchEvent(new CustomEvent("page-watch:remove",{bubbles:!0,composed:!0,detail:{url:n?.data?.url||i,subscriptionId:n?.data?.subscriptionId||null}}))};#N=t=>{t.stopPropagation(),this.#o?this.#h():this.#I()};#B=t=>{this.#o&&!this.contains(t.target)&&this.#h()};#L=t=>{t.key==="Escape"&&this.#o&&(t.preventDefault(),this.#h(),this.#e?.focus())};#M=async t=>{let e=t.currentTarget.closest("[data-notification-id]");if(!e)return;let i=e.getAttribute("data-notification-id");i&&(this.#s.has(i)||(this.#s.add(i),e.setAttribute("data-read",""),await this.#b(),this.#u(),this.dispatchEvent(new CustomEvent("notification-wc:read",{bubbles:!0,composed:!0,detail:{id:i}}))))};#R=async()=>{let t=this.#l();for(let e of t)this.#s.add(e.id);await this.#b(),this.#d();for(let e of t)this.dispatchEvent(new CustomEvent("notification-wc:read",{bubbles:!0,composed:!0,detail:{id:e.id}}))};#I(){this.#t&&(this.#o=!0,this.#t.hidden=!1,this.#e?.setAttribute("aria-expanded","true"),this.#c(),this.dispatchEvent(new CustomEvent("notification-wc:open",{bubbles:!0,composed:!0})))}#h(){this.#t&&(this.#o=!1,this.#t.hidden=!0,this.#e?.setAttribute("aria-expanded","false"),this.dispatchEvent(new CustomEvent("notification-wc:close",{bubbles:!0,composed:!0})))}async#m(){let t=this.getAttribute("src");if(!t)return;let e,i=0;try{if(t.startsWith("http")||t.startsWith("/")){let o=await fetch(t,{headers:{accept:"application/json"}});if(i=o.status,!o.ok)throw new Error(`${o.status}`);e=await o.json()}else e=await new w(t).get("/")}catch(o){let p=o instanceof b?o.status:i;if(p===404||p===503)return;let f=o instanceof b?`${o.status}`:String(o);console.warn("[notification-wc] failed to fetch",t,f);return}let n=Array.isArray(e)?e:Array.isArray(e?.notifications)?e.notifications:[],a=this.#g,r=a.size===0,l=this.hasAttribute("toast-new")?document.querySelector("toast-msg"):null;for(let o of n)o?.id&&(a.has(o.id)||(this.dispatchEvent(new CustomEvent("notification-wc:new",{bubbles:!0,composed:!0,detail:{notification:o}})),!r&&l&&typeof l.show=="function"&&l.show({message:o.title||o.body||"New notification",variant:o.type==="alert"||o.type==="stewardship"?"warning":"info",duration:5e3})),a.add(o.id));this.#f=n,this.#d()}};E("notification-wc",v);export{v as NotificationWc};
|
|
37
|
+
//# sourceMappingURL=notification-wc.js.map
|
|
@@ -1,51 +1,82 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Y=window.matchMedia("(prefers-reduced-motion: reduce)");var M=new Map;function x(t,e,r={}){let i=r.priority??10,o={impl:e,bundle:r.bundle,contract:r.contract,priority:i},n=M.get(t);if(customElements.get(t)){if(!n||n.priority>=i){n&&n.priority===i&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${t}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${r.bundle}".`);return}console.warn(`[VB Bundle] Tag <${t}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${r.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=i){n.priority===i&&console.warn(`[VB Bundle] Tag <${t}> already registered by "${n.bundle}". Skipping "${r.bundle}" (first wins at equal priority).`);return}M.set(t,o),customElements.define(t,e)}var y=class extends HTMLElement{#t=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#t)e();this.#t=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,r,i,o){e.addEventListener(r,i,o),this.#t.push(()=>e.removeEventListener(r,i,o))}setup(){}teardown(){}};var B="https://vanilla-breeze.com/specs/canonical-document-v1",F=new Set(["SCRIPT","STYLE","TEMPLATE","NOSCRIPT","NAV","ASIDE","HEADER","FOOTER","FIGCAPTION","PAGE-INFO","CHANGE-SET","PAGE-TOC","PAGE-TOOLS","PAGE-STATS","CONTENT-LENS","BUTTON","DIALOG","MENU","FORM","DEL"]),U=new Set(["ARTICLE","SECTION","ASIDE","NAV","HEADER","FOOTER","DIV","MAIN","HGROUP","H1","H2","H3","H4","H5","H6","P","BLOCKQUOTE","PRE","HR","OL","UL","LI","DL","DT","DD","TABLE","THEAD","TBODY","TFOOT","TR","TD","TH","CAPTION","FIGURE","DETAILS","SUMMARY","ADDRESS","FORM","FIELDSET","LEGEND"]),V=new Set(["PRE","TEXTAREA"]);function _(t){return!t||t.nodeType!==1?!1:!!(F.has(t.tagName)||t.hasAttribute("hidden")||t.getAttribute("aria-hidden")==="true"||t.getAttribute("data-signable")==="false")}function D(t,e,r){if(_(t))return;let i=U.has(t.tagName),o=r||V.has(t.tagName);for(let n of t.childNodes)if(n.nodeType===3){let s=n.nodeValue||"";if(!s)continue;if(o)N(e,s.normalize("NFC"));else{let a=s.normalize("NFC").replace(/\s+/g," ");if(a===""||a===" "&&(e.text===""||e.text.endsWith(" ")||e.text.endsWith(`
|
|
2
|
+
`)))continue;N(e,a)}}else if(n.nodeType===1){if(n.tagName==="BR"){w(e,`
|
|
3
|
+
`);continue}D(n,e,o)}i&&w(e,`
|
|
4
|
+
|
|
5
|
+
`),t.tagName==="HR"&&w(e,`
|
|
6
|
+
|
|
7
|
+
`)}function N(t,e){t.text+=e}function w(t,e){if(!t.text.endsWith(e)){if(e===`
|
|
8
|
+
|
|
9
|
+
`&&t.text.endsWith(`
|
|
10
|
+
`)){t.text=t.text.replace(/\n+$/,"")+`
|
|
11
|
+
|
|
12
|
+
`;return}e===`
|
|
13
|
+
`&&t.text.endsWith(`
|
|
14
|
+
|
|
15
|
+
`)||(t.text+=e)}}function G(t){let e=[...t.querySelectorAll("[data-signable]")],r=e.filter(o=>!e.some(n=>n!==o&&n.contains(o))),i={text:""};for(let o of r)D(o,i,!1);return i.text.replace(/^\s+/,"").replace(/\s+$/,"")}function u(t,e){return t.querySelector(`meta[name="${$(e)}"]`)?.getAttribute("content")||""}function E(t,e){return t.querySelector(`meta[property="${$(e)}"]`)?.getAttribute("content")||""}function z(t,e){return t.querySelector(`meta[itemprop="${$(e)}"]`)?.getAttribute("content")||""}function R(t,e){return t.querySelector(`link[rel="${$(e)}"]`)?.getAttribute("href")||""}function $(t){return String(t).replace(/[^a-zA-Z0-9:_\-/]/g,"")}function j(t){if(!t)return"";try{let e=new URL(t);e.search="",e.hash="";let r=`${e.protocol}//${e.hostname.toLowerCase()}`;return e.port&&(r+=`:${e.port}`),r+=e.pathname,r}catch{return t}}function O(t){if(!t)return"";let e=String(t).match(/^(\d{4}-\d{2}-\d{2})/);return e?e[1]:""}function K(t){return E(t,"og:title")||t.title||""}function W(t){let e=u(t,"keywords");return e?e.split(",").map(r=>r.trim()).filter(Boolean):[]}function X(t){return R(t,"license")||u(t,"license")}function H(t,e={}){let r=e.url??t?.location?.href??"",i=O(E(t,"article:published_time")),o=O(u(t,"last-modified")||E(t,"article:modified_time"));return{"@context":B,"@version":1,url:j(r),title:K(t),author:u(t,"author"),authorUrl:E(t,"article:author")||R(t,"author"),published:i,modified:o,version:z(t,"version"),keywords:W(t),topic:u(t,"vb:topic"),provenance:u(t,"vb:provenance"),review:u(t,"vb:review"),status:u(t,"vb:status"),license:X(t),content:G(t)}}function P(t){return JSON.stringify(t)}var C=class t extends y{setup(){this.hasAttribute("auto")&&this.#l(),this.#t(),this.#r(),this.#i(),this.#o()}#t(){for(let e of this.querySelectorAll("time[data-relative]")){let r=e.getAttribute("datetime");if(!r)continue;let i=t.#n(new Date(r));i&&(e.textContent=i)}}static#n(e){let i=Date.now()-e.getTime();if(i<0)return null;let o=Math.floor(i/1e3),n=Math.floor(o/60),s=Math.floor(n/60),a=Math.floor(s/24);return a>365?`${Math.floor(a/365)} year${Math.floor(a/365)!==1?"s":""} ago`:a>30?`${Math.floor(a/30)} month${Math.floor(a/30)!==1?"s":""} ago`:a>0?`${a} day${a!==1?"s":""} ago`:s>0?`${s} hour${s!==1?"s":""} ago`:n>0?`${n} minute${n!==1?"s":""} ago`:"just now"}#r(){let e=this.querySelector("[data-reading-time]");if(!e)return;let r=document.querySelectorAll("[data-signable]");if(!r.length)return;let i=0;for(let n of r){let s=n.textContent?.trim()||"";i+=s.split(/\s+/).filter(Boolean).length}let o=Math.max(1,Math.ceil(i/200));e.textContent=`~${o} min`}#i(){let e=!!document.querySelector('meta[name="vb:provenance"], meta[name="author"]'),r=e?"declared":"undeclared",i=this.querySelector(".page-info-badge");i&&i.setAttribute("data-trust",r),this.dispatchEvent(new CustomEvent("page-info:verified",{detail:{status:r,tier:e?1:0},bubbles:!0}))}async#o(){let r=document.querySelector('meta[name="vb:signature"]')?.content;if(!r)return;let i=document.querySelector('meta[name="vb:signature-algorithm"]')?.content;if(i&&i!=="ECDSA-P256-SHA256"){this.#e("failed",{reason:`unsupported-algorithm:${i}`});return}let o=document.querySelector('link[rel="author-key"]')?.getAttribute("href");if(!o){this.#e("failed",{reason:"missing-author-key"});return}let n;try{let c=new URL(o,document.baseURI),l=await fetch(c,{credentials:"omit"});if(!l.ok)throw new Error(`status ${l.status}`);let d=await l.json(),h={kty:d.kty,crv:d.crv,x:d.x,y:d.y,use:d.use||"sig",key_ops:["verify"]};n=await crypto.subtle.importKey("jwk",h,{name:"ECDSA",namedCurve:"P-256"},!1,["verify"])}catch(c){this.#e("key-unavailable",{reason:c.message});return}let s;try{let c=document.querySelector('link[rel="canonical"]')?.href||document.location.href;s=P(H(document,{url:c}))}catch(c){this.#e("failed",{reason:`canonicalize:${c.message}`});return}let a;try{let c=new TextEncoder().encode(s),l=Uint8Array.from(atob(r),d=>d.charCodeAt(0));a=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},n,l,c)}catch(c){this.#e("failed",{reason:`verify:${c.message}`});return}this.#e(a?"verified":"failed",{reason:a?"ok":"mismatch"})}#e(e,r={}){let o={undeclared:0,declared:1,"domain-anchored":2,verified:3,failed:-1,"key-unavailable":-2}[e]??0,n=this.querySelector(".page-info-badge");if(n){n.setAttribute("data-trust",e);let s=n.getAttribute("aria-label")||"";e==="verified"&&!s.includes("verified")?n.setAttribute("aria-label",`${s} \u2014 verified`.trim()):e==="failed"?n.setAttribute("aria-label",`${s} \u2014 verification failed`.trim()):e==="key-unavailable"&&n.setAttribute("aria-label",`${s} \u2014 author key unavailable`.trim())}this.dispatchEvent(new CustomEvent("page-info:verified",{detail:{status:e,tier:o,...r},bubbles:!0}))}static#a={human:"Human written","ai-assisted":"Human-written, AI-assisted","ai-generated":"AI-generated",translated:"Translated",synthesized:"Synthesized from sources",migrated:"Migrated content"};static#s={unreviewed:"Unreviewed","fact-checked":"Fact-checked","editor-reviewed":"Editor-reviewed"};static#c={draft:"Draft",published:"Published",archived:"Archived"};static#d(e){if(!e)return"";let r=String(e).trim().split(/\s+/).filter(Boolean);return r.length?r.map(o=>t.#a[o]||o).join(" \xB7 "):""}#l(){let e=f=>document.querySelector(`meta[name="${f}"]`)?.content,r=f=>document.querySelector(`meta[property="${f}"]`)?.content,i=f=>document.querySelector(`meta[itemprop="${f}"]`)?.content,o=f=>document.querySelector(`link[rel="${f}"]`)?.href,n=e("author"),s=r("article:author")||o("author"),a=e("last-modified")||r("article:modified_time"),c=r("article:published_time"),l=e("keywords"),d=e("license"),h=o("license"),p=i("version"),b=e("vb:provenance"),v=e("vb:review"),m=e("vb:status"),S=e("vb:ai-tools"),A=e("vb:topic"),L=e("vb:version-url"),g=t.#d(b),k=t.#s[v]||v||"",T=t.#c[m]||m||"",q=b||S||v||d,I=a||c||p;this.innerHTML=`
|
|
2
16
|
<details>
|
|
3
17
|
<summary>
|
|
4
|
-
${
|
|
18
|
+
${n?`
|
|
5
19
|
<span class="page-info-author">
|
|
6
|
-
${
|
|
20
|
+
${s?`<a href="${s}" rel="author">${n}</a>`:n}
|
|
7
21
|
</span>
|
|
8
22
|
<span class="page-info-sep" aria-hidden="true">·</span>
|
|
9
23
|
`:""}
|
|
10
|
-
${
|
|
11
|
-
<time datetime="${
|
|
24
|
+
${a?`
|
|
25
|
+
<time datetime="${a}" data-relative>${a}</time>
|
|
12
26
|
<span class="page-info-sep" aria-hidden="true">·</span>
|
|
13
27
|
`:""}
|
|
14
|
-
${
|
|
28
|
+
${g?`
|
|
15
29
|
<span class="page-info-badge"
|
|
16
|
-
data-provenance="${
|
|
30
|
+
data-provenance="${b||""}"
|
|
17
31
|
data-trust="declared"
|
|
18
|
-
aria-label="Content provenance: ${
|
|
19
|
-
${
|
|
32
|
+
aria-label="Content provenance: ${g}">
|
|
33
|
+
${g}
|
|
20
34
|
</span>
|
|
21
35
|
`:""}
|
|
36
|
+
${m&&m!=="published"?`
|
|
37
|
+
<span class="page-info-sep" aria-hidden="true">·</span>
|
|
38
|
+
<span class="page-info-badge" data-status="${m}">${T}</span>
|
|
39
|
+
`:""}
|
|
22
40
|
</summary>
|
|
23
41
|
<div class="page-info-panel">
|
|
24
|
-
${
|
|
42
|
+
${n?`
|
|
25
43
|
<section>
|
|
26
44
|
<h2 class="page-info-section-heading">Author</h2>
|
|
27
|
-
<p>${
|
|
45
|
+
<p>${s?`<a href="${s}" rel="author">${n}</a>`:n}</p>
|
|
28
46
|
</section>
|
|
29
47
|
`:""}
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
${I?`
|
|
49
|
+
<section>
|
|
50
|
+
<h2 class="page-info-section-heading">History</h2>
|
|
51
|
+
<dl>
|
|
52
|
+
${c?`<dl-item><dt>Published</dt><dd><time datetime="${c}" data-relative>${c}</time></dd></dl-item>`:""}
|
|
53
|
+
${a?`<dl-item><dt>Last updated</dt><dd><time datetime="${a}" data-relative>${a}</time></dd></dl-item>`:""}
|
|
54
|
+
${p?`<dl-item><dt>Version</dt><dd>${L?`<a href="${L}">${p}</a>`:p}</dd></dl-item>`:""}
|
|
55
|
+
</dl>
|
|
56
|
+
</section>
|
|
57
|
+
`:""}
|
|
58
|
+
${q?`
|
|
38
59
|
<section>
|
|
39
60
|
<h2 class="page-info-section-heading">How this was made</h2>
|
|
40
61
|
<dl>
|
|
41
|
-
|
|
42
|
-
${
|
|
43
|
-
${
|
|
44
|
-
${
|
|
62
|
+
${b?`<dl-item><dt>Authorship</dt><dd>${g}</dd></dl-item>`:""}
|
|
63
|
+
${S?`<dl-item><dt>AI tools used</dt><dd>${S}</dd></dl-item>`:""}
|
|
64
|
+
${k?`<dl-item><dt>Review</dt><dd>${k}</dd></dl-item>`:""}
|
|
65
|
+
${T?`<dl-item><dt>Status</dt><dd>${T}</dd></dl-item>`:""}
|
|
66
|
+
${d?`<dl-item><dt>License</dt><dd>${h?`<a href="${h}" rel="license">${d}</a>`:d}</dd></dl-item>`:""}
|
|
67
|
+
</dl>
|
|
68
|
+
</section>
|
|
69
|
+
`:""}
|
|
70
|
+
${l||A?`
|
|
71
|
+
<section>
|
|
72
|
+
<h2 class="page-info-section-heading">Topic</h2>
|
|
73
|
+
<dl>
|
|
74
|
+
${A?`<dl-item><dt>Subject</dt><dd>${A}</dd></dl-item>`:""}
|
|
75
|
+
${l?`<dl-item><dt>Keywords</dt><dd>${l}</dd></dl-item>`:""}
|
|
45
76
|
</dl>
|
|
46
77
|
</section>
|
|
47
78
|
`:""}
|
|
48
79
|
</div>
|
|
49
80
|
</details>
|
|
50
|
-
`}};
|
|
81
|
+
`}};x("page-info",C);export{C as PageInfo};
|
|
51
82
|
//# sourceMappingURL=page-info.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var w=window.matchMedia("(prefers-reduced-motion: reduce)");var g=new Map;function y(c,e,t={}){let i=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:i},n=g.get(c);if(customElements.get(c)){if(!n||n.priority>=i){n&&n.priority===i&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${c}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${c}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=i){n.priority===i&&console.warn(`[VB Bundle] Tag <${c}> already registered by "${n.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}g.set(c,s),customElements.define(c,e)}var f=class extends HTMLElement{#t=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#t)e();this.#t=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,i,s){e.addEventListener(t,i,s),this.#t.push(()=>e.removeEventListener(t,i,s))}setup(){}teardown(){}};var p=class extends f{#t;#i=[];#n=new Map;#c;#e;#r;#o=!1;setup(){requestAnimationFrame(()=>this.#a())}teardown(){this.#t?.disconnect(),clearTimeout(this.#r)}#a(){this.#o=this.#h(),this.#o?this.#u():this.#y(),this.#w(),this.#f(),this.#b()}#h(){return this.querySelector("nav, details")!==null}#u(){this.#e=this.querySelector("details");let e=this.querySelectorAll('a[href^="#"]');for(let t of e){let i=t.getAttribute("href");if(!i)continue;let s=i.slice(1);if(s){let n=document.getElementById(s);n&&(this.#i.push(n),this.#n.set(s,t),t.classList.contains("link")||t.classList.add("link"),t.addEventListener("click",a=>{a.preventDefault(),this.#d(n)}))}}}#f(){this.#c=window.matchMedia("(min-width: 64rem)"),this.listen(this.#c,"change",this.#m),this.listen(window,"resize",this.#p)}#m=e=>{e.matches&&this.#e&&(this.#e.open=!0)};#p=()=>{clearTimeout(this.#r),this.#r=setTimeout(()=>this.#s(),150)};#b(){this.listen(window,"hashchange",this.#g),this.#s()}#g=()=>{this.#s()};#s(){let e=window.location.hash.slice(1);e&&this.#n.has(e)&&this.#l(e)}#l(e){for(let i of this.#n.values())i.classList.remove("active"),i.removeAttribute("aria-current");let t=this.#n.get(e);t&&(t.classList.add("active"),t.setAttribute("aria-current","true"))}#y(){let e=(this.getAttribute("levels")||"h2,h3").split(",").map(r=>r.trim().toLowerCase()),t=this.getAttribute("scope")||"main",i=this.getAttribute("title")||"On this page",s=document.querySelector(t);if(!s||(this.#i=Array.from(s.querySelectorAll(e.join(","))).filter(r=>r.id).filter(r=>!r.hasAttribute("data-toc-ignore")&&!r.closest("[data-toc-ignore]")),this.#i.length===0))return;let n={depth:-1,children:[]},a=[n];for(let r of this.#i){let l=e.indexOf(r.tagName.toLowerCase());for(;a[a.length-1].depth>=l;)a.pop();let o={heading:r,depth:l,children:[]};a[a.length-1].children.push(o),a.push(o)}let b=r=>{let l=document.createElement("ul");l.className="list";for(let o of r){let h=document.createElement("li");h.className="item",h.dataset.level=String(o.depth);let d=document.createElement("a");d.href=`#${o.heading.id}`,d.className="link",d.textContent=this.#v(o.heading),d.addEventListener("click",v=>{v.preventDefault(),this.#d(o.heading)}),h.appendChild(d),o.children.length&&h.appendChild(b(o.children)),l.appendChild(h),this.#n.set(o.heading.id,d)}return l};this.#e=document.createElement("details"),this.#e.className="details",this.#e.open=!0;let m=document.createElement("summary");m.className="summary",m.textContent=i,this.#e.appendChild(m);let u=document.createElement("nav");u.className="nav",u.setAttribute("aria-label",i),u.appendChild(b(n.children)),this.#e.appendChild(u),this.appendChild(this.#e)}#v(e){let t=e.cloneNode(!0);return t.querySelectorAll(".heading-anchor").forEach(s=>s.remove()),t.textContent.trim()}#d(e){let t=new URL(window.location.href);t.hash=e.id,window.history.pushState(null,"",t),e.scrollIntoView({behavior:"smooth",block:"start"}),e.focus(),this.dispatchEvent(new CustomEvent("page-toc:navigate",{bubbles:!0,detail:{id:e.id}}))}#w(){if(this.#i.length===0)return;let e=new Set;this.#t=new IntersectionObserver(t=>{for(let i of t)i.isIntersecting?e.add(i.target.id):e.delete(i.target.id);this.#E(e)},{rootMargin:"-80px 0px -70% 0px",threshold:0});for(let t of this.#i)this.#t.observe(t)}#E(e){for(let t of this.#i)if(e.has(t.id)){this.#l(t.id);return}this.#s()}refresh(){this.#o||(this.innerHTML=""),this.#n.clear(),this.#i=[],this.#t?.disconnect(),this.#a()}};y("page-toc",p);export{p as PageToc};
|
|
2
2
|
//# sourceMappingURL=page-toc.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var w=window.matchMedia("(prefers-reduced-motion: reduce)");var m=new Map;function y(r,e,n={}){let o=n.priority??10,s={impl:e,bundle:n.bundle,contract:n.contract,priority:o},t=m.get(r);if(customElements.get(r)){if(!t||t.priority>=o){t&&t.priority===o&&t.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${t.bundle}" (priority ${t.priority}). Skipping "${n.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${t.bundle}" cannot be replaced (customElements.define is permanent). "${n.bundle}" has higher priority but arrived late.`);return}if(t&&t.priority>=o){t.priority===o&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${t.bundle}". Skipping "${n.bundle}" (first wins at equal priority).`);return}m.set(r,s),customElements.define(r,e)}var d=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#e)e();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,n,o,s){e.addEventListener(n,o,s),this.#e.push(()=>e.removeEventListener(n,o,s))}setup(){}teardown(){}};var f=class extends d{setup(){this.#e().catch(()=>{})}async#e(){let e=this.getAttribute("data-lens-src")||"/api/analytics/popular",n=this.getAttribute("window"),o=new URL(e,document.baseURI);n&&o.searchParams.set("window",n);let s=null;try{let i=await fetch(o,{credentials:"omit"});if(!i.ok)throw new Error(`status ${i.status}`);s=await i.json()}catch(i){this.#r(i.message);return}let t=Array.isArray(s?.pages)?s.pages:Array.isArray(s)?s:[];if(!t.length){this.#n();return}let a=this.getAttribute("data-meta-src"),c=null;if(a)try{let i=await fetch(a,{credentials:"omit"});if(i.ok){let l=await i.json(),u=Array.isArray(l)?l:l?.pages||[];c=new Map(u.map(h=>[h.url,h]))}}catch{}this.#t(t,c)}#t(e,n){let o=parseInt(this.getAttribute("limit")||"10",10)||10,s=e.slice(0,o),t=['<h2 class="popularity-heading">Most visited</h2>'];t.push('<ol class="popularity-list">');for(let a of s){let c=n?.get(a.url)||{},i=a.title||c.title||a.url,l=g(a.views??a.count??0),u=c.provenance?`<span class="popularity-prov" data-provenance="${b(c.provenance)}">${p(c.provenance)}</span>`:"";t.push(`<li><a href="${b(a.url)}">${p(i)}</a><small>${l} views${u?` \xB7 ${u}`:""}</small></li>`)}t.push("</ol>"),this.innerHTML=t.join(`
|
|
2
|
+
`)}#r(e){this.innerHTML=`
|
|
3
|
+
<h2 class="popularity-heading">Most visited</h2>
|
|
4
|
+
<p class="popularity-empty">Popularity data is unavailable right now${e?` (${p(e)})`:""}.</p>
|
|
5
|
+
`}#n(){this.innerHTML=`
|
|
6
|
+
<h2 class="popularity-heading">Most visited</h2>
|
|
7
|
+
<p class="popularity-empty">Not enough data yet to surface most-visited pages.</p>
|
|
8
|
+
`}};function g(r){let e=Number(r)||0;return e>=1e4?`${Math.round(e/1e3)}k`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function p(r){return String(r??"").replace(/[&<>]/g,e=>({"&":"&","<":"<",">":">"})[e])}function b(r){return String(r??"").replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}y("popularity-index",f);export{f as PopularityIndex};
|
|
9
|
+
//# sourceMappingURL=popularity-index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var h=window.matchMedia("(prefers-reduced-motion: reduce)");var l=new Map;function u(r,t,e={}){let i=e.priority??10,s={impl:t,bundle:e.bundle,contract:e.contract,priority:i},n=l.get(r);if(customElements.get(r)){if(!n||n.priority>=i){n&&n.priority===i&&n.impl!==t&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${e.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${e.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=i){n.priority===i&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}". Skipping "${e.bundle}" (first wins at equal priority).`);return}l.set(r,s),customElements.define(r,t)}var c=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let t of this.#e)t();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(t,e,i,s){t.addEventListener(e,i,s),this.#e.push(()=>t.removeEventListener(e,i,s))}setup(){}teardown(){}};var a=class extends c{#e;#t;#n=null;setup(){this.#n===null&&(this.#n=this.getAttribute("label")||this.textContent.trim()||"Print this page");let t=this.#n,e=this.hasAttribute("raw-toggle");this.innerHTML="",e&&this.setAttribute("role","group");let i=this.getAttribute("variant")||"icon";this.#e=document.createElement("button"),this.#e.type="button",this.#e.className="print-trigger",this.#e.setAttribute("aria-label",t);let s=i!=="label",n=i!=="icon";if(s){let o=document.createElement("icon-wc");o.setAttribute("name","printer"),o.setAttribute("size","sm"),o.setAttribute("aria-hidden","true"),this.#e.appendChild(o)}if(n){let o=document.createElement("span");o.textContent=t,this.#e.appendChild(o)}if(this.listen(this.#e,"click",this.#i),this.append(this.#e),e){let o=document.createElement("label");this.#t=document.createElement("input"),this.#t.type="checkbox";let d=document.createElement("span");d.textContent="Print without VB styles",o.append(this.#t,d),this.append(o)}}teardown(){this.#e=null,this.#t=null}#i=()=>{let t=this.#t?.checked;if(t&&document.documentElement.setAttribute("data-print-raw",""),window.print(),t){let e=()=>{document.documentElement.removeAttribute("data-print-raw"),window.removeEventListener("afterprint",e),clearTimeout(i)};window.addEventListener("afterprint",e,{once:!0});let i=setTimeout(e,5e3)}}};u("print-page",a);export{a as PrintPage};
|
|
2
2
|
//# sourceMappingURL=print-page.js.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var p=window.matchMedia("(prefers-reduced-motion: reduce)");var a=new Map;function l(r,e,s={}){let i=s.priority??10,t={impl:e,bundle:s.bundle,contract:s.contract,priority:i},n=a.get(r);if(customElements.get(r)){if(!n||n.priority>=i){n&&n.priority===i&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${s.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${s.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=i){n.priority===i&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}". Skipping "${s.bundle}" (first wins at equal priority).`);return}a.set(r,t),customElements.define(r,e)}var o=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#e)e();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,s,i,t){e.addEventListener(s,i,t),this.#e.push(()=>e.removeEventListener(s,i,t))}setup(){}teardown(){}};var c=class r extends o{static STORAGE_KEY="vb:recently-visited";static PAUSE_KEY="vb:recently-visited:paused";setup(){!this.hasAttribute("no-track")&&!this.#e()&&this.#o(),this.#n()}#e(){try{return localStorage.getItem(r.PAUSE_KEY)==="1"}catch{return!1}}#i(e){try{e?localStorage.setItem(r.PAUSE_KEY,"1"):localStorage.removeItem(r.PAUSE_KEY)}catch{}}#t(){try{let e=localStorage.getItem(r.STORAGE_KEY);if(!e)return[];let s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}#r(e){try{localStorage.setItem(r.STORAGE_KEY,JSON.stringify(e))}catch{}}#s(){let e=parseInt(this.getAttribute("limit")||"25",10);return Number.isFinite(e)&&e>0?e:25}#o(){let e=location.pathname+location.search,s=document.title,i=Date.now(),t=this.#t().filter(n=>n.url!==e);t.unshift({url:e,title:s,ts:i}),this.#r(t.slice(0,this.#s()))}#n(){let e=this.#t().slice(0,this.#s()),s=this.getAttribute("empty-text")||"No recently visited pages yet.",i=this.#e(),t=[];if(t.push('<header class="recently-visited-header">'),t.push('<h2 class="recently-visited-heading">Recently visited</h2>'),t.push('<menu class="recently-visited-actions">'),t.push(`<li><label class="recently-visited-pause"><input type="checkbox" data-recently-visited-pause${i?" checked":""}> <span>Pause</span></label></li>`),t.push('<li><button type="button" data-recently-visited-clear class="ghost">Clear</button></li>'),t.push("</menu>"),t.push("</header>"),t.push('<p class="recently-visited-explainer"><small>Stored on this device only. Never sent to a server.</small></p>'),e.length===0)t.push(`<p class="recently-visited-empty">${d(s)}</p>`);else{t.push('<ol class="recently-visited-list">');for(let n of e){let u=f(n.ts);t.push(`<li><a href="${h(n.url)}">${d(n.title||n.url)}</a><small>${u}</small></li>`)}t.push("</ol>")}this.innerHTML=t.join(`
|
|
2
|
+
`),this.#c()}#c(){let e=this.querySelector("[data-recently-visited-clear]");e&&e.addEventListener("click",()=>{this.#r([]),this.#n(),this.dispatchEvent(new CustomEvent("recently-visited:clear",{bubbles:!0}))});let s=this.querySelector("[data-recently-visited-pause]");s&&s.addEventListener("change",()=>{this.#i(s.checked)})}};function d(r){return String(r??"").replace(/[&<>]/g,e=>({"&":"&","<":"<",">":">"})[e])}function h(r){return String(r??"").replace(/[&<>"]/g,e=>({"&":"&","<":"<",">":">",'"':"""})[e])}function f(r){let e=Date.now()-r;return e<6e4?"just now":e<36e5?`${Math.floor(e/6e4)}m ago`:e<864e5?`${Math.floor(e/36e5)}h ago`:`${Math.floor(e/864e5)}d ago`}l("recently-visited",c);export{c as RecentlyVisited};
|
|
3
|
+
//# sourceMappingURL=recently-visited.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var v=`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
position: relative;
|
|
@@ -452,11 +452,11 @@ var h=`
|
|
|
452
452
|
background: #450a0a;
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
|
-
`;var w=window.matchMedia("(prefers-reduced-motion: reduce)");var g=new Map;function x(o,e,t={}){let r=t.priority??10,a={impl:e,bundle:t.bundle,contract:t.contract,priority:r},s=g.get(o);if(customElements.get(o)){if(!s||s.priority>=r){s&&s.priority===r&&s.impl!==e&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${s.bundle}" (priority ${s.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${o}> defined by "${s.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(s&&s.priority>=r){s.priority===r&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${s.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}g.set(o,a),customElements.define(o,e)}function n(o){return String(o).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function f(o){return o.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}function b(o){let e=0;for(let r=0;r<o.length;r++)e=o.charCodeAt(r)+((e<<5)-e);return`hsl(${(e%360+360)%360}, 65%, 55%)`}function l(o){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${o}</svg>`}var c={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>',mapPin:'<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',checkCircle:'<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',send:'<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>'},k={says:{label:"Says",icon:c.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:c.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:c.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:c.heart,color:"#ef4444"}};var u=class{#e=new Map;async load(){return[...this.#e.values()]}async save(e){return e.id||(e.id=crypto.randomUUID()),this.#e.set(e.id,e),e}async update(e,t){let r=this.#e.get(e);if(!r)throw new Error(`Pin ${e} not found`);return Object.assign(r,t),r}async remove(e){this.#e.delete(e)}},v=class{#e;constructor(e="review-surface"){this.#e=e}#r(){try{return JSON.parse(localStorage.getItem(this.#e)||"[]")}catch{return[]}}#s(e){localStorage.setItem(this.#e,JSON.stringify(e))}async load(){return this.#r()}async save(e){e.id||(e.id=crypto.randomUUID());let t=this.#r();return t.push(e),this.#s(t),e}async update(e,t){let r=this.#r(),a=r.findIndex(s=>s.id===e);if(a===-1)throw new Error(`Pin ${e} not found`);return Object.assign(r[a],t),this.#s(r),r[a]}async remove(e){let t=this.#r().filter(r=>r.id!==e);this.#s(t)}},_=class{#e;constructor(e){if(!e)throw new Error("RestAdapter requires an endpoint URL");this.#e=e.replace(/\/$/,"")}async load(){let e=await fetch(this.#e);if(!e.ok)throw new Error(`HTTP ${e.status}`);let t=await e.json();return Array.isArray(t)?t:t.pins||[]}async save(e){let t=await fetch(this.#e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.json()}async update(e,t){let r=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok)throw new Error(`HTTP ${r.status}`);return r.json()}async remove(e){let t=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"DELETE"});if(!t.ok)throw new Error(`HTTP ${t.status}`)}},m=class extends HTMLElement{static get observedAttributes(){return["src","editable","adapter","endpoint","storage-key","author","compact","show-resolved"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"}),this.__pins=[],this.__adapter=null,this._activePin=null,this._annotating=!1}get pins(){return this.__pins}set pins(e){this.__pins=Array.isArray(e)?e:[],this.isConnected&&this._render()}get adapter(){return this.__adapter}set adapter(e){this.__adapter=e,this.isConnected&&this._loadFromAdapter()}#r(){for(let e of this.children){let t=e.getAttribute("slot");t&&this.#e.set(t,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}connectedCallback(){this.#r(),this.setAttribute("data-upgraded",""),this.#s(),this.hasAttribute("src")?this._loadSrc(this.getAttribute("src")):this._loadFromAdapter()}disconnectedCallback(){this.removeAttribute("data-upgraded"),this.removeAttribute("data-annotating")}attributeChangedCallback(e){this.isConnected&&(e==="src"?this._loadSrc(this.getAttribute("src")):e==="adapter"||e==="endpoint"||e==="storage-key"?(this.#s(),this._loadFromAdapter()):this._render())}#s(){if(this.__adapter&&!(this.__adapter instanceof u)&&!(this.__adapter instanceof v)&&!(this.__adapter instanceof _))return;switch(this.getAttribute("adapter")||"memory"){case"local":this.__adapter=new v(this.getAttribute("storage-key")||"review-surface");break;case"rest":try{this.__adapter=new _(this.getAttribute("endpoint"))}catch{this.__adapter=new u}break;default:this.__adapter=new u}}async _loadSrc(e){if(e){this.shadowRoot.innerHTML=`<style>${h}</style><div class="state-msg">Loading\u2026</div>`;try{let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}`);let r=await t.json();this.__pins=Array.isArray(r)?r:r.pins||[],this._render()}catch(t){this.shadowRoot.innerHTML=`<style>${h}</style><div class="state-msg state-msg--error">Could not load pins: ${n(t.message)}</div>`}}}async _loadFromAdapter(){if(this.__adapter){try{this.__pins=await this.__adapter.load()}catch{this.__pins=[]}this._render()}}async addPin(e){let t={id:crypto.randomUUID(),x:Math.max(0,Math.min(100,e.x)),y:Math.max(0,Math.min(100,e.y)),text:e.text||"",author:e.author||this.getAttribute("author")||"Anonymous",createdAt:new Date().toISOString(),resolved:!1,resolvedBy:null,resolvedAt:null,replies:[]};return this.__adapter&&await this.__adapter.save(t),this.__pins.push(t),this._render(),this.#t(`Pin ${this.#a().length} added`),this.dispatchEvent(new CustomEvent("review-surface:add",{bubbles:!0,composed:!0,detail:{pin:t}})),t}async removePin(e){let t=this.__pins.find(r=>r.id===e);t&&(this.__adapter&&await this.__adapter.remove(e),this.__pins=this.__pins.filter(r=>r.id!==e),this._activePin===e&&(this._activePin=null),this._render(),this.#t("Pin removed"),this.dispatchEvent(new CustomEvent("review-surface:remove",{bubbles:!0,composed:!0,detail:{pin:t}})))}async resolvePin(e){let t=this.__pins.find(a=>a.id===e);if(!t)return;let r={resolved:!0,resolvedBy:this.getAttribute("author")||"Anonymous",resolvedAt:new Date().toISOString()};this.__adapter&&await this.__adapter.update(e,r),Object.assign(t,r),this._render(),this.#t("Pin resolved"),this.dispatchEvent(new CustomEvent("review-surface:resolve",{bubbles:!0,composed:!0,detail:{pin:t}}))}async unresolvePin(e){let t=this.__pins.find(a=>a.id===e);if(!t)return;let r={resolved:!1,resolvedBy:null,resolvedAt:null};this.__adapter&&await this.__adapter.update(e,r),Object.assign(t,r),this._render(),this.#t("Pin re-opened"),this.dispatchEvent(new CustomEvent("review-surface:update",{bubbles:!0,composed:!0,detail:{pin:t,changes:r}}))}exportPins(){return structuredClone(this.__pins)}importPins(e){this.__pins=Array.isArray(e)?structuredClone(e):[],this._activePin=null,this._render()}#a(){let e=this.hasAttribute("show-resolved");return this.__pins.filter(t=>e||!t.resolved).sort((t,r)=>new Date(t.createdAt)-new Date(r.createdAt))}_render(){let e=this.hasAttribute("editable"),t=this.#a(),r=this._activePin?this.__pins.find(a=>a.id===this._activePin):null;this.setAttribute("pin-count",String(t.length)),this.shadowRoot.innerHTML=`<style>${h}</style>
|
|
455
|
+
`;var C=window.matchMedia("(prefers-reduced-motion: reduce)");var k=new Map;function $(a,e,t={}){let r=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:r},o=k.get(a);if(customElements.get(a)){if(!o||o.priority>=r){o&&o.priority===r&&o.impl!==e&&console.warn(`[VB Bundle] Tag <${a}> already registered by "${o.bundle}" (priority ${o.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${a}> defined by "${o.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(o&&o.priority>=r){o.priority===r&&console.warn(`[VB Bundle] Tag <${a}> already registered by "${o.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}k.set(a,s),customElements.define(a,e)}function n(a){return String(a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function g(a){return a.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}function y(a){let e=0;for(let r=0;r<a.length;r++)e=a.charCodeAt(r)+((e<<5)-e);return`hsl(${(e%360+360)%360}, 65%, 55%)`}function l(a){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${a}</svg>`}var c={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>',mapPin:'<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',checkCircle:'<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',send:'<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>'},R={says:{label:"Says",icon:c.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:c.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:c.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:c.heart,color:"#ef4444"}};function P(){let a=globalThis.localStorage;if(!a)throw new Error("VBStore: localStorage is not available in this environment");return{async getRaw(e){return a.getItem(e)},async setRaw(e,t){a.setItem(e,t)},async removeRaw(e){a.removeItem(e)},async keys(e){let t=[];for(let r=0;r<a.length;r++){let s=a.key(r);s&&s.startsWith(e)&&t.push(s)}return t}}}var f=null;function p(){return f||(f=P()),f}function x(a,e){if(typeof a!="string"||!a)throw new TypeError("VBStore: namespace must be a non-empty string");if(typeof e!="string"||!e)throw new TypeError("VBStore: key must be a non-empty string");return`vb:${a}:${e}`}function E(a){if(typeof a!="string"||!a)throw new TypeError("VBStore: namespace must be a non-empty string");return`vb:${a}:`}function A(a){try{let e=JSON.parse(a);if(e&&typeof e=="object"&&typeof e.timestamp=="number")return e}catch{}return null}var _={configure(a={}){f=a.backend??null},async set(a,e,t){let r={data:t,timestamp:Date.now()};await p().setRaw(x(a,e),JSON.stringify(r))},async get(a,e,t){let r=await p().getRaw(x(a,e));if(r==null)return null;let s=A(r);return!s||t?.maxAge!=null&&Date.now()-s.timestamp>t.maxAge?null:s.data},async remove(a,e){await p().removeRaw(x(a,e))},async list(a){let e=E(a),t=await p().keys(e),r=[];for(let s of t){let o=await p().getRaw(s);if(o==null)continue;let i=A(o);i&&r.push({key:s.slice(e.length),data:i.data,timestamp:i.timestamp})}return r},async clear(a){let e=E(a),t=await p().keys(e);for(let r of t)await p().removeRaw(r)},async clearAll(){let a=await p().keys("vb:");for(let e of a)await p().removeRaw(e)},async setMany(a,e){for(let[t,r]of e)await _.set(a,t,r)}};var h=class{#e=new Map;async load(){return[...this.#e.values()]}async save(e){return e.id||(e.id=crypto.randomUUID()),this.#e.set(e.id,e),e}async update(e,t){let r=this.#e.get(e);if(!r)throw new Error(`Pin ${e} not found`);return Object.assign(r,t),r}async remove(e){this.#e.delete(e)}},b=class{#e;constructor(e="default"){this.#e=e}async#r(){let e=await _.get("reviews",this.#e);return Array.isArray(e)?e:[]}async#a(e){await _.set("reviews",this.#e,e)}async load(){return this.#r()}async save(e){e.id||(e.id=crypto.randomUUID());let t=await this.#r();return t.push(e),await this.#a(t),e}async update(e,t){let r=await this.#r(),s=r.findIndex(o=>o.id===e);if(s===-1)throw new Error(`Pin ${e} not found`);return Object.assign(r[s],t),await this.#a(r),r[s]}async remove(e){let t=(await this.#r()).filter(r=>r.id!==e);await this.#a(t)}},m=class{#e;constructor(e){if(!e)throw new Error("RestAdapter requires an endpoint URL");this.#e=e.replace(/\/$/,"")}async load(){let e=await fetch(this.#e);if(!e.ok)throw new Error(`HTTP ${e.status}`);let t=await e.json();return Array.isArray(t)?t:t.pins||[]}async save(e){let t=await fetch(this.#e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.json()}async update(e,t){let r=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok)throw new Error(`HTTP ${r.status}`);return r.json()}async remove(e){let t=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"DELETE"});if(!t.ok)throw new Error(`HTTP ${t.status}`)}},w=class extends HTMLElement{static get observedAttributes(){return["src","editable","adapter","endpoint","storage-key","author","compact","show-resolved"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"}),this.__pins=[],this.__adapter=null,this._activePin=null,this._annotating=!1}get pins(){return this.__pins}set pins(e){this.__pins=Array.isArray(e)?e:[],this.isConnected&&this._render()}get adapter(){return this.__adapter}set adapter(e){this.__adapter=e,this.isConnected&&this._loadFromAdapter()}#r(){for(let e of this.children){let t=e.getAttribute("slot");t&&this.#e.set(t,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}connectedCallback(){this.#r(),this.setAttribute("data-upgraded",""),this.#a(),this.hasAttribute("src")?this._loadSrc(this.getAttribute("src")):this._loadFromAdapter()}disconnectedCallback(){this.removeAttribute("data-upgraded"),this.removeAttribute("data-annotating")}attributeChangedCallback(e){this.isConnected&&(e==="src"?this._loadSrc(this.getAttribute("src")):e==="adapter"||e==="endpoint"||e==="storage-key"?(this.#a(),this._loadFromAdapter()):this._render())}#a(){if(this.__adapter&&!(this.__adapter instanceof h)&&!(this.__adapter instanceof b)&&!(this.__adapter instanceof m))return;switch(this.getAttribute("adapter")||"memory"){case"local":this.__adapter=new b(this.getAttribute("storage-key")||"default");break;case"rest":try{this.__adapter=new m(this.getAttribute("endpoint"))}catch{this.__adapter=new h}break;default:this.__adapter=new h}}async _loadSrc(e){if(e){this.shadowRoot.innerHTML=`<style>${v}</style><div class="state-msg">Loading\u2026</div>`;try{let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}`);let r=await t.json();this.__pins=Array.isArray(r)?r:r.pins||[],this._render()}catch(t){this.shadowRoot.innerHTML=`<style>${v}</style><div class="state-msg state-msg--error">Could not load pins: ${n(t.message)}</div>`}}}async _loadFromAdapter(){if(this.__adapter){try{this.__pins=await this.__adapter.load()}catch{this.__pins=[]}this._render()}}async addPin(e){let t={id:crypto.randomUUID(),x:Math.max(0,Math.min(100,e.x)),y:Math.max(0,Math.min(100,e.y)),text:e.text||"",author:e.author||this.getAttribute("author")||"Anonymous",createdAt:new Date().toISOString(),resolved:!1,resolvedBy:null,resolvedAt:null,replies:[]};return this.__adapter&&await this.__adapter.save(t),this.__pins.push(t),this._render(),this.#t(`Pin ${this.#s().length} added`),this.dispatchEvent(new CustomEvent("review-surface:add",{bubbles:!0,composed:!0,detail:{pin:t}})),t}async removePin(e){let t=this.__pins.find(r=>r.id===e);t&&(this.__adapter&&await this.__adapter.remove(e),this.__pins=this.__pins.filter(r=>r.id!==e),this._activePin===e&&(this._activePin=null),this._render(),this.#t("Pin removed"),this.dispatchEvent(new CustomEvent("review-surface:remove",{bubbles:!0,composed:!0,detail:{pin:t}})))}async resolvePin(e){let t=this.__pins.find(s=>s.id===e);if(!t)return;let r={resolved:!0,resolvedBy:this.getAttribute("author")||"Anonymous",resolvedAt:new Date().toISOString()};this.__adapter&&await this.__adapter.update(e,r),Object.assign(t,r),this._render(),this.#t("Pin resolved"),this.dispatchEvent(new CustomEvent("review-surface:resolve",{bubbles:!0,composed:!0,detail:{pin:t}}))}async unresolvePin(e){let t=this.__pins.find(s=>s.id===e);if(!t)return;let r={resolved:!1,resolvedBy:null,resolvedAt:null};this.__adapter&&await this.__adapter.update(e,r),Object.assign(t,r),this._render(),this.#t("Pin re-opened"),this.dispatchEvent(new CustomEvent("review-surface:update",{bubbles:!0,composed:!0,detail:{pin:t,changes:r}}))}exportPins(){return structuredClone(this.__pins)}importPins(e){this.__pins=Array.isArray(e)?structuredClone(e):[],this._activePin=null,this._render()}#s(){let e=this.hasAttribute("show-resolved");return this.__pins.filter(t=>e||!t.resolved).sort((t,r)=>new Date(t.createdAt)-new Date(r.createdAt))}_render(){let e=this.hasAttribute("editable"),t=this.#s(),r=this._activePin?this.__pins.find(s=>s.id===this._activePin):null;this.setAttribute("pin-count",String(t.length)),this.shadowRoot.innerHTML=`<style>${v}</style>
|
|
456
456
|
<div class="rs-container">
|
|
457
457
|
<slot></slot>
|
|
458
458
|
<div class="rs-overlay" role="img" aria-label="Review annotation surface">
|
|
459
|
-
${t.map((
|
|
459
|
+
${t.map((s,o)=>this._renderPin(s,o+1)).join("")}
|
|
460
460
|
</div>
|
|
461
461
|
${r?this._renderPopover(r,e):""}
|
|
462
462
|
</div>
|
|
@@ -470,7 +470,7 @@ var h=`
|
|
|
470
470
|
aria-expanded="${this._activePin===e.id}"
|
|
471
471
|
aria-haspopup="dialog">
|
|
472
472
|
<span class="rs-pin__number">${t}</span>
|
|
473
|
-
</button>`}_renderPopover(e,t){let r=this.#
|
|
473
|
+
</button>`}_renderPopover(e,t){let r=this.#s().findIndex(s=>s.id===e.id)+1;return`<div class="rs-popover" data-open
|
|
474
474
|
style="left:${Math.min(e.x,70)}%;top:${e.y}%"
|
|
475
475
|
role="dialog"
|
|
476
476
|
aria-labelledby="rs-popover-title-${n(e.id)}">
|
|
@@ -497,7 +497,7 @@ var h=`
|
|
|
497
497
|
|
|
498
498
|
<div class="rs-comment">
|
|
499
499
|
<div class="rs-comment__meta">
|
|
500
|
-
<span class="rs-comment__avatar" style="background:${
|
|
500
|
+
<span class="rs-comment__avatar" style="background:${y(e.author||"Anonymous")}">${g(e.author||"Anonymous")}</span>
|
|
501
501
|
<span class="rs-comment__author">${n(e.author||"Anonymous")}</span>
|
|
502
502
|
<span class="rs-comment__time">${this.#i(e.createdAt)}</span>
|
|
503
503
|
</div>
|
|
@@ -506,14 +506,14 @@ var h=`
|
|
|
506
506
|
|
|
507
507
|
${e.replies?.length?`
|
|
508
508
|
<div class="rs-replies">
|
|
509
|
-
${e.replies.map(
|
|
509
|
+
${e.replies.map(s=>`
|
|
510
510
|
<div class="rs-reply">
|
|
511
511
|
<div class="rs-comment__meta">
|
|
512
|
-
<span class="rs-comment__avatar" style="background:${
|
|
513
|
-
<span class="rs-comment__author">${n(
|
|
514
|
-
<span class="rs-comment__time">${this.#i(
|
|
512
|
+
<span class="rs-comment__avatar" style="background:${y(s.author||"Anonymous")}">${g(s.author||"Anonymous")}</span>
|
|
513
|
+
<span class="rs-comment__author">${n(s.author||"Anonymous")}</span>
|
|
514
|
+
<span class="rs-comment__time">${this.#i(s.createdAt)}</span>
|
|
515
515
|
</div>
|
|
516
|
-
<div class="rs-comment__text">${n(
|
|
516
|
+
<div class="rs-comment__text">${n(s.text)}</div>
|
|
517
517
|
</div>
|
|
518
518
|
`).join("")}
|
|
519
519
|
</div>`:""}
|
|
@@ -537,5 +537,5 @@ var h=`
|
|
|
537
537
|
${l(c.download)} Export
|
|
538
538
|
</button>
|
|
539
539
|
<output class="rs-toolbar__count">${e} pin${e!==1?"s":""}</output>
|
|
540
|
-
</div>`}_bindListeners(e){let t=this.shadowRoot;t.querySelectorAll(".rs-pin").forEach(
|
|
540
|
+
</div>`}_bindListeners(e){let t=this.shadowRoot;t.querySelectorAll(".rs-pin").forEach(o=>{o.addEventListener("click",i=>{i.stopPropagation();let d=o.dataset.pinId;this._activePin=this._activePin===d?null:d,this._render(),this._activePin&&this.dispatchEvent(new CustomEvent("review-surface:select",{bubbles:!0,composed:!0,detail:{pin:this.__pins.find(u=>u.id===d)}}))})});let r=t.querySelector(".rs-overlay");r&&e&&r.addEventListener("click",o=>{if(!this._annotating||o.target.closest(".rs-pin"))return;let i=r.getBoundingClientRect(),d=(o.clientX-i.left)/i.width*100,u=(o.clientY-i.top)/i.height*100;this.#n(d,u)}),t.querySelectorAll("[data-action]").forEach(o=>{o.addEventListener("click",i=>{i.stopPropagation();let d=o.dataset.action,u=o.dataset.pinId;switch(d){case"close":this._activePin=null,this._render();break;case"resolve":this.resolvePin(u);break;case"unresolve":this.unresolvePin(u);break;case"delete":this.removePin(u);break;case"toggle-mode":this._annotating=!this._annotating,this._annotating?this.setAttribute("data-annotating",""):this.removeAttribute("data-annotating"),this._render(),this.dispatchEvent(new CustomEvent("review-surface:mode",{bubbles:!0,composed:!0,detail:{mode:this._annotating?"annotate":"view"}}));break;case"export":this.#c();break;case"reply":this.#o(u);break}})});let s=t.querySelector(".rs-input__field");s&&s.addEventListener("keydown",o=>{if(o.key==="Enter"&&!o.shiftKey){o.preventDefault();let i=t.querySelector('[data-action="reply"]')?.dataset.pinId;i&&this.#o(i)}}),t.addEventListener("keydown",o=>{o.key==="Escape"&&(this._activePin?(this._activePin=null,this._render()):this._annotating&&(this._annotating=!1,this.removeAttribute("data-annotating"),this._render(),this.dispatchEvent(new CustomEvent("review-surface:mode",{bubbles:!0,composed:!0,detail:{mode:"view"}}))))})}async#n(e,t){let r=this.getAttribute("author")||"Anonymous",s=await this.addPin({x:e,y:t,text:"",author:r});this._activePin=s.id,this._render(),requestAnimationFrame(()=>{let o=this.shadowRoot.querySelector(".rs-input__field");o&&o.focus()})}async#o(e){let t=this.shadowRoot.querySelector(".rs-input__field");if(!t)return;let r=t.value.trim();if(!r)return;let s=this.__pins.find(i=>i.id===e);if(!s)return;let o={id:crypto.randomUUID(),text:r,author:this.getAttribute("author")||"Anonymous",createdAt:new Date().toISOString()};s.replies||(s.replies=[]),s.text?(s.replies.push(o),this.__adapter&&await this.__adapter.update(e,{replies:s.replies})):(s.text=r,this.__adapter&&await this.__adapter.update(e,{text:r})),this._render(),this.#t("Reply added"),requestAnimationFrame(()=>{let i=this.shadowRoot.querySelector(".rs-input__field");i&&i.focus()}),this.dispatchEvent(new CustomEvent("review-surface:update",{bubbles:!0,composed:!0,detail:{pin:s,changes:{replies:s.replies}}}))}async#c(){let e=JSON.stringify(this.exportPins(),null,2);try{await navigator.clipboard.writeText(e),this.#t("Pins copied to clipboard")}catch{let t=new Blob([e],{type:"application/json"}),r=URL.createObjectURL(t),s=document.createElement("a");s.href=r,s.download="review-pins.json",s.click(),URL.revokeObjectURL(r),this.#t("Pins exported as file")}}#i(e){if(!e)return"";try{let t=new Date(e),s=new Date-t,o=Math.floor(s/6e4);if(o<1)return"just now";if(o<60)return`${o}m ago`;let i=Math.floor(o/60);if(i<24)return`${i}h ago`;let d=Math.floor(i/24);return d<7?`${d}d ago`:t.toLocaleDateString()}catch{return""}}#t(e){let t=this.shadowRoot.querySelector(".rs-live");t&&(t.textContent=e)}};$("review-surface",w);export{b as LocalStorageAdapter,h as MemoryAdapter,m as RestAdapter,w as ReviewSurface};
|
|
541
541
|
//# sourceMappingURL=review-surface.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var d=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#e)e();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,i,s){e.addEventListener(t,i,s),this.#e.push(()=>e.removeEventListener(t,i,s))}setup(){}teardown(){}};var p=window.matchMedia("(prefers-reduced-motion: reduce)");var u=new Map;function h(o,e,t={}){let i=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:i},n=u.get(o);if(customElements.get(o)){if(!n||n.priority>=i){n&&n.priority===i&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${o}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=i){n.priority===i&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${n.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}u.set(o,s),customElements.define(o,e)}var f=8,l=8,a=class extends d{#e=null;#t=new Set;#n=!1;setup(){this.hidden=!0,this.#o(),this.listen(document,"pointerup",this.#s),this.listen(document,"pointerdown",this.#d),this.listen(document,"keydown",this.#l),this.id&&new MutationObserver(()=>this.#o()).observe(document.body,{childList:!0,subtree:!0,attributeFilter:["data-selection-menu"]})}getSelection(){return this.#e?{...this.#e}:null}dismiss(){this.#i()}#o(){this.#t.clear();let e=this.getAttribute("for");if(e){let t=document.getElementById(e);t&&(this.#t.add(t),t.hasAttribute("data-selection-menu")||t.setAttribute("data-selection-menu",this.id||""))}this.id&&document.querySelectorAll(`[data-selection-menu="${this.id}"]`).forEach(t=>{this.#t.add(t)})}#s=()=>{requestAnimationFrame(()=>{this.isConnected&&this.#r()})};#r(){let e=window.getSelection();if(!e||e.isCollapsed||!e.toString().trim())return;let t=e.getRangeAt(0),i=t.commonAncestorContainer,s=i.nodeType===Node.ELEMENT_NODE?i:i.parentElement,n=null;for(let c of this.#t)if(c.contains(s)){n=c;break}if(!n)return;let r=e.toString().trim();this.#e={range:t.cloneRange(),text:r,target:n},this.dispatchEvent(new CustomEvent("selection-menu:select",{detail:{range:this.#e.range,text:r,target:n},bubbles:!0})),this.#c(t.getBoundingClientRect())}#c(e){this.hidden=!1,this.#n=!0,requestAnimationFrame(()=>{let t=this.getBoundingClientRect(),i=t.width||200,s=t.height||40,n=e.top-s-f,r=e.left+e.width/2-i/2;n<l&&(n=e.bottom+f);let c=window.innerWidth-i-l;r=Math.max(l,Math.min(r,c)),this.style.top=`${n}px`,this.style.left=`${r}px`})}#i(){this.hidden=!0,this.#n=!1,this.#e=null,this.dispatchEvent(new CustomEvent("selection-menu:dismiss",{bubbles:!0}))}#d=e=>{this.#n&&(this.contains(e.target)||this.#i())};#l=e=>{e.key==="Escape"&&this.#n&&this.#i()}};h("selection-menu",a);
|
|
2
|
+
//# sourceMappingURL=selection-menu.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var at=window.matchMedia("(prefers-reduced-motion: reduce)");var q=new Map;function F(r,e,t={}){let o=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:o},n=q.get(r);if(customElements.get(r)){if(!n||n.priority>=o){n&&n.priority===o&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=o){n.priority===o&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}q.set(r,s),customElements.define(r,e)}var v=class extends HTMLElement{#t=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#t)e();this.#t=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,o,s){e.addEventListener(t,o,s),this.#t.push(()=>e.removeEventListener(t,o,s))}setup(){}teardown(){}};function X(r,e,t){e/=100,t/=100;let o=i=>(i+r/30)%12,s=e*Math.min(t,1-t),n=i=>t-s*Math.max(-1,Math.min(o(i)-3,9-o(i),1));return{r:Math.round(n(0)*255),g:Math.round(n(8)*255),b:Math.round(n(4)*255)}}function G(r,e,t){r/=255,e/=255,t/=255;let o=Math.max(r,e,t),s=Math.min(r,e,t),n=(o+s)/2,i=0,l=0;if(o!==s){let a=o-s;switch(l=n>.5?a/(2-o-s):a/(o+s),o){case r:i=((e-t)/a+(e<t?6:0))/6;break;case e:i=((t-r)/a+2)/6;break;case t:i=((r-e)/a+4)/6;break}}return{h:Math.round(i*360),s:Math.round(l*100),l:Math.round(n*100)}}function S(r){r=r.replace(/^#/,""),r.length===3&&(r=r[0]+r[0]+r[1]+r[1]+r[2]+r[2]);let e=parseInt(r,16);return{r:e>>16&255,g:e>>8&255,b:e&255}}function k(r,e,t){return"#"+[r,e,t].map(o=>Math.max(0,Math.min(255,Math.round(o))).toString(16).padStart(2,"0")).join("")}function N(r){let{r:e,g:t,b:o}=S(r);return G(e,t,o)}function c(r,e,t){let{r:o,g:s,b:n}=X(r,e,t);return k(o,s,n)}var E=r=>r<=.04045?r/12.92:Math.pow((r+.055)/1.055,2.4),z=r=>r<=.0031308?12.92*r:1.055*Math.pow(r,1/2.4)-.055,A=r=>r<0?0:r>1?1:r;function h(r){let{r:e,g:t,b:o}=S(r),s=E(e/255),n=E(t/255),i=E(o/255),l=.4122214708*s+.5363325363*n+.0514459929*i,a=.2119034982*s+.6806995451*n+.1073969566*i,d=.0883024619*s+.2817188376*n+.6299787005*i,p=Math.cbrt(l),f=Math.cbrt(a),b=Math.cbrt(d),M=.2104542553*p+.793617785*f-.0040720468*b,g=1.9779984951*p-2.428592205*f+.4505937099*b,y=.0259040371*p+.7827717662*f-.808675766*b,T=Math.sqrt(g*g+y*y),x=Math.atan2(y,g)*180/Math.PI;return x<0&&(x+=360),{l:M,c:T,h:x}}function $(r,e,t){let o=t*Math.PI/180,s=e*Math.cos(o),n=e*Math.sin(o),i=r+.3963377774*s+.2158037573*n,l=r-.1055613458*s-.0638541728*n,a=r-.0894841775*s-1.291485548*n,d=i*i*i,p=l*l*l,f=a*a*a,b=4.0767416621*d-3.3077115913*p+.2309699292*f,M=-1.2684380046*d+2.6097574011*p-.3413193965*f,g=-.0041960863*d-.7034186147*p+1.707614701*f,y=A(z(b)),T=A(z(M)),x=A(z(g));return k(Math.round(y*255),Math.round(T*255),Math.round(x*255))}function B(r,e){if(!r)return null;let t=String(r).trim();if(/^#[0-9a-f]{6}$/i.test(t))return t.toLowerCase();if(/^#[0-9a-f]{3}$/i.test(t))return("#"+t.slice(1).split("").map(i=>i+i).join("")).toLowerCase();if(typeof document>"u")return null;let o=e||document.createElement("span");e||(o.style.display="none",document.body.appendChild(o)),o.style.color="",o.style.color=t;let s=getComputedStyle(o).color;e||o.remove();let n=s.match(/rgba?\(\s*([0-9.]+)[\s,]+([0-9.]+)[\s,]+([0-9.]+)/);return n?k(Math.round(+n[1]),Math.round(+n[2]),Math.round(+n[3])):null}function P({l:r,c:e,h:t}){return`oklch(${(r*100).toFixed(1)}% ${e.toFixed(3)} ${t.toFixed(1)})`}function C(r){let{r:e,g:t,b:o}=S(r),s=n=>{let i=n/255;return i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)};return .2126*s(e)+.7152*s(t)+.0722*s(o)}function _(r,e){let t=C(r),o=C(e),s=Math.max(t,o),n=Math.min(t,o);return(s+.05)/(n+.05)}function V(r){return r>=7?"AAA":r>=4.5?"AA":"Fail"}function L(r){return C(r)>.4?"#000000":"#ffffff"}var u=r=>(r%360+360)%360;function K(r,e,t){return{colors:[c(r,e,t),c(u(r+180),e,t)],names:["Base","Complement"]}}function Q(r,e,t){return{colors:[c(u(r-30),e,t),c(r,e,t),c(u(r+30),e,t)],names:["Analog A","Base","Analog B"]}}function Y(r,e,t){return{colors:[c(r,e,t),c(u(r+120),e,t),c(u(r+240),e,t)],names:["Base","Triad A","Triad B"]}}function Z(r,e,t){return{colors:[c(r,e,t),c(u(r+150),e,t),c(u(r+210),e,t)],names:["Base","Split A","Split B"]}}function tt(r,e,t){return{colors:[c(r,e,t),c(u(r+90),e,t),c(u(r+180),e,t),c(u(r+270),e,t)],names:["Base","Tetrad A","Tetrad B","Tetrad C"]}}var et=[{label:"50",l:96},{label:"100",l:90},{label:"200",l:80},{label:"300",l:70},{label:"400",l:60},{label:"500",l:50},{label:"600",l:40},{label:"700",l:30},{label:"800",l:22},{label:"900",l:15},{label:"950",l:10}];function rt(r,e,t){let o=[],s=[];for(let n of et){let i=n.l>85||n.l<20?Math.max(e*.6,5):e;o.push(c(r,Math.round(i),n.l)),s.push(n.label)}return{colors:o,names:s}}var D={complementary:K,analogous:Q,triadic:Y,"split-complementary":Z,tetradic:tt,monochromatic:rt};function I(r,e){let{h:t,s:o,l:s}=N(r);return(D[e]||D.complementary)(t,o,s)}var w=["primary","secondary","accent"],W=["success","warning","error","info"],ot=[...w,...W],U={primary:"Primary",secondary:"Secondary",accent:"Accent",success:"Success",warning:"Warning",error:"Error",info:"Info"},nt={aaa:{bg:"oklch(92% 0.08 145)",fg:"oklch(30% 0.12 145)"},aa:{bg:"oklch(94% 0.08 90)",fg:"oklch(35% 0.12 70)"},fail:{bg:"oklch(92% 0.08 25)",fg:"oklch(35% 0.15 25)"}},O="var(--font-mono, monospace)",R="var(--color-text-muted, #666)",H="var(--color-border, #ddd)",J="var(--color-surface, #fff)",st="var(--color-text, #222)",m="var(--radius-s, 0.25rem)",it="var(--radius-m, 0.5rem)",j=class extends v{static observedAttributes=["colors","roles","show-export","label"];#t=[];#o=[];#b=null;#l=null;#e=null;setup(){this.#e=document.createElement("span"),this.#e.style.cssText="position:absolute;visibility:hidden;pointer-events:none",this.append(this.#e),this.#b=this.querySelector("color-palette, palette-generator"),this.#d(),this.#s(),this.#u(),this.#a("init"),this.#v(),this.#p(),this.#c("init")}attributeChangedCallback(e){!this.isConnected||!this.hasAttribute("data-upgraded")||(e==="roles"&&this.#d(),e==="colors"&&this.#s(),this.#u(),this.#a("attribute"),this.#p(),this.#c("attribute"))}teardown(){this.#e?.remove(),this.#e=null}#s(){let e=this.querySelector("color-palette");if(e){if(typeof e.colors<"u"&&e.colors.length){this.#t=e.colors.slice();return}let n=(e.getAttribute("colors")||"").split(",").map(i=>i.trim()).filter(Boolean);if(n.length){this.#t=n;return}}let t=this.querySelector("palette-generator");if(t){let s=t.getAttribute("seed")||t.querySelector('input[type="color"]')?.value||"",n=t.getAttribute("harmony")||"complementary";if(s)try{let{colors:i}=I(s,n);this.#t=i.slice();return}catch{}}let o=this.getAttribute("colors")||"";this.#t=o.split(",").map(s=>s.trim()).filter(Boolean)}#d(){let t=(this.getAttribute("roles")||w.join(",")).split(",").map(o=>o.trim().toLowerCase()).filter(o=>ot.includes(o));this.#o=t.length?t:[...w]}#i(){let e={};for(let t=0;t<this.#o.length;t++)e[this.#o[t]]=this.#t[t]||this.#t[this.#t.length-1]||"#888888";return e}#u(){let e=this.querySelector(":scope > .sp-shell");e&&e.remove();let t=this.getAttribute("label"),o=this.hasAttribute("show-export"),s=document.createElement("div");if(s.className="sp-shell",s.style.cssText="display:flex;flex-direction:column;gap:var(--size-m,1rem);margin-block-start:var(--size-s,0.75rem)",t){let i=document.createElement("p");i.style.cssText="font-weight:600;margin:0",i.textContent=t,s.append(i)}let n=document.createElement("section");n.className="sp-previews",n.setAttribute("aria-label","Role previews"),n.style.cssText="display:grid;grid-template-columns:repeat(auto-fill,minmax(min(22rem,100%),1fr));gap:var(--size-m,1rem)",s.append(n),this.#l=n,o&&s.insertAdjacentHTML("beforeend",this.#$()),this.append(s)}#a(e){if(!this.#l)return;let t=this.#i();this.#l.innerHTML=this.#o.map(o=>this.#g(o,t[o])).join("")}#g(e,t){let o=U[e]||e,n=W.includes(e)?this.#x(e,t):this.#y(e,t),i=`display:flex;flex-direction:column;gap:var(--size-s,0.75rem);padding:var(--size-m,1rem);border:1px solid ${H};border-radius:${it};background:${J};min-inline-size:0`;return`<article class="sp-card" data-role="${e}" aria-label="${o} role preview" style="${i}">
|
|
2
|
+
<header style="display:flex;align-items:center;justify-content:space-between;gap:var(--size-s,0.75rem)">
|
|
3
|
+
<div>
|
|
4
|
+
<code style="font-family:${O};font-size:var(--font-size-sm,0.875rem);font-weight:600">${e}</code>
|
|
5
|
+
<span style="display:block;font-size:var(--font-size-xs,0.75rem);color:${R}">${o}</span>
|
|
6
|
+
</div>
|
|
7
|
+
<div style="display:flex;align-items:center;gap:0.5rem">
|
|
8
|
+
<span class="sp-swatch" style="display:inline-block;inline-size:1.75rem;block-size:1.75rem;border-radius:${m};border:1px solid oklch(0% 0 0 / 0.15);background:${t}"></span>
|
|
9
|
+
<code style="font-family:${O};font-size:var(--font-size-xs,0.75rem);color:${R}">${t}</code>
|
|
10
|
+
</div>
|
|
11
|
+
</header>
|
|
12
|
+
<div class="sp-samples" style="display:flex;flex-wrap:wrap;gap:var(--size-s,0.75rem);align-items:flex-start">${n}</div>
|
|
13
|
+
</article>`}#y(e,t){let o=this.#S(e,t),s=this.#f(),n=this.#k(e,t),i=this.#T(t);return[this.#r({render:`<button type="button" tabindex="-1" style="all:unset;display:inline-block;padding:0.375rem 0.875rem;border-radius:${m};background:${t};color:${o};font-family:inherit;font-size:var(--font-size-sm,0.875rem);font-weight:600;cursor:default">Button</button>`,fg:o,bg:t,caption:"On role"}),this.#r({render:`<span style="color:${t};background:${s};padding:0.25rem 0.5rem;border-radius:${m};font-size:var(--font-size-sm,0.875rem);font-weight:500;text-decoration:underline">Linked text</span>`,fg:t,bg:s||"#ffffff",caption:"On surface"}),this.#r({render:`<span style="display:inline-block;padding:0.125rem 0.5rem;border-radius:999px;background:${n};color:${i};font-size:var(--font-size-xs,0.75rem);font-weight:600;letter-spacing:0.04em;text-transform:uppercase">Badge</span>`,fg:i,bg:n,caption:"Subtle"})].join("")}#x(e,t){let o=this.#f(),s=this.#w(e,t),n=this.#M(e,t),i=L(t);return[this.#r({render:`<div style="display:flex;align-items:center;gap:0.5rem;padding:0.5rem 0.75rem;border-radius:${m};background:${s};color:${n};border:1px solid ${t};font-size:var(--font-size-sm,0.875rem);max-inline-size:100%">
|
|
14
|
+
<span style="display:inline-block;inline-size:0.5rem;block-size:0.5rem;border-radius:50%;background:${t};flex-shrink:0"></span>
|
|
15
|
+
<span><strong>${U[e]||e}</strong> \u2014 message text</span>
|
|
16
|
+
</div>`,fg:n,bg:s,caption:"Alert"}),this.#r({render:`<span style="display:inline-block;padding:0.125rem 0.5rem;border-radius:999px;background:${t};color:${i};font-size:var(--font-size-xs,0.75rem);font-weight:700;letter-spacing:0.04em;text-transform:uppercase">${e}</span>`,fg:i,bg:t,caption:"Badge"}),this.#r({render:`<span style="color:${t};background:${o};padding:0.25rem 0.5rem;border-radius:${m};font-size:var(--font-size-sm,0.875rem);font-weight:600">Inline status</span>`,fg:t,bg:o||"#ffffff",caption:"On surface"})].join("")}#r({render:e,fg:t,bg:o,caption:s}){let n=B(t,this.#e)||"#000000",i=B(o,this.#e)||"#ffffff",l=_(n,i),a=V(l).toLowerCase(),d=nt[a],p=`display:inline-flex;align-items:center;gap:0.25rem;padding:0.125rem 0.375rem;border-radius:${m};font-family:${O};font-size:var(--font-size-xs,0.75rem);background:${d.bg};color:${d.fg}`;return`<div style="display:flex;flex-direction:column;gap:0.25rem;align-items:flex-start;min-inline-size:0;max-inline-size:100%">
|
|
17
|
+
<div style="max-inline-size:100%">${e}</div>
|
|
18
|
+
<div style="display:flex;align-items:center;gap:0.375rem;font-size:var(--font-size-xs,0.75rem);color:${R}">
|
|
19
|
+
<span style="${p}" title="${s}: ${l.toFixed(2)}:1">${l.toFixed(2)} <small>${a.toUpperCase()}</small></span>
|
|
20
|
+
<span>${s}</span>
|
|
21
|
+
</div>
|
|
22
|
+
</div>`}#$(){let e=`display:flex;gap:var(--size-2xs,0.375rem);padding-block-start:var(--size-xs,0.5rem);border-block-start:1px solid ${H}`,t=`padding:0.375rem 0.875rem;border:1px solid ${H};border-radius:${m};background:${J};color:${st};cursor:pointer;font:inherit;font-size:var(--font-size-sm,0.875rem)`;return`<div class="sp-export" role="toolbar" aria-label="Export semantic palette" style="${e}">
|
|
23
|
+
<button type="button" class="sp-copy-css" style="${t}">Copy Theme CSS</button>
|
|
24
|
+
<button type="button" class="sp-copy-json" style="${t}">Copy JSON</button>
|
|
25
|
+
</div>`}#v(){let e=this.querySelector("color-palette");e&&this.listen(e,"color-palette:change",()=>{this.#s(),this.#a("palette"),this.#c("palette")});let t=this.querySelector("palette-generator");t&&this.listen(t,"palette-generator:generate",()=>{this.#s(),this.#a("palette"),this.#c("palette")})}#p(){let e=this.querySelector(".sp-copy-css"),t=this.querySelector(".sp-copy-json");e&&this.listen(e,"click",()=>{navigator.clipboard?.writeText(this.#m()),this.#h(e,"Copy Theme CSS")}),t&&this.listen(t,"click",()=>{navigator.clipboard?.writeText(JSON.stringify(this.#i(),null,2)),this.#h(t,"Copy JSON")})}#n(){return getComputedStyle(this)}#f(){return this.#n().getPropertyValue("--color-surface").trim()||"#ffffff"}#S(e,t){return this.#n().getPropertyValue(`--color-text-on-${e}`).trim()||L(t)}#k(e,t){let o=this.#n().getPropertyValue(`--color-${e}-subtle`).trim();if(o)return o;let{h:s}=h(t);return $(.95,.03,s)}#w(e,t){let o=this.#n().getPropertyValue(`--color-${e}-subtle`).trim();if(o)return o;let{h:s}=h(t);return $(.94,.05,s)}#M(e,t){let o=this.#n().getPropertyValue(`--color-${e}-text`).trim();if(o)return o;let{h:s}=h(t);return $(.3,.14,s)}#T(e){let{l:t,c:o,h:s}=h(e);return $(Math.max(.2,t-.25),o,s)}#m(){let e=this.#i(),t=[],o=[];for(let n of this.#o){let i=e[n];if(!i)continue;let{l,c:a,h:d}=h(i);w.includes(n)?t.push(` --hue-${n}: ${d.toFixed(1)};`,` --lightness-${n}: ${(l*100).toFixed(1)}%;`,` --chroma-${n}: ${a.toFixed(3)};`):o.push(` --color-${n}: ${P({l,c:a,h:d})};`)}let s=[];return t.length&&s.push(" /* Brand seeds */",...t),o.length&&(t.length&&s.push(""),s.push(" /* Status colors */",...o)),`:root {
|
|
26
|
+
${s.join(`
|
|
27
|
+
`)}
|
|
28
|
+
}
|
|
29
|
+
`}#h(e,t){e.textContent="Copied!",setTimeout(()=>{e.textContent=t},1500)}#c(e){this.dispatchEvent(new CustomEvent("semantic-palette:change",{bubbles:!0,detail:{mapping:this.#i(),tokens:this.#m(),source:e}}))}};F("semantic-palette",j);
|
|
30
|
+
//# sourceMappingURL=semantic-palette.js.map
|