diff --git a/200.html b/200.html index ade36bdb..d2933ed5 100644 --- a/200.html +++ b/200.html @@ -1,9 +1,9 @@ - - - - - -
- \ No newline at end of file + + + + + +
+ \ No newline at end of file diff --git a/404.html b/404.html index ade36bdb..d2933ed5 100644 --- a/404.html +++ b/404.html @@ -1,9 +1,9 @@ - - - - - -
- \ No newline at end of file + + + + + +
+ \ No newline at end of file diff --git a/_nuxt/3-SVqsS-.js b/_nuxt/3-SVqsS-.js deleted file mode 100644 index 8875a973..00000000 --- a/_nuxt/3-SVqsS-.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as p}from"./CNTXZiWI.js";import u from"./BLy52rwp.js";import{d as x,u as f,w as h,a as s,o as r,c as n,b as e,e as c,t as i,f as l,g}from"./D6y6W-Zj.js";import{u as b}from"./T8qFVnUA.js";import{q as y}from"./ElOT_Ul4.js";import"./C-v3KzvZ.js";import"./DXU4rfre.js";import"./DvDH6DOc.js";const v={key:0,class:"container mx-auto"},w={class:"mb-10 bg-gray-200 p-10 shadow-lg"},k={class:"flex flex-auto items-center"},C=["src"],B={class:"flex items-center"},N={class:"text-xl font-bold text-gray-700 md:text-3xl"},R={class:"flex items-center text-sm text-gray-600"},V={class:"prose prose-sm max-w-none prose-a:text-blue-800 prose-a:no-underline hover:prose-a:text-blue-600 prose-pre:bg-white prose-pre:text-black"},G=x({__name:"[...slug]",async setup(q){let o,a;const _=f(),{data:t}=([o,a]=h(()=>b("page-data",()=>y(_.path).findOne())),o=await o,a(),o);return(A,D)=>{const m=p,d=u;return s(t)?(r(),n("div",v,[e("article",w,[e("div",k,[s(t).cover_image?(r(),n("img",{key:0,class:"mr-4 h-16 border-2 border-black",src:s(t).cover_image},null,8,C)):c("",!0),e("div",B,[e("div",null,[e("h1",N,i(s(t).title),1),e("p",R,i(s(t).date),1)])])]),e("article",V,[l(d,null,{default:g(()=>[l(m,{value:s(t)},null,8,["value"])]),_:1})])])])):c("",!0)}}});export{G as default}; diff --git a/_nuxt/7n6Wnr7D.js b/_nuxt/7n6Wnr7D.js new file mode 100644 index 00000000..d99f3a4d --- /dev/null +++ b/_nuxt/7n6Wnr7D.js @@ -0,0 +1 @@ +import{l as o,o as r,c as s,a7 as t}from"./YC8jgtvV.js";const c={};function n(e,a){return r(),s("p",null,[t(e.$slots,"default")])}const f=o(c,[["render",n]]);export{f as default}; diff --git a/_nuxt/DFlUAqO6.js b/_nuxt/8IBqTAFr.js similarity index 56% rename from _nuxt/DFlUAqO6.js rename to _nuxt/8IBqTAFr.js index 653a8e16..7d183815 100644 --- a/_nuxt/DFlUAqO6.js +++ b/_nuxt/8IBqTAFr.js @@ -1 +1 @@ -import{_ as r,a7 as t}from"./D6y6W-Zj.js";const s={};function n(e,o){return t(e.$slots,"default")}const c=r(s,[["render",n]]);export{c as default}; +import{l as r,a7 as t}from"./YC8jgtvV.js";const s={};function n(e,o){return t(e.$slots,"default")}const c=r(s,[["render",n]]);export{c as default}; diff --git a/_nuxt/8m7fprhq.js b/_nuxt/8m7fprhq.js new file mode 100644 index 00000000..d8548bb3 --- /dev/null +++ b/_nuxt/8m7fprhq.js @@ -0,0 +1 @@ +import{l as _,c as s,h as l,b as e,n as v,t as d,F as c,r as h,i as b,g as y,T as M,o as r,e as g}from"./YC8jgtvV.js";var O={};Object.defineProperty(O,"__esModule",{value:!0});var p=O.identify=void 0;const u=["C","C# / Db","D","D# / Eb","E","F","F# / Gb","G","G# / Ab","A","A# / Bb","B"],x={"0 1":{name:"No 3 Major 7",rootOffset:1},"0 2":{name:"No 3 7",rootOffset:2},"0 3":{name:"Minor",rootOffset:0},"0 4":{name:"",rootOffset:0},"0 5":{name:"5",rootOffset:5},"0 6":{name:"7",rootOffset:2},"0 7":{name:"5",rootOffset:0},"0 8":{name:"",rootOffset:8},"0 9":{name:"Minor",rootOffset:9},"0 10":{name:"No 3 7",rootOffset:0},"0 11":{name:"No 3 Major 7",rootOffset:0},"0 2 7":{name:"Suspended 2",rootOffset:0},"0 3 6 10":{name:"Half-diminished 7",rootOffset:0},"0 3 6 9":{name:"Diminished 7",rootOffset:0},"0 3 6":{name:"Diminished",rootOffset:0},"0 3 7 10":{name:"Minor 7",rootOffset:0},"0 3 7 11":{name:"Minor-major 7",rootOffset:0},"0 3 7 9":{name:"Minor 6",rootOffset:0},"0 3 7":{name:"Minor",rootOffset:0},"0 4 10":{name:"7",rootOffset:0},"0 4 11":{name:"Major 7",rootOffset:0},"0 4 5 7":{name:"Add 11",rootOffset:0},"0 4 6":{name:"Flat 5",rootOffset:0},"0 4 7 10":{name:"Dominant 7",rootOffset:0},"0 4 7 11":{name:"Major 7",rootOffset:0},"0 4 7 9":{name:"Major 6",rootOffset:0},"0 4 7":{name:"",rootOffset:0},"0 4 8 10":{name:"Augmented 7",rootOffset:0},"0 4 8":{name:"Augmented",rootOffset:0},"0 5 7":{name:"Suspended 4",rootOffset:0},"0 5 8":{name:"Minor",rootOffset:5},"0 5 9":{name:"",rootOffset:5},"0 4 9":{name:"Minor",rootOffset:9},"0 3 8":{name:"",rootOffset:8},"0 1 5":{name:"Major 7",rootOffset:1},"0 2 6":{name:"Major 7",rootOffset:2},"0 4 5":{name:"5 Major 7",rootOffset:5},"0 1 2":{name:"No 3 7 Major 7",rootOffset:2},"0 1 3":{name:"Minor Add Flat 9",rootOffset:0},"0 1 6":{name:"5 Sharp 11",rootOffset:6},"0 1 7":{name:"5 Add Flat 9",rootOffset:0},"0 1 8":{name:"5 Major 7",rootOffset:1},"0 1 9":{name:"Sharp 9",rootOffset:9},"0 1 10":{name:"Minor Add 9",rootOffset:10},"0 1 11":{name:"No 3 7 Major 7",rootOffset:1},"0 2 10":{name:"Add 9",rootOffset:10},"0 2 11":{name:"Minor Add Flat 9",rootOffset:11},"0 2 3":{name:"Minor Add 9",rootOffset:0},"0 2 4":{name:"Add 9",rootOffset:0},"0 2 5":{name:"Minor 7",rootOffset:2},"0 2 8":{name:"Flat 5",rootOffset:8},"0 2 9":{name:"5 7",rootOffset:2},"0 3 10":{name:"Minor 7",rootOffset:0},"0 3 4":{name:"Sharp 9",rootOffset:0},"0 3 5":{name:"5 7",rootOffset:5},"0 3 9":{name:"Minor 6",rootOffset:0},"0 5 10":{name:"Suspended 2",rootOffset:10},"0 5 11":{name:"5 Sharp 11",rootOffset:5},"0 5 6":{name:"5 Add Flat 9",rootOffset:5},"0 6 10":{name:"Flat 5",rootOffset:6},"0 6 7":{name:"5 Sharp 11",rootOffset:0},"0 6 8":{name:"7",rootOffset:8},"0 6 9":{name:"Minor 6",rootOffset:9},"0 7 10":{name:"5 7",rootOffset:0},"0 7 11":{name:"5 Major 7",rootOffset:0},"0 7 8":{name:"Major 7",rootOffset:8},"0 7 9":{name:"Minor 7",rootOffset:9},"0 8 10":{name:"Add 9",rootOffset:8},"0 8 11":{name:"Sharp 9",rootOffset:8},"0 9 10":{name:"Minor Add Flat 9",rootOffset:9},"0 9 11":{name:"Minor Add 9",rootOffset:9},"0 10 11":{name:"No 3 7 Major 7",rootOffset:0},"0 1 4":{name:"Sharp 9",rootOffset:9},"0 8 9":{name:"Sharp 9",rootOffset:5},"0 6 11":{name:"7/13",rootOffset:2},"0 3 11":{name:"Sharp 9",rootOffset:8}};function w(f){const a=f.map(t=>typeof t=="number"?t:u.indexOf(t));if(a.some(t=>t<0))throw new Error("Unsupported note letter or number provided");if(new Set(a.map(t=>t%12)).size===1)return{name:u[a[0]%12]};const i=a.sort((t,o)=>t-o)[0]%12,m=[...new Set(a.map(t=>(t-i)%12).sort((t,o)=>t-o))],n=x[m.join(" ")];if(n){const t=(i+n.rootOffset)%12,o=u[t];return{name:n.name!==""?`${o} ${n.name}`:o,interval:m,root:t}}else return{name:void 0}}p=O.identify=w;const A={mounted(){typeof navigator.requestMIDIAccess<"u"&&navigator.requestMIDIAccess().then(f=>{this.midi=f,this.midi.inputs.forEach(a=>{a.onmidimessage=i=>{i.data[0]===144&&(this.activeKeys.set(i.data[1],i.data),this.$forceUpdate()),i.data[0]===128&&(this.activeKeys.delete(i.data[1]),this.$forceUpdate())}})},f=>{console.error(f)})},data(){return{tooltip:!1,midi:void 0,activeKeys:new Map}},computed:{inputs(){if(typeof this.midi<"u")return Array.from(this.midi.inputs.values())},outputs(){if(typeof this.midi<"u")return Array.from(this.midi.outputs.values())}},methods:{orderedNotes(){return Array.from(this.activeKeys.keys()).sort()},chord(){const f=Array.from(this.activeKeys.keys());return p(f).name}}},k={class:"h-2/3 bg-gradient-to-b from-green-900 via-purple-900 to-indigo-900 text-white"},N={key:0,class:"p-4 text-center font-light tracking-wide"},S=e("a",{class:"text-blue-500 underline",href:"https://developer.mozilla.org/en-US/docs/Web/API/MIDIMessageEvent#browser_compatibility"},"not supported",-1),j={key:1},I={class:"flex flex-wrap"},D={class:"absolute bottom-16 right-2"},F=e("div",{class:"mb-0 rounded-t-lg border-b border-solid bg-green-600 p-3 font-semibold uppercase text-white opacity-75"}," MIDI Status ",-1),E={class:"p-3 font-mono text-orange-900"},z={class:"mb-2 font-bold"},V={class:"mb-2"},C=e("div",{class:"font-bold"},"Inputs:",-1),B={key:0,class:"p-4 text-center italic"},K={key:1},T={class:"flex-1"},P={class:"flex-1"},U={class:"mb-2"},G=e("div",{class:"font-bold"},"Outputs:",-1),L={key:0,class:"p-4 text-center italic"},q={key:1},H={class:"flex-1"},R={class:"flex-1"},W={class:"absolute bottom-2 right-2"},Y=e("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20",class:"h-10 w-10"},[e("g",{fill:"none"},[e("path",{d:"M2.5 4a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5h-15zm.5 6h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v5H3v-5zm2.75-2.5a.75.75 0 1 1 0-1.5a.75.75 0 0 1 0 1.5zm6.25-1a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm-3 .251a.75.75 0 1 1-1.5 0a.75.75 0 0 1 1.5 0z",fill:"currentColor"})])],-1),J=[Y],Q={class:"absolute bottom-4 left-4"},X={class:"flex"},Z={class:"grid h-screen place-items-center"},$={class:"text-center text-4xl font-semibold tracking-wide"},ee={key:0};function te(f,a,i,m,n,t){return r(),s("div",k,[typeof n.midi>"u"?(r(),s("div",N,[l(" Unfortunately, the Web MIDI API is "),S,l(" in all browsers... ")])):(r(),s("div",j,[e("div",I,[e("div",D,[e("div",{class:v([{hidden:!n.tooltip,block:n.tooltip},"z-50 max-w-md break-words rounded-lg border-2 border-green-800 bg-yellow-200 text-sm font-normal leading-normal"])},[e("div",null,[F,e("div",E,[e("div",z,[l(" Enabled: "),e("span",null,d(typeof n.midi<"u"?"Yep!":"Nope"),1)]),e("div",V,[C,t.inputs.length===0?(r(),s("div",B," No input devices detected :( ")):(r(),s("div",K,[(r(!0),s(c,null,h(t.inputs,o=>(r(),s("div",{key:o.id,class:"flex"},[e("div",T,d(o.manufacturer),1),e("div",P,d(o.name),1)]))),128))]))]),e("div",U,[G,t.outputs.length===0?(r(),s("div",L," No output devices detected :( ")):(r(),s("div",q,[(r(!0),s(c,null,h(t.outputs,o=>(r(),s("div",{key:o.id,class:"flex"},[e("div",H,d(o.manufacturer),1),e("div",R,d(o.name),1)]))),128))]))])])])],2)]),e("div",W,[e("button",{onClick:a[0]||(a[0]=o=>n.tooltip=!n.tooltip),class:"border-3 rounded-lg border-green-600 bg-green-50 px-1 text-green-600 shadow hover:text-green-500 hover:shadow-lg",type:"button"},J)])]),e("div",Q,[e("div",X,[(r(!0),s(c,null,h(t.orderedNotes(),o=>(r(),s("div",{key:o,class:"p-4"},d(o),1))),128))])]),e("div",Z,[e("div",null,[e("div",$,[b(M,{"enter-active-class":"duration-500 ease-out","enter-class":"opacity-0 transform","enter-to-class":"opacity-100","leave-active-class":"duration-500","leave-class":"opacity-100","leave-to-class":"opacity-0 transform"},{default:y(()=>[n.activeKeys.size>=1?(r(),s("div",ee,d(t.chord()||"?"),1)):g("",!0)]),_:1})])])])]))])}const se=_(A,[["render",te]]);export{se as default}; diff --git a/_nuxt/BNjek0E5.js b/_nuxt/8tpp9ZIr.js similarity index 58% rename from _nuxt/BNjek0E5.js rename to _nuxt/8tpp9ZIr.js index 5a27b65e..82adfb53 100644 --- a/_nuxt/BNjek0E5.js +++ b/_nuxt/8tpp9ZIr.js @@ -1 +1 @@ -import{d as n,K as e}from"./D6y6W-Zj.js";const t=n({name:"DocumentDrivenNotFound",render(){return e("div","Document not found")}});export{t as default}; +import{d as n,K as e}from"./YC8jgtvV.js";const t=n({name:"DocumentDrivenNotFound",render(){return e("div","Document not found")}});export{t as default}; diff --git a/_nuxt/avmke64t.js b/_nuxt/B3uj60Hf.js similarity index 93% rename from _nuxt/avmke64t.js rename to _nuxt/B3uj60Hf.js index e3c1d83e..61dbc0e9 100644 --- a/_nuxt/avmke64t.js +++ b/_nuxt/B3uj60Hf.js @@ -1 +1 @@ -import{_ as u,c as _,o as m,b as c}from"./D6y6W-Zj.js";const p={data(){return{}},mounted(){const s=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"],a=e=>{const i=t=>e.unhex([t.slice(1,3),t.slice(3,5),t.slice(5,7)]),d=(t,r)=>t.map(n=>{const o=e.floor(n+e.random(-r,r));return o<0?0:o>255?255:o});e.setup=()=>{e.createCanvas(400,400),e.frameRate(5)},e.draw=()=>{e.background(0,0,0),e.noStroke(),e.noFill();const t=9,r=400/t;for(let n=0;n<=t;n++)for(let o=0;o<=t;o++){const f=s[o%9];e.fill(d(i(f),15)),e.square(n*r,o*r,r)}}};new this.$p5(a,"canvas")}},h={class:"bg-gradient-to-b from-green-800 to-gray-800"},v=c("div",{class:"grid h-screen place-items-center"},[c("div",{class:"font-mono text-white"},[c("div",{class:"mb-2 border-2 border-white"},[c("div",{id:"canvas"})])])],-1),I=[v];function b(s,a,e,i,d,l){return m(),_("div",h,I)}const g=u(p,[["render",b]]);export{g as default}; +import{l as u,c as _,o as m,b as c}from"./YC8jgtvV.js";const p={data(){return{}},mounted(){const s=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"],a=e=>{const i=t=>e.unhex([t.slice(1,3),t.slice(3,5),t.slice(5,7)]),d=(t,r)=>t.map(n=>{const o=e.floor(n+e.random(-r,r));return o<0?0:o>255?255:o});e.setup=()=>{e.createCanvas(400,400),e.frameRate(5)},e.draw=()=>{e.background(0,0,0),e.noStroke(),e.noFill();const t=9,r=400/t;for(let n=0;n<=t;n++)for(let o=0;o<=t;o++){const f=s[o%9];e.fill(d(i(f),15)),e.square(n*r,o*r,r)}}};new this.$p5(a,"canvas")}},h={class:"bg-gradient-to-b from-green-800 to-gray-800"},v=c("div",{class:"grid h-screen place-items-center"},[c("div",{class:"font-mono text-white"},[c("div",{class:"mb-2 border-2 border-white"},[c("div",{id:"canvas"})])])],-1),I=[v];function b(s,a,e,i,d,l){return m(),_("div",h,I)}const g=u(p,[["render",b]]);export{g as default}; diff --git a/_nuxt/B4L3tEQJ.js b/_nuxt/B4L3tEQJ.js deleted file mode 100644 index 5e2b5fad..00000000 --- a/_nuxt/B4L3tEQJ.js +++ /dev/null @@ -1 +0,0 @@ -import{d as i,H as c,v as p,o as s,c as n,a as u,a7 as t}from"./D6y6W-Zj.js";const f=["id"],l=["href"],k=i({__name:"ProseH5",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=p(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h5)});return(e,m)=>(s(),n("h5",{id:e.id},[e.id&&u(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/B4Ww-T0F.js b/_nuxt/B4Ww-T0F.js new file mode 100644 index 00000000..3111fbcc --- /dev/null +++ b/_nuxt/B4Ww-T0F.js @@ -0,0 +1 @@ +import{a5 as _,R as B,ab as T,H as M,P as H,N as J}from"./YC8jgtvV.js";import{g as k,a as P,b as O,o as b,c as G,d as $,f as j,h as D,i as Z}from"./NquB2IUV.js";import{p as q}from"./C-v3KzvZ.js";import{u as U}from"./JthqPOXk.js";import"./DvDH6DOc.js";const F="memory",V=()=>{const t=new Map;return{name:F,options:{},hasItem(r){return t.has(r)},getItem(r){return t.get(r)??null},getItemRaw(r){return t.get(r)??null},setItem(r,n){t.set(r,n)},setItemRaw(r,n){t.set(r,n)},removeItem(r){t.delete(r)},getKeys(){return Array.from(t.keys())},clear(){t.clear()},dispose(){t.clear()}}};function Q(t){return!t||typeof t.then!="function"?Promise.resolve(t):t}function p(t,...r){try{return Q(t(...r))}catch(n){return Promise.reject(n)}}function X(t){const r=typeof t;return t===null||r!=="object"&&r!=="function"}function ee(t){const r=Object.getPrototypeOf(t);return!r||r.isPrototypeOf(Object)}function K(t){if(X(t))return String(t);if(ee(t)||Array.isArray(t))return JSON.stringify(t);if(typeof t.toJSON=="function")return K(t.toJSON());throw new Error("[unstorage] Cannot stringify value!")}function z(){if(typeof Buffer===void 0)throw new TypeError("[unstorage] Buffer is not supported!")}const C="base64:";function te(t){if(typeof t=="string")return t;z();const r=Buffer.from(t).toString("base64");return C+r}function re(t){return typeof t!="string"||!t.startsWith(C)?t:(z(),Buffer.from(t.slice(C.length),"base64"))}const ne=["hasItem","getItem","getItemRaw","setItem","setItemRaw","removeItem","getMeta","setMeta","removeMeta","getKeys","clear","mount","unmount"];function ie(t,r){if(r=E(r),!r)return t;const n={...t};for(const a of ne)n[a]=(c="",...l)=>t[a](r+c,...l);return n.getKeys=(a="",...c)=>t.getKeys(r+a,...c).then(l=>l.map(o=>o.slice(r.length))),n}function y(t){return t?t.split("?")[0].replace(/[/\\]/g,":").replace(/:+/g,":").replace(/^:|:$/g,""):""}function ae(...t){return y(t.join(":"))}function E(t){return t=y(t),t?t+":":""}const se="memory",oe=()=>{const t=new Map;return{name:se,options:{},hasItem(r){return t.has(r)},getItem(r){return t.get(r)??null},getItemRaw(r){return t.get(r)??null},setItem(r,n){t.set(r,n)},setItemRaw(r,n){t.set(r,n)},removeItem(r){t.delete(r)},getKeys(){return Array.from(t.keys())},clear(){t.clear()},dispose(){t.clear()}}};function ue(t={}){const r={mounts:{"":t.driver||oe()},mountpoints:[""],watching:!1,watchListeners:[],unwatch:{}},n=e=>{for(const i of r.mountpoints)if(e.startsWith(i))return{base:i,relativeKey:e.slice(i.length),driver:r.mounts[i]};return{base:"",relativeKey:e,driver:r.mounts[""]}},a=(e,i)=>r.mountpoints.filter(s=>s.startsWith(e)||i&&e.startsWith(s)).map(s=>({relativeBase:e.length>s.length?e.slice(s.length):void 0,mountpoint:s,driver:r.mounts[s]})),c=(e,i)=>{if(r.watching){i=y(i);for(const s of r.watchListeners)s(e,i)}},l=async()=>{if(!r.watching){r.watching=!0;for(const e in r.mounts)r.unwatch[e]=await x(r.mounts[e],c,e)}},o=async()=>{if(r.watching){for(const e in r.unwatch)await r.unwatch[e]();r.unwatch={},r.watching=!1}},h=(e,i,s)=>{const u=new Map,m=f=>{let d=u.get(f.base);return d||(d={driver:f.driver,base:f.base,items:[]},u.set(f.base,d)),d};for(const f of e){const d=typeof f=="string",A=y(d?f:f.key),w=d?void 0:f.value,v=d||!f.options?i:{...i,...f.options},I=n(A);m(I).items.push({key:A,value:w,relativeKey:I.relativeKey,options:v})}return Promise.all([...u.values()].map(f=>s(f))).then(f=>f.flat())},g={hasItem(e,i={}){e=y(e);const{relativeKey:s,driver:u}=n(e);return p(u.hasItem,s,i)},getItem(e,i={}){e=y(e);const{relativeKey:s,driver:u}=n(e);return p(u.getItem,s,i).then(m=>_(m))},getItems(e,i){return h(e,i,s=>s.driver.getItems?p(s.driver.getItems,s.items.map(u=>({key:u.relativeKey,options:u.options})),i).then(u=>u.map(m=>({key:ae(s.base,m.key),value:_(m.value)}))):Promise.all(s.items.map(u=>p(s.driver.getItem,u.relativeKey,u.options).then(m=>({key:u.key,value:_(m)})))))},getItemRaw(e,i={}){e=y(e);const{relativeKey:s,driver:u}=n(e);return u.getItemRaw?p(u.getItemRaw,s,i):p(u.getItem,s,i).then(m=>re(m))},async setItem(e,i,s={}){if(i===void 0)return g.removeItem(e);e=y(e);const{relativeKey:u,driver:m}=n(e);m.setItem&&(await p(m.setItem,u,K(i),s),m.watch||c("update",e))},async setItems(e,i){await h(e,i,async s=>{if(s.driver.setItems)return p(s.driver.setItems,s.items.map(u=>({key:u.relativeKey,value:K(u.value),options:u.options})),i);s.driver.setItem&&await Promise.all(s.items.map(u=>p(s.driver.setItem,u.relativeKey,K(u.value),u.options)))})},async setItemRaw(e,i,s={}){if(i===void 0)return g.removeItem(e,s);e=y(e);const{relativeKey:u,driver:m}=n(e);if(m.setItemRaw)await p(m.setItemRaw,u,i,s);else if(m.setItem)await p(m.setItem,u,te(i),s);else return;m.watch||c("update",e)},async removeItem(e,i={}){typeof i=="boolean"&&(i={removeMeta:i}),e=y(e);const{relativeKey:s,driver:u}=n(e);u.removeItem&&(await p(u.removeItem,s,i),(i.removeMeta||i.removeMata)&&await p(u.removeItem,s+"$",i),u.watch||c("remove",e))},async getMeta(e,i={}){typeof i=="boolean"&&(i={nativeOnly:i}),e=y(e);const{relativeKey:s,driver:u}=n(e),m=Object.create(null);if(u.getMeta&&Object.assign(m,await p(u.getMeta,s,i)),!i.nativeOnly){const f=await p(u.getItem,s+"$",i).then(d=>_(d));f&&typeof f=="object"&&(typeof f.atime=="string"&&(f.atime=new Date(f.atime)),typeof f.mtime=="string"&&(f.mtime=new Date(f.mtime)),Object.assign(m,f))}return m},setMeta(e,i,s={}){return this.setItem(e+"$",i,s)},removeMeta(e,i={}){return this.removeItem(e+"$",i)},async getKeys(e,i={}){e=E(e);const s=a(e,!0);let u=[];const m=[];for(const f of s){const A=(await p(f.driver.getKeys,f.relativeBase,i)).map(w=>f.mountpoint+y(w)).filter(w=>!u.some(v=>w.startsWith(v)));m.push(...A),u=[f.mountpoint,...u.filter(w=>!w.startsWith(f.mountpoint))]}return e?m.filter(f=>f.startsWith(e)&&!f.endsWith("$")):m.filter(f=>!f.endsWith("$"))},async clear(e,i={}){e=E(e),await Promise.all(a(e,!1).map(async s=>{if(s.driver.clear)return p(s.driver.clear,s.relativeBase,i);if(s.driver.removeItem){const u=await s.driver.getKeys(s.relativeBase||"",i);return Promise.all(u.map(m=>s.driver.removeItem(m,i)))}}))},async dispose(){await Promise.all(Object.values(r.mounts).map(e=>L(e)))},async watch(e){return await l(),r.watchListeners.push(e),async()=>{r.watchListeners=r.watchListeners.filter(i=>i!==e),r.watchListeners.length===0&&await o()}},async unwatch(){r.watchListeners=[],await o()},mount(e,i){if(e=E(e),e&&r.mounts[e])throw new Error(`already mounted at ${e}`);return e&&(r.mountpoints.push(e),r.mountpoints.sort((s,u)=>u.length-s.length)),r.mounts[e]=i,r.watching&&Promise.resolve(x(i,c,e)).then(s=>{r.unwatch[e]=s}).catch(console.error),g},async unmount(e,i=!0){e=E(e),!(!e||!r.mounts[e])&&(r.watching&&e in r.unwatch&&(r.unwatch[e](),delete r.unwatch[e]),i&&await L(r.mounts[e]),r.mountpoints=r.mountpoints.filter(s=>s!==e),delete r.mounts[e])},getMount(e=""){e=y(e)+":";const i=n(e);return{driver:i.driver,base:i.base}},getMounts(e="",i={}){return e=y(e),a(e,i.parents).map(u=>({driver:u.driver,base:u.mountpoint}))}};return g}function x(t,r,n){return t.watch?t.watch((a,c)=>r(a,n+c)):()=>{}}async function L(t){typeof t.dispose=="function"&&await p(t.dispose)}function ce(t={}){const r=le(n,t.operators);function n(a,c){return typeof c!="object"||c instanceof RegExp?r.$eq(a,c):Object.keys(c||{}).every(l=>{const o=c[l];if(l.startsWith("$")&&r[l]){const h=r[l];return typeof h=="function"?h(a,o):!1}return n(k(a,l),o)})}return n}function le(t,r={}){return{$match:(n,a)=>t(n,a),$eq:(n,a)=>a instanceof RegExp?a.test(n):n===a,$ne:(n,a)=>a instanceof RegExp?!a.test(n):n!==a,$not:(n,a)=>!t(n,a),$and:(n,a)=>(P(a,"$and requires an array as condition"),a.every(c=>t(n,c))),$or:(n,a)=>(P(a,"$or requires an array as condition"),a.some(c=>t(n,c))),$in:(n,a)=>O(a).some(c=>Array.isArray(n)?t(n,{$contains:c}):t(n,c)),$contains:(n,a)=>(n=Array.isArray(n)?n:String(n),O(a).every(c=>n.includes(c))),$icontains:(n,a)=>{if(typeof a!="string")throw new TypeError("$icontains requires a string, use $contains instead");return n=String(n).toLocaleLowerCase(),O(a).every(c=>n.includes(c.toLocaleLowerCase()))},$containsAny:(n,a)=>(P(a,"$containsAny requires an array as condition"),n=Array.isArray(n)?n:String(n),a.some(c=>n.includes(c))),$exists:(n,a)=>a?typeof n<"u":typeof n>"u",$type:(n,a)=>typeof n===String(a),$regex:(n,a)=>{if(!(a instanceof RegExp)){const c=String(a).match(/\/(.*)\/([dgimsuy]*)$/);a=c!=null&&c[1]?new RegExp(c[1],c[2]||""):new RegExp(a)}return a.test(String(n||""))},$lt:(n,a)=>nn<=a,$gt:(n,a)=>n>a,$gte:(n,a)=>n>=a,...r||{}}}function fe(t){const r=ce(),n=(l,{query:o,before:h,after:g})=>{const e=typeof o=="string"?{_path:o}:o,i=l.findIndex(u=>r(u,e));h=h??1,g=g??1;const s=new Array(h+g).fill(null,0);return i===-1?s:s.map((u,m)=>l[i-h+m+ +(m>=h)]||null)},a=[(l,o)=>{const h=l.result.filter(g=>O(o.where).every(e=>r(g,e)));return{...l,result:h,total:h.length}},(l,o)=>O(o.sort).forEach(h=>G(l.result,h)),function(o,h,g){var e;if(h.surround){let i=n(((e=o.result)==null?void 0:e.length)===1?g:o.result,h.surround);i=$(j(h.without))(i),i=$(D(h.only))(i),o.surround=i}return o}],c=[(l,o)=>{if(o.skip)return{...l,result:l.result.slice(o.skip),skip:o.skip}},(l,o)=>{if(o.limit)return{...l,result:l.result.slice(0,o.limit),limit:o.limit}},function(o,h,g){var e,i,s;if(h.dirConfig){const u=((e=o.result[0])==null?void 0:e._path)||((s=(i=h.where)==null?void 0:i.find(m=>m._path))==null?void 0:s._path);if(typeof u=="string"){const m=g.find(f=>f._path===B(u,"_dir"));m&&(o.dirConfig={_path:m._path,...j(["_"])(m)})}}return o},(l,o)=>({...l,result:$(j(o.without))(l.result)}),(l,o)=>({...l,result:$(D(o.only))(l.result)})];return async l=>{const o=await t(),h=l.params(),g={result:o,limit:0,skip:0,total:o.length},e=a.reduce((s,u)=>u(s,h,o)||s,g);if(h.count)return{result:e.result.length};const i=c.reduce((s,u)=>u(s,h,o)||s,e);return h.first?{...b(["skip","limit","total"])(i),result:i.result[0]}:i}}function N(t){const r=fe(t);return async n=>{var l;n.params().first&&n.withDirConfig();const a=n.params(),c=await r(n);return a.surround?c==null?void 0:c.surround:(c!=null&&c.dirConfig&&(c.result={_path:(l=c.dirConfig)==null?void 0:l._path,...c.result,_dir:c.dirConfig}),c==null?void 0:c.result)}}var me={exports:{}};(function(t,r){(function(n,a,c){t.exports=c(),t.exports.default=c()})("slugify",T,function(){var n=JSON.parse(`{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E'","Ը":"Y'","Թ":"T'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C'","Կ":"K","Հ":"H","Ձ":"D'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P'","Ք":"Q'","Օ":"O''","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"'","’":"'","“":"\\"","”":"\\"","„":"\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}`),a=JSON.parse('{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}');function c(l,o){if(typeof l!="string")throw new Error("slugify: string argument expected");o=typeof o=="string"?{replacement:o}:o||{};var h=a[o.locale]||{},g=o.replacement===void 0?"-":o.replacement,e=o.trim===void 0?!0:o.trim,i=l.normalize().split("").reduce(function(s,u){var m=h[u];return m===void 0&&(m=n[u]),m===void 0&&(m=u),m===g&&(m=" "),s+m.replace(o.remove||/[^\w\s$*_+~.()'"!\-:@]+/g,"")},"");return o.strict&&(i=i.replace(/[^A-Za-z0-9\s]/g,"")),e&&(i=i.trim()),i=i.replace(/\s+/g,g),o.lower&&(i=i.toLowerCase()),i}return c.extend=function(l){Object.assign(n,l)},c})})(me);const he=t=>t.split(/[\s-]/g).map(q).join(" ");function ge(t,r){const{navigation:n}=M().public.content;if(n===!1)return[];const a=l=>({...de(["title",...n.fields])(l),...ye(l==null?void 0:l.navigation)?l.navigation:{}}),c=t.sort((l,o)=>l._path.localeCompare(o._path)).reduce((l,o)=>{var m;const h=o._path.substring(1).split("/"),g=o._id.split(":").slice(1),e=!!((m=g[g.length-1])!=null&&m.match(/([1-9][0-9]*\.)?index.md/g)),i=f=>({title:f.title,_path:f._path,_file:f._file,children:[],...a(f),...f._draft?{_draft:!0}:{}}),s=i(o);if(e){const f=r[s._path];if(typeof(f==null?void 0:f.navigation)<"u"&&!(f!=null&&f.navigation))return l;if(o._path!=="/"){const d=i(o);s.children.push(d)}f&&Object.assign(s,a(f))}return h.length===1?(l.push(s),l):(h.slice(0,-1).reduce((f,d,A)=>{const w="/"+h.slice(0,A+1).join("/"),v=r[w];if(typeof(v==null?void 0:v.navigation)<"u"&&!v.navigation)return[];let I=f.find(W=>W._path===w);return I||(I={title:he(d),_path:w,_file:o._file,children:[],...v&&a(v)},f.push(I)),I.children},l).push(s),l)},[]);return Y(c)}const pe=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function Y(t){var n;t.forEach(a=>{a._file=a._file.split(".").slice(0,-1).join(".")});const r=t.sort((a,c)=>pe.compare(a._file,c._file));for(const a of r)(n=a.children)!=null&&n.length?Y(a.children):delete a.children,delete a._file;return t}function de(t){return r=>(r=r||{},t&&t.length?t.filter(n=>typeof r[n]<"u").reduce((n,a)=>Object.assign(n,{[a]:r[a]}),{}):r)}function ye(t){return Object.prototype.toString.call(t)==="[object Object]"}const we=t=>H(t,M().public.content.api.baseURL),ve=ie(ue({driver:V()}),"@content");function Ie(t){async function r(){const n=new Set(await t.getKeys("cache:")),a=U().getPreviewToken();if(a){const l=await t.getItem(`${a}$`).then(g=>g||{});if(Array.isArray(l.ignoreSources)){const g=l.ignoreSources.map(e=>`cache:${e.trim()}:`);for(const e of n)g.some(i=>e.startsWith(i))&&n.delete(e)}const o=await t.getKeys(`${a}:`),h=await Promise.all(o.map(g=>t.getItem(g)));for(const g of h)n.delete(`cache:${g._id}`),g.__deleted||n.add(`${a}:${g._id}`)}return await Promise.all(Array.from(n).map(l=>t.getItem(l)))}return{storage:t,fetch:N(r),query:n=>Z(N(r),{initialParams:n,legacy:!0})}}let R=null,S=null;async function Ae(){return S?await S:R||(S=Ee(),R=await S),R}async function Ee(){const t=J(),{content:r}=M().public,n=Ie(ve),a=await n.storage.getItem("integrity");if(r.integrity!==+(a||0)){const{contents:c,navigation:l}=await $fetch(we(r.integrity?`cache.${r.integrity}.json`:"cache.json"));await Promise.all(c.map(o=>n.storage.setItem(`cache:${o._id}`,o))),await n.storage.setItem("navigation",l),await n.storage.setItem("integrity",r.integrity)}return await t.callHook("content:storage",n.storage),n}async function Pe(t){const r=await Ae();if(!U().getPreviewToken()&&Object.keys(t||{}).length===0)return r.storage.getItem("navigation");const n=await r.query(t).where({_partial:!1,navigation:{$ne:!1}}).find(),c=(await r.query().where({_path:/\/_dir$/i,_partial:!0}).find()).reduce((l,o)=>{var g;((g=o.title)==null?void 0:g.toLowerCase())==="dir"&&(o.title=void 0);const h=o._path.split("/").slice(0,-1).join("/")||"/";return l[h]={...o,...o.body},l},{});return ge(n,c)}export{ve as contentStorage,Ie as createDB,Pe as generateNavigation,Ae as useContentDatabase}; diff --git a/_nuxt/B7vccJE6.js b/_nuxt/B7vccJE6.js deleted file mode 100644 index 5a1978c6..00000000 --- a/_nuxt/B7vccJE6.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as t,c,a7 as r}from"./D6y6W-Zj.js";const s={};function n(e,a){return t(),c("blockquote",null,[r(e.$slots,"default")])}const _=o(s,[["render",n]]);export{_ as default}; diff --git a/_nuxt/B9owgOfn.js b/_nuxt/B9owgOfn.js new file mode 100644 index 00000000..cd7a26fd --- /dev/null +++ b/_nuxt/B9owgOfn.js @@ -0,0 +1 @@ +import{d as p,H as f,k as i,o as t,c as s,a as u,a7 as n}from"./YC8jgtvV.js";const l=["id"],d=["href"],_=p({__name:"ProseH5",props:{id:{}},setup(r){const a=r,{headings:o}=f().public.mdc,c=i(()=>{var e;return a.id&&(typeof(o==null?void 0:o.anchorLinks)=="boolean"&&(o==null?void 0:o.anchorLinks)===!0||typeof(o==null?void 0:o.anchorLinks)=="object"&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h5))});return(e,k)=>(t(),s("h5",{id:e.id},[e.id&&u(c)?(t(),s("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,d)):n(e.$slots,"default",{key:1})],8,l))}});export{_ as default}; diff --git a/_nuxt/C9mKha9k.js b/_nuxt/BDj4EL7w.js similarity index 81% rename from _nuxt/C9mKha9k.js rename to _nuxt/BDj4EL7w.js index ef9a45a1..8f0932b6 100644 --- a/_nuxt/C9mKha9k.js +++ b/_nuxt/BDj4EL7w.js @@ -1 +1 @@ -import{_ as x,c as u,o as v,b as c}from"./D6y6W-Zj.js";const _={data(){return{}},mounted(){document.getElementById("canvas").textContent="";const o=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"],m=e=>{const r=document.getElementById("canvas"),a=r.clientWidth,n=r.clientHeight,f=[{color:o[1],min:0,max:.2,yoff:2},{color:o[2],min:.2,max:.4,yoff:2},{color:o[3],min:.4,max:.6,yoff:2},{color:o[4],min:.6,max:.8,yoff:2},{color:o[5],min:.8,max:1,yoff:2}],l=t=>{e.fill(t.color),e.beginShape();let d=1;for(let i=0;i<=a;i+=10){const h=e.map(e.noise(d,t.yoff),0,1,t.min*n,t.max*n);e.curveVertex(i,h),d+=e.random(.5)}t.yoff+=e.random(-.5,.5),e.curveVertex(a,n),e.curveVertex(0,n),e.endShape(e.CLOSE)},s=()=>{e.clear(),e.background(o[0]),f.forEach(t=>l(t))};e.setup=()=>{e.createCanvas(a,n),e.frameRate(5),e.smooth(),e.stroke(255),e.strokeWeight(3),s(),e.noLoop()},e.mousePressed=()=>{s()}};new this.$p5(m,"canvas")}},y={class:"select-none bg-gradient-to-b from-green-800 to-gray-800"},p=c("div",{class:"m-6 grid h-2/3 place-items-center"},[c("div",{class:"font-mono text-white"},[c("div",{id:"canvas",class:"mb-2 h-96 border-2 border-white"}),c("div",{class:"my-2 w-48 text-center md:w-full"}," Click or tap anywhere to redraw the waves! ")])],-1),g=[p];function w(o,m,e,r,a,n){return v(),u("div",y,g)}const b=x(_,[["render",w]]);export{b as default}; +import{l as x,c as u,o as v,b as c}from"./YC8jgtvV.js";const _={data(){return{}},mounted(){document.getElementById("canvas").textContent="";const o=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"],m=e=>{const r=document.getElementById("canvas"),a=r.clientWidth,n=r.clientHeight,l=[{color:o[1],min:0,max:.2,yoff:2},{color:o[2],min:.2,max:.4,yoff:2},{color:o[3],min:.4,max:.6,yoff:2},{color:o[4],min:.6,max:.8,yoff:2},{color:o[5],min:.8,max:1,yoff:2}],f=t=>{e.fill(t.color),e.beginShape();let d=1;for(let i=0;i<=a;i+=10){const h=e.map(e.noise(d,t.yoff),0,1,t.min*n,t.max*n);e.curveVertex(i,h),d+=e.random(.5)}t.yoff+=e.random(-.5,.5),e.curveVertex(a,n),e.curveVertex(0,n),e.endShape(e.CLOSE)},s=()=>{e.clear(),e.background(o[0]),l.forEach(t=>f(t))};e.setup=()=>{e.createCanvas(a,n),e.frameRate(5),e.smooth(),e.stroke(255),e.strokeWeight(3),s(),e.noLoop()},e.mousePressed=()=>{s()}};new this.$p5(m,"canvas")}},y={class:"select-none bg-gradient-to-b from-green-800 to-gray-800"},p=c("div",{class:"m-6 grid h-2/3 place-items-center"},[c("div",{class:"font-mono text-white"},[c("div",{id:"canvas",class:"mb-2 h-96 border-2 border-white"}),c("div",{class:"my-2 w-48 text-center md:w-full"}," Click or tap anywhere to redraw the waves! ")])],-1),g=[p];function w(o,m,e,r,a,n){return v(),u("div",y,g)}const b=x(_,[["render",w]]);export{b as default}; diff --git a/_nuxt/DxVn7wJS.js b/_nuxt/BJy0y-3L.js similarity index 97% rename from _nuxt/DxVn7wJS.js rename to _nuxt/BJy0y-3L.js index 48f9228c..d8bc8125 100644 --- a/_nuxt/DxVn7wJS.js +++ b/_nuxt/BJy0y-3L.js @@ -1 +1 @@ -import{_ as g,c as h,b as n,A as d,B as c,t as a,o as u}from"./D6y6W-Zj.js";const p={data(){return{height:0,width:0,distance:3,strokeWidth:1,startingX:125,startingY:150,startingAngle:0,sequence:"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678",sketch:void 0}},methods:{render(i){const e="0123456789",r=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"],o={x:this.startingX,y:this.startingY,a:this.startingAngle};i.strokeWeight(this.strokeWidth),i.clear(),i.background(r[9]),i.beginShape(),i.vertex(o.x,o.y);for(let t=0;t{r.setup=()=>{r.createCanvas(this.width,this.height),r.noLoop(),r.noFill(),r.stroke(255),this.sketch=r,this.render(this.sketch)}};new this.$p5(e,"canvas")}},m={class:"select-none bg-gradient-to-b from-green-800 to-gray-800"},x={class:"m-8 grid place-items-center"},b={class:"font-mono text-white"},f=n("div",{id:"canvas-container",class:"mb-2 h-96 border-2 border-white"},[n("div",{id:"canvas"})],-1),v={class:"my-2 md:w-full"},k={class:"grid-rows-auto my-2 grid grid-cols-2 gap-4 border-2 border-white p-2 md:grid-rows-1"},_={class:"flex flex-col"},y={for:"distanceInput",class:"text-right"},A={class:"flex flex-col"},w={for:"strokeInput",class:"text-right"},I={class:"flex flex-col"},C={for:"startingXInput",class:"text-right"},V={class:"flex flex-col"},W={for:"startingYInput",class:"text-right"},X={class:"flex flex-col"},Y={for:"startingAngleInput",class:"text-right"};function D(i,e,r,o,t,l){return u(),h("div",m,[n("div",x,[n("div",b,[f,n("div",v,[d(n("textarea",{readonly:"","onUpdate:modelValue":e[0]||(e[0]=s=>t.sequence=s),class:"block h-24 w-full border-2 border-white bg-black p-2 text-white placeholder:italic placeholder:text-slate-400 focus:border-2 focus:border-yellow-500 focus:outline-none sm:text-sm",placeholder:"Enter a sequence of numbers...",type:"text"},null,512),[[c,t.sequence]])]),n("div",k,[n("div",_,[n("label",y,"Segment Length ["+a(t.distance)+"]",1),d(n("input",{id:"distanceInput","onUpdate:modelValue":e[1]||(e[1]=s=>t.distance=s),onChange:e[2]||(e[2]=s=>l.render(t.sketch)),type:"range",min:"1",max:"25",class:"accent-black"},null,544),[[c,t.distance,void 0,{number:!0}]])]),n("div",A,[n("label",w,"Stroke Width ["+a(t.strokeWidth)+"]",1),d(n("input",{id:"strokeInput","onUpdate:modelValue":e[3]||(e[3]=s=>t.strokeWidth=s),onChange:e[4]||(e[4]=s=>l.render(t.sketch)),type:"range",min:"1",max:"10",class:"accent-black"},null,544),[[c,t.strokeWidth,void 0,{number:!0}]])]),n("div",I,[n("label",C,"X Position ["+a(t.startingX)+"]",1),d(n("input",{id:"startingXInput","onUpdate:modelValue":e[5]||(e[5]=s=>t.startingX=s),onChange:e[6]||(e[6]=s=>l.render(t.sketch)),type:"range",min:"0",max:"500",class:"accent-black"},null,544),[[c,t.startingX,void 0,{number:!0}]])]),n("div",V,[n("label",W,"Y Position ["+a(t.startingY)+"]",1),d(n("input",{id:"startingYInput","onUpdate:modelValue":e[7]||(e[7]=s=>t.startingY=s),onChange:e[8]||(e[8]=s=>l.render(t.sketch)),type:"range",min:"0",max:"500",class:"accent-black"},null,544),[[c,t.startingY,void 0,{number:!0}]])]),n("div",X,[n("label",Y,"Angle ["+a(t.startingAngle)+"]",1),d(n("input",{id:"startingAngleInput","onUpdate:modelValue":e[9]||(e[9]=s=>t.startingAngle=s),onChange:e[10]||(e[10]=s=>l.render(t.sketch)),type:"range",min:"-180",max:"180",class:"accent-black"},null,544),[[c,t.startingAngle,void 0,{number:!0}]])])])])])])}const F=g(p,[["render",D]]);export{F as default}; +import{l as g,c as h,b as n,B as d,C as c,t as a,o as u}from"./YC8jgtvV.js";const p={data(){return{height:0,width:0,distance:3,strokeWidth:1,startingX:125,startingY:150,startingAngle:0,sequence:"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678",sketch:void 0}},methods:{render(i){const e="0123456789",r=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"],o={x:this.startingX,y:this.startingY,a:this.startingAngle};i.strokeWeight(this.strokeWidth),i.clear(),i.background(r[9]),i.beginShape(),i.vertex(o.x,o.y);for(let t=0;t{r.setup=()=>{r.createCanvas(this.width,this.height),r.noLoop(),r.noFill(),r.stroke(255),this.sketch=r,this.render(this.sketch)}};new this.$p5(e,"canvas")}},m={class:"select-none bg-gradient-to-b from-green-800 to-gray-800"},x={class:"m-8 grid place-items-center"},b={class:"font-mono text-white"},f=n("div",{id:"canvas-container",class:"mb-2 h-96 border-2 border-white"},[n("div",{id:"canvas"})],-1),v={class:"my-2 md:w-full"},k={class:"grid-rows-auto my-2 grid grid-cols-2 gap-4 border-2 border-white p-2 md:grid-rows-1"},_={class:"flex flex-col"},y={for:"distanceInput",class:"text-right"},w={class:"flex flex-col"},A={for:"strokeInput",class:"text-right"},I={class:"flex flex-col"},C={for:"startingXInput",class:"text-right"},V={class:"flex flex-col"},W={for:"startingYInput",class:"text-right"},X={class:"flex flex-col"},Y={for:"startingAngleInput",class:"text-right"};function D(i,e,r,o,t,l){return u(),h("div",m,[n("div",x,[n("div",b,[f,n("div",v,[d(n("textarea",{readonly:"","onUpdate:modelValue":e[0]||(e[0]=s=>t.sequence=s),class:"block h-24 w-full border-2 border-white bg-black p-2 text-white placeholder:italic placeholder:text-slate-400 focus:border-2 focus:border-yellow-500 focus:outline-none sm:text-sm",placeholder:"Enter a sequence of numbers...",type:"text"},null,512),[[c,t.sequence]])]),n("div",k,[n("div",_,[n("label",y,"Segment Length ["+a(t.distance)+"]",1),d(n("input",{id:"distanceInput","onUpdate:modelValue":e[1]||(e[1]=s=>t.distance=s),onChange:e[2]||(e[2]=s=>l.render(t.sketch)),type:"range",min:"1",max:"25",class:"accent-black"},null,544),[[c,t.distance,void 0,{number:!0}]])]),n("div",w,[n("label",A,"Stroke Width ["+a(t.strokeWidth)+"]",1),d(n("input",{id:"strokeInput","onUpdate:modelValue":e[3]||(e[3]=s=>t.strokeWidth=s),onChange:e[4]||(e[4]=s=>l.render(t.sketch)),type:"range",min:"1",max:"10",class:"accent-black"},null,544),[[c,t.strokeWidth,void 0,{number:!0}]])]),n("div",I,[n("label",C,"X Position ["+a(t.startingX)+"]",1),d(n("input",{id:"startingXInput","onUpdate:modelValue":e[5]||(e[5]=s=>t.startingX=s),onChange:e[6]||(e[6]=s=>l.render(t.sketch)),type:"range",min:"0",max:"500",class:"accent-black"},null,544),[[c,t.startingX,void 0,{number:!0}]])]),n("div",V,[n("label",W,"Y Position ["+a(t.startingY)+"]",1),d(n("input",{id:"startingYInput","onUpdate:modelValue":e[7]||(e[7]=s=>t.startingY=s),onChange:e[8]||(e[8]=s=>l.render(t.sketch)),type:"range",min:"0",max:"500",class:"accent-black"},null,544),[[c,t.startingY,void 0,{number:!0}]])]),n("div",X,[n("label",Y,"Angle ["+a(t.startingAngle)+"]",1),d(n("input",{id:"startingAngleInput","onUpdate:modelValue":e[9]||(e[9]=s=>t.startingAngle=s),onChange:e[10]||(e[10]=s=>l.render(t.sketch)),type:"range",min:"-180",max:"180",class:"accent-black"},null,544),[[c,t.startingAngle,void 0,{number:!0}]])])])])])])}const F=g(p,[["render",D]]);export{F as default}; diff --git a/_nuxt/BKNGoZSq.js b/_nuxt/BKNGoZSq.js deleted file mode 100644 index 8b09057b..00000000 --- a/_nuxt/BKNGoZSq.js +++ /dev/null @@ -1 +0,0 @@ -import{d as i,H as c,v as p,o as s,c as n,a as u,a7 as t}from"./D6y6W-Zj.js";const f=["id"],l=["href"],k=i({__name:"ProseH6",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=p(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h6)});return(e,m)=>(s(),n("h6",{id:e.id},[e.id&&u(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/BKnB9ShE.js b/_nuxt/BKnB9ShE.js new file mode 100644 index 00000000..0b39f521 --- /dev/null +++ b/_nuxt/BKnB9ShE.js @@ -0,0 +1 @@ +import{l as o,o as r,c as t,a7 as n}from"./YC8jgtvV.js";const s={};function c(e,a){return r(),t("strong",null,[n(e.$slots,"default")])}const f=o(s,[["render",c]]);export{f as default}; diff --git a/_nuxt/BLy52rwp.js b/_nuxt/BLy52rwp.js deleted file mode 100644 index df3d184e..00000000 --- a/_nuxt/BLy52rwp.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as f}from"./CNTXZiWI.js";import{d as l,p as s,I as d,K as c}from"./D6y6W-Zj.js";import"./C-v3KzvZ.js";import"./DXU4rfre.js";import"./DvDH6DOc.js";const _=l({name:"ContentRenderer",props:{value:{type:Object,required:!1,default:()=>({})},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"}},setup(t){s(()=>t.excerpt,n=>{var e,a,i;n&&!((e=t.value)!=null&&e.excerpt)&&(console.warn(`No excerpt found for document content/${(a=t==null?void 0:t.value)==null?void 0:a._path}.${(i=t==null?void 0:t.value)==null?void 0:i._extension}!`),console.warn("Make sure to use in your content if you want to use excerpt feature."))},{immediate:!0})},render(t){var u,o;const n=d(),{value:e,excerpt:a,tag:i}=t,r=a?e==null?void 0:e.excerpt:e==null?void 0:e.body;return!((u=r==null?void 0:r.children)!=null&&u.length)&&(n!=null&&n.empty)?n.empty({value:e,excerpt:a,tag:i,...this.$attrs}):n!=null&&n.default?n.default({value:e,excerpt:a,tag:i,...this.$attrs}):(r==null?void 0:r.type)==="root"&&((o=r==null?void 0:r.children)!=null&&o.length)?c(f,{value:e,excerpt:a,tag:i,...this.$attrs}):c("pre",null,JSON.stringify({message:"You should use slots with ",value:e,excerpt:a,tag:i},null,2))}});export{_ as default}; diff --git a/_nuxt/BQ_EhnmX.js b/_nuxt/BQ_EhnmX.js deleted file mode 100644 index a82c17ff..00000000 --- a/_nuxt/BQ_EhnmX.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as t,a7 as s}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),t("td",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/BW3Uyh46.js b/_nuxt/BW3Uyh46.js new file mode 100644 index 00000000..964f4457 --- /dev/null +++ b/_nuxt/BW3Uyh46.js @@ -0,0 +1 @@ +import s from"./CvqFk8MA.js";import{d as o,I as u,k as f,$ as m}from"./YC8jgtvV.js";import"./Dnd51l0P.js";const d=o({name:"Markdown",extends:s,setup(t){const{parent:e}=m(),{between:n,default:a}=u(),r=f(()=>typeof t.unwrap=="string"?t.unwrap.split(" "):["*"]);return{fallbackSlot:a,tags:r,between:n,parent:e}}});export{d as default}; diff --git a/_nuxt/BY1K6PIA.js b/_nuxt/BY1K6PIA.js new file mode 100644 index 00000000..1ccda56f --- /dev/null +++ b/_nuxt/BY1K6PIA.js @@ -0,0 +1 @@ +import{l as o,o as r,c as t,a7 as s}from"./YC8jgtvV.js";const c={};function n(e,a){return r(),t("tbody",null,[s(e.$slots,"default")])}const d=o(c,[["render",n]]);export{d as default}; diff --git a/_nuxt/B_oFiJGZ.js b/_nuxt/B_oFiJGZ.js deleted file mode 100644 index 35e44809..00000000 --- a/_nuxt/B_oFiJGZ.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as s,a7 as t}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),s("p",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/CzWl7KmD.js b/_nuxt/Beu9PnWL.js similarity index 61% rename from _nuxt/CzWl7KmD.js rename to _nuxt/Beu9PnWL.js index fa8eac64..ef2782aa 100644 --- a/_nuxt/CzWl7KmD.js +++ b/_nuxt/Beu9PnWL.js @@ -1,2 +1,2 @@ -const __vite__fileDeps=["./U3g5PXV_.js","./D6y6W-Zj.js","./ElOT_Ul4.js","./DvDH6DOc.js","./DXU4rfre.js","./C-v3KzvZ.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); -import{u as m}from"./T8qFVnUA.js";import{H as v,L as l,M as d,C as g,N as y,d as h,O as _,v as w,I as C,K as p,i as N}from"./D6y6W-Zj.js";import{h as f}from"./DvDH6DOc.js";import{q as P,w as c,e as $,s as x,j as E,u as T}from"./ElOT_Ul4.js";import{u as j}from"./DXU4rfre.js";const S=async t=>{const{content:e}=v().public;typeof(t==null?void 0:t.params)!="function"&&(t=P(t));const n=t.params(),o=e.experimental.stripQueryParameters?c(`/navigation/${`${f(n)}.${e.integrity}`}/${$(n)}.json`):c(`/navigation/${f(n)}.${e.integrity}.json`);if(x())return(await l(()=>import("./U3g5PXV_.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url).then(i=>i.generateNavigation))(n);const a=await $fetch(o,{method:"GET",responseType:"json",params:e.experimental.stripQueryParameters?void 0:{_params:E(n),previewToken:j().getPreviewToken()}});if(typeof a=="string"&&a.startsWith(""))throw new Error("Not found");return a},b="$s";function D(...t){const e=typeof t[t.length-1]=="string"?t.pop():void 0;typeof t[0]!="string"&&t.unshift(e);const[n,o]=t;if(!n||typeof n!="string")throw new TypeError("[nuxt] [useState] key must be a string: "+n);if(o!==void 0&&typeof o!="function")throw new Error("[nuxt] [useState] init must be a function: "+o);const a=b+n,r=y(),i=d(r.payload.state,a);if(i.value===void 0&&o){const s=o();if(g(s))return r.payload.state[a]=s,s;i.value=s}return i}const R=h({name:"ContentNavigation",props:{query:{type:Object,required:!1,default:void 0}},async setup(t){const{query:e}=_(t),n=w(()=>{var a;return typeof((a=e.value)==null?void 0:a.params)=="function"?e.value.params():e.value});if(!n.value&&D("dd-navigation").value){const{navigation:a}=T();return{navigation:a}}const{data:o}=await m(`content-navigation-${f(n.value)}`,()=>S(n.value));return{navigation:o}},render(t){const e=C(),{navigation:n}=t,o=i=>p(N,{to:i._path},()=>i.title),a=(i,s)=>p("ul",s?{"data-level":s}:null,i.map(u=>u.children?p("li",null,[o(u),a(u.children,s+1)]):p("li",null,o(u)))),r=i=>a(i,0);return e!=null&&e.default?e.default({navigation:n,...this.$attrs}):r(n)}}),Q=R;export{Q as default}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./B4Ww-T0F.js","./YC8jgtvV.js","./NquB2IUV.js","./DvDH6DOc.js","./JthqPOXk.js","./C-v3KzvZ.js"])))=>i.map(i=>d[i]); +import{u as m}from"./DjmxGRUG.js";import{H as v,L as l,M as d,D as g,N as y,d as h,O as _,k as w,I as C,K as p,_ as N}from"./YC8jgtvV.js";import{h as f}from"./DvDH6DOc.js";import{q as P,w as c,e as $,s as x,j as E,u as T}from"./NquB2IUV.js";import{u as j}from"./JthqPOXk.js";const D=async t=>{const{content:e}=v().public;typeof(t==null?void 0:t.params)!="function"&&(t=P(t));const n=t.params(),o=e.experimental.stripQueryParameters?c(`/navigation/${`${f(n)}.${e.integrity}`}/${$(n)}.json`):c(`/navigation/${f(n)}.${e.integrity}.json`);if(x())return(await l(()=>import("./B4Ww-T0F.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url).then(i=>i.generateNavigation))(n);const a=await $fetch(o,{method:"GET",responseType:"json",params:e.experimental.stripQueryParameters?void 0:{_params:E(n),previewToken:j().getPreviewToken()}});if(typeof a=="string"&&a.startsWith(""))throw new Error("Not found");return a},S="$s";function b(...t){const e=typeof t[t.length-1]=="string"?t.pop():void 0;typeof t[0]!="string"&&t.unshift(e);const[n,o]=t;if(!n||typeof n!="string")throw new TypeError("[nuxt] [useState] key must be a string: "+n);if(o!==void 0&&typeof o!="function")throw new Error("[nuxt] [useState] init must be a function: "+o);const a=S+n,r=y(),i=d(r.payload.state,a);if(i.value===void 0&&o){const s=o();if(g(s))return r.payload.state[a]=s,s;i.value=s}return i}const R=h({name:"ContentNavigation",props:{query:{type:Object,required:!1,default:void 0}},async setup(t){const{query:e}=_(t),n=w(()=>{var a;return typeof((a=e.value)==null?void 0:a.params)=="function"?e.value.params():e.value});if(!n.value&&b("dd-navigation").value){const{navigation:a}=T();return{navigation:a}}const{data:o}=await m(`content-navigation-${f(n.value)}`,()=>D(n.value));return{navigation:o}},render(t){const e=C(),{navigation:n}=t,o=i=>p(N,{to:i._path},()=>i.title),a=(i,s)=>p("ul",s?{"data-level":s}:null,i.map(u=>u.children?p("li",null,[o(u),a(u.children,s+1)]):p("li",null,o(u)))),r=i=>a(i,0);return e!=null&&e.default?e.default({navigation:n,...this.$attrs}):r(n)}}),Q=R;export{Q as default}; diff --git a/_nuxt/CjCPfpaE.js b/_nuxt/BiZieXJo.js similarity index 86% rename from _nuxt/CjCPfpaE.js rename to _nuxt/BiZieXJo.js index 00d48d53..9bb1d07f 100644 --- a/_nuxt/CjCPfpaE.js +++ b/_nuxt/BiZieXJo.js @@ -1 +1 @@ -import{_ as s,c as n,b as t,a7 as a,f as l,g as c,i as r,o as i}from"./D6y6W-Zj.js";const d={},_={class:"container mx-auto my-12 h-screen bg-background font-display lg:my-16"},h={class:"flex flex-col border-2 bg-white"},u={class:"absolute left-2 top-2"},f=t("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",class:"mr-2 h-6 w-6"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15M12 9l-3 3m0 0l3 3m-3-3h12.75"})],-1),m=t("span",null,"Back",-1);function p(e,x){const o=r;return i(),n("main",null,[t("div",_,[t("div",h,[a(e.$slots,"default")])]),t("div",u,[l(o,{as:"button",to:"/playground",class:"inline-flex items-center rounded px-4 py-2 font-bold text-white hover:text-cyan"},{default:c(()=>[f,m]),_:1})])])}const w=s(d,[["render",p]]);export{w as default}; +import{l as s,c as n,b as t,a7 as a,i as l,g as c,_ as r,o as i}from"./YC8jgtvV.js";const d={},_={class:"container mx-auto my-12 h-screen bg-background font-display lg:my-16"},h={class:"flex flex-col border-2 bg-white"},u={class:"absolute left-2 top-2"},f=t("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",class:"mr-2 h-6 w-6"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15M12 9l-3 3m0 0l3 3m-3-3h12.75"})],-1),m=t("span",null,"Back",-1);function p(e,x){const o=r;return i(),n("main",null,[t("div",_,[t("div",h,[a(e.$slots,"default")])]),t("div",u,[l(o,{as:"button",to:"/playground",class:"inline-flex items-center rounded px-4 py-2 font-bold text-white hover:text-cyan"},{default:c(()=>[f,m]),_:1})])])}const w=s(d,[["render",p]]);export{w as default}; diff --git a/_nuxt/oGJ4KIAb.js b/_nuxt/BknKiCrO.js similarity index 97% rename from _nuxt/oGJ4KIAb.js rename to _nuxt/BknKiCrO.js index 4e8757eb..62d70e71 100644 --- a/_nuxt/oGJ4KIAb.js +++ b/_nuxt/BknKiCrO.js @@ -1 +1 @@ -import{_ as d,c as h,o as c,j as l}from"./D6y6W-Zj.js";const a=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"];class o{constructor(){this.parent=void 0,this.children=[],this.orientation="h",this.x=0,this.y=0,this.w=500,this.h=500}add(i){i.parent=this,this.children.push(i),this.children.forEach((n,r)=>{if(this.orientation==="h"){const e=this.w/this.children.length,t=this.x+e*r;n.x=t,n.y=this.y,n.w=e,n.h=this.h}else if(this.orientation==="v"){const e=this.h/this.children.length,t=this.y+e*r;n.x=this.x,n.y=t,n.w=this.w,n.h=e}})}render(i){i.rect(this.x,this.y,this.w,this.h),this.children.forEach((n,r)=>{i.fill(a[r%9]),n.render(i)})}traverseForPoint(i,n){if(this.children.length===0)return this;for(let r=0;r=e.x&&i<=e.x+e.w&&n>=e.y&&n<=e.y+e.h)return e.children.length===0?e:e.traverseForPoint(i,n)}}}const f={data(){return{}},mounted(){const s=i=>{const e=new o;for(let t=0;t<5;t++)e.add(new o);e.children[0].orientation="v";for(let t=0;t<3;t++)e.children[0].add(new o);e.children[0].children[2].orientation="v";for(let t=0;t<4;t++)e.children[0].children[2].add(new o);e.children[1].orientation="v";for(let t=0;t<3;t++)e.children[1].add(new o);for(let t=0;t<9;t++)e.children[1].children[0].add(new o);e.children[3].orientation="v";for(let t=0;t<3;t++)e.children[3].add(new o);e.children[3].children[2].orientation="v";for(let t=0;t<9;t++)e.children[3].children[2].add(new o);i.setup=()=>{i.createCanvas(500,500),i.noLoop(),i.stroke(255),i.strokeWeight(2),e.render(i)},i.mouseClicked=()=>{const t=e.traverseForPoint(i.mouseX,i.mouseY);t&&(t.add(new o),t.add(new o),t.render(i))}};new this.$p5(s,"canvas")}},v={class:"select-none bg-gradient-to-b from-green-800 to-gray-800"},w=l('
m-ary tree based tiling
',1),u=[w];function m(s,i,n,r,e,t){return c(),h("div",v,u)}const _=d(f,[["render",m]]);export{_ as default}; +import{l as d,c as h,o as c,m as l}from"./YC8jgtvV.js";const a=["#FFBA08","#FAA307","#F48C06","#E85D04","#DC2F02","#D00000","#9D0208","#6A040F","#370617","#03071E"];class o{constructor(){this.parent=void 0,this.children=[],this.orientation="h",this.x=0,this.y=0,this.w=500,this.h=500}add(i){i.parent=this,this.children.push(i),this.children.forEach((n,r)=>{if(this.orientation==="h"){const e=this.w/this.children.length,t=this.x+e*r;n.x=t,n.y=this.y,n.w=e,n.h=this.h}else if(this.orientation==="v"){const e=this.h/this.children.length,t=this.y+e*r;n.x=this.x,n.y=t,n.w=this.w,n.h=e}})}render(i){i.rect(this.x,this.y,this.w,this.h),this.children.forEach((n,r)=>{i.fill(a[r%9]),n.render(i)})}traverseForPoint(i,n){if(this.children.length===0)return this;for(let r=0;r=e.x&&i<=e.x+e.w&&n>=e.y&&n<=e.y+e.h)return e.children.length===0?e:e.traverseForPoint(i,n)}}}const f={data(){return{}},mounted(){const s=i=>{const e=new o;for(let t=0;t<5;t++)e.add(new o);e.children[0].orientation="v";for(let t=0;t<3;t++)e.children[0].add(new o);e.children[0].children[2].orientation="v";for(let t=0;t<4;t++)e.children[0].children[2].add(new o);e.children[1].orientation="v";for(let t=0;t<3;t++)e.children[1].add(new o);for(let t=0;t<9;t++)e.children[1].children[0].add(new o);e.children[3].orientation="v";for(let t=0;t<3;t++)e.children[3].add(new o);e.children[3].children[2].orientation="v";for(let t=0;t<9;t++)e.children[3].children[2].add(new o);i.setup=()=>{i.createCanvas(500,500),i.noLoop(),i.stroke(255),i.strokeWeight(2),e.render(i)},i.mouseClicked=()=>{const t=e.traverseForPoint(i.mouseX,i.mouseY);t&&(t.add(new o),t.add(new o),t.render(i))}};new this.$p5(s,"canvas")}},v={class:"select-none bg-gradient-to-b from-green-800 to-gray-800"},w=l('
m-ary tree based tiling
',1),u=[w];function m(s,i,n,r,e,t){return c(),h("div",v,u)}const _=d(f,[["render",m]]);export{_ as default}; diff --git a/_nuxt/BmD66l6I.js b/_nuxt/BmD66l6I.js new file mode 100644 index 00000000..74f18c79 --- /dev/null +++ b/_nuxt/BmD66l6I.js @@ -0,0 +1 @@ +import{l as o,o as r,c as t,a7 as a}from"./YC8jgtvV.js";const s={};function c(e,n){return r(),t("thead",null,[a(e.$slots,"default")])}const d=o(s,[["render",c]]);export{d as default}; diff --git a/_nuxt/C8bARUYD.js b/_nuxt/Bv5xXi_H.js similarity index 97% rename from _nuxt/C8bARUYD.js rename to _nuxt/Bv5xXi_H.js index b8cc7529..dfa87dac 100644 --- a/_nuxt/C8bARUYD.js +++ b/_nuxt/Bv5xXi_H.js @@ -1 +1 @@ -import{_ as w,c as r,b as s,n as x,e as m,F as h,r as _,h as f,o as l,t as p}from"./D6y6W-Zj.js";const v={data(){return{ix:0,a:[],b:[],timeline:[]}},computed:{step(){return this.timeline.length>0?this.timeline[this.ix]:{}},done(){return this.timeline.length-1===this.ix},started(){return this.timeline.length>0}},mounted(){this.generateRandomMatrices()},created(){typeof window>"u"||window.addEventListener("keydown",o=>{o.key===" "?this.incStep():o.key==="Escape"&&(this.ix=0)})},methods:{randomMatrix(o,n){const d=[];for(let b=0;bMath.round(Math.random()*10)));return d},generateRandomMatrices(){this.a=this.randomMatrix(3,4),this.b=this.randomMatrix(4,3),this.timeline=[],this.ix=0},matmul(o,n){this.timeline=[];const d=[];for(let c=0;c{n[e].forEach((i,t)=>{const g=[];o[e].forEach((a,u)=>{g.push(`${o[t][u]}*${n[u][e]}`),d[t][e]+=o[t][u]*n[u][e],b[e*o.length+t]=`${g.join(" + ")} = ${d[t][e]}`;const y=JSON.parse(JSON.stringify(d));this.timeline.push({row_a:t,col_a:u,row_b:u,col_b:e,row_c:t,col_c:e,cur_a:o[t][u],cur_b:n[u][e],cur_c:d[t][e],c:y,all_steps:b.slice()})})})})},incStep(){this.ix!==this.timeline.length-1&&(this.ix+=1)},decStep(){this.ix>0&&(this.ix-=1)}}},k={class:"m-4 space-y-4"},M=s("div",{class:"m-2 w-4/5"},[f(" Walk through the steps of matrix multiplication with randomly generated matrices. Press the "),s("em",null,"Spacebar"),f(" or click the "),s("em",{class:"bg-blue-200 text-blue-800"},"buttons"),f(" to iterate through the steps. ")],-1),S={class:"m-2 inline-flex space-x-2"},C=["disabled"],B=s("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[s("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M11 19l-7-7 7-7m8 14l-7-7 7-7"})],-1),E=[B],A=["disabled"],N=s("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[s("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 5l7 7-7 7M5 5l7 7-7 7"})],-1),R=[N],V={class:"flex flex-wrap"},D={class:"w-34 m-2 border border-gray-400 sm:w-min"},F=s("div",{class:"bg-gray-200 p-4 text-center font-bold"},"Matrix A",-1),J={class:"flex items-center justify-center p-4"},L={class:"text-center"},O={class:"w-34 m-2 border border-gray-400 sm:w-min"},z=s("div",{class:"bg-gray-200 p-4 text-center font-bold"},"Matrix B",-1),P={class:"flex items-center justify-center p-4"},T={class:"text-center"},W=s("div",{class:"bg-gray-200 p-4 text-center font-bold"},"Result",-1),q={class:"flex items-center justify-center p-4"},G={class:"text-center"},H={key:1,class:"m-2 w-72 border border-gray-400 bg-gray-100 p-2"},I=s("div",{class:"text-center font-bold"},"Steps",-1),K={class:"font-mono"},Q={key:0,class:"italic text-green-600"};function U(o,n,d,b,c,e){return l(),r("div",k,[M,s("div",S,[s("button",{class:x(["bg-blue-200 px-4 py-2 font-bold text-blue-800 hover:bg-blue-800 hover:text-blue-200",{"cursor-not-allowed opacity-25":!e.started}]),disabled:!e.started,onClick:n[0]||(n[0]=(...i)=>e.decStep&&e.decStep(...i))},E,10,C),e.done?m("",!0):(l(),r("button",{key:0,class:"bg-blue-200 px-4 py-2 font-bold text-blue-800 hover:bg-blue-800 hover:text-blue-200",onClick:n[1]||(n[1]=i=>e.matmul(c.a,c.b))}," Start ")),e.done?(l(),r("button",{key:1,class:"bg-orange-200 px-4 py-2 font-bold text-orange-800 hover:bg-blue-800 hover:text-blue-200",onClick:n[2]||(n[2]=(...i)=>e.generateRandomMatrices&&e.generateRandomMatrices(...i))}," Again! ")):m("",!0),s("button",{class:x(["bg-blue-200 px-4 py-2 font-bold text-blue-800 hover:bg-blue-800 hover:text-blue-200",{"cursor-not-allowed opacity-25":!e.started}]),disabled:!e.started,onClick:n[3]||(n[3]=(...i)=>e.incStep&&e.incStep(...i))},R,10,A)]),s("div",V,[s("div",D,[F,s("div",J,[s("table",L,[(l(!0),r(h,null,_(c.a,(i,t)=>(l(),r("tr",{key:t},[(l(!0),r(h,null,_(c.a[t],(g,a)=>(l(),r("td",{key:a,class:x([{"text-green-600":e.step&&t==e.step.row_a&&a==e.step.col_a,"bg-orange-100":e.step&&t==e.step.row_a},"p-2"])},p(c.a[t][a]),3))),128))]))),128))])])]),s("div",O,[z,s("div",P,[s("table",T,[(l(!0),r(h,null,_(c.b,(i,t)=>(l(),r("tr",{key:t},[(l(!0),r(h,null,_(c.b[t],(g,a)=>(l(),r("td",{key:a,class:x([{"text-green-600":e.step&&t==e.step.row_b&&a==e.step.col_b,"bg-orange-100":e.step&&a==e.step.col_b},"p-2"])},p(c.b[t][a]),3))),128))]))),128))])])]),e.started?(l(),r("div",{key:0,class:x(["m-2 w-72 border border-gray-400 sm:w-min",{"bg-green-200":e.done}])},[W,s("div",q,[s("table",G,[(l(!0),r(h,null,_(e.step.c,(i,t)=>(l(),r("tr",{key:t},[(l(!0),r(h,null,_(e.step.c[t],(g,a)=>(l(),r("td",{key:a,class:"p-2"},p(e.step.c[t][a]),1))),128))]))),128))])])],2)):m("",!0),e.started?(l(),r("div",H,[I,s("div",K,[(l(!0),r(h,null,_(e.step.all_steps,(i,t)=>(l(),r("div",{key:t},p(i),1))),128)),e.done?(l(),r("div",Q,"Done!")):m("",!0)])])):m("",!0)]),m("",!0)])}const Y=w(v,[["render",U]]);export{Y as default}; +import{l as w,c as r,b as s,n as x,e as m,F as h,r as _,h as f,o as l,t as p}from"./YC8jgtvV.js";const v={data(){return{ix:0,a:[],b:[],timeline:[]}},computed:{step(){return this.timeline.length>0?this.timeline[this.ix]:{}},done(){return this.timeline.length-1===this.ix},started(){return this.timeline.length>0}},mounted(){this.generateRandomMatrices()},created(){typeof window>"u"||window.addEventListener("keydown",o=>{o.key===" "?this.incStep():o.key==="Escape"&&(this.ix=0)})},methods:{randomMatrix(o,n){const d=[];for(let b=0;bMath.round(Math.random()*10)));return d},generateRandomMatrices(){this.a=this.randomMatrix(3,4),this.b=this.randomMatrix(4,3),this.timeline=[],this.ix=0},matmul(o,n){this.timeline=[];const d=[];for(let c=0;c{n[e].forEach((i,t)=>{const g=[];o[e].forEach((a,u)=>{g.push(`${o[t][u]}*${n[u][e]}`),d[t][e]+=o[t][u]*n[u][e],b[e*o.length+t]=`${g.join(" + ")} = ${d[t][e]}`;const y=JSON.parse(JSON.stringify(d));this.timeline.push({row_a:t,col_a:u,row_b:u,col_b:e,row_c:t,col_c:e,cur_a:o[t][u],cur_b:n[u][e],cur_c:d[t][e],c:y,all_steps:b.slice()})})})})},incStep(){this.ix!==this.timeline.length-1&&(this.ix+=1)},decStep(){this.ix>0&&(this.ix-=1)}}},k={class:"m-4 space-y-4"},M=s("div",{class:"m-2 w-4/5"},[f(" Walk through the steps of matrix multiplication with randomly generated matrices. Press the "),s("em",null,"Spacebar"),f(" or click the "),s("em",{class:"bg-blue-200 text-blue-800"},"buttons"),f(" to iterate through the steps. ")],-1),S={class:"m-2 inline-flex space-x-2"},C=["disabled"],B=s("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[s("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M11 19l-7-7 7-7m8 14l-7-7 7-7"})],-1),E=[B],A=["disabled"],N=s("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},[s("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M13 5l7 7-7 7M5 5l7 7-7 7"})],-1),R=[N],V={class:"flex flex-wrap"},D={class:"w-34 m-2 border border-gray-400 sm:w-min"},F=s("div",{class:"bg-gray-200 p-4 text-center font-bold"},"Matrix A",-1),J={class:"flex items-center justify-center p-4"},L={class:"text-center"},O={class:"w-34 m-2 border border-gray-400 sm:w-min"},z=s("div",{class:"bg-gray-200 p-4 text-center font-bold"},"Matrix B",-1),P={class:"flex items-center justify-center p-4"},T={class:"text-center"},W=s("div",{class:"bg-gray-200 p-4 text-center font-bold"},"Result",-1),q={class:"flex items-center justify-center p-4"},G={class:"text-center"},H={key:1,class:"m-2 w-72 border border-gray-400 bg-gray-100 p-2"},I=s("div",{class:"text-center font-bold"},"Steps",-1),K={class:"font-mono"},Q={key:0,class:"italic text-green-600"};function U(o,n,d,b,c,e){return l(),r("div",k,[M,s("div",S,[s("button",{class:x(["bg-blue-200 px-4 py-2 font-bold text-blue-800 hover:bg-blue-800 hover:text-blue-200",{"cursor-not-allowed opacity-25":!e.started}]),disabled:!e.started,onClick:n[0]||(n[0]=(...i)=>e.decStep&&e.decStep(...i))},E,10,C),e.done?m("",!0):(l(),r("button",{key:0,class:"bg-blue-200 px-4 py-2 font-bold text-blue-800 hover:bg-blue-800 hover:text-blue-200",onClick:n[1]||(n[1]=i=>e.matmul(c.a,c.b))}," Start ")),e.done?(l(),r("button",{key:1,class:"bg-orange-200 px-4 py-2 font-bold text-orange-800 hover:bg-blue-800 hover:text-blue-200",onClick:n[2]||(n[2]=(...i)=>e.generateRandomMatrices&&e.generateRandomMatrices(...i))}," Again! ")):m("",!0),s("button",{class:x(["bg-blue-200 px-4 py-2 font-bold text-blue-800 hover:bg-blue-800 hover:text-blue-200",{"cursor-not-allowed opacity-25":!e.started}]),disabled:!e.started,onClick:n[3]||(n[3]=(...i)=>e.incStep&&e.incStep(...i))},R,10,A)]),s("div",V,[s("div",D,[F,s("div",J,[s("table",L,[(l(!0),r(h,null,_(c.a,(i,t)=>(l(),r("tr",{key:t},[(l(!0),r(h,null,_(c.a[t],(g,a)=>(l(),r("td",{key:a,class:x([{"text-green-600":e.step&&t==e.step.row_a&&a==e.step.col_a,"bg-orange-100":e.step&&t==e.step.row_a},"p-2"])},p(c.a[t][a]),3))),128))]))),128))])])]),s("div",O,[z,s("div",P,[s("table",T,[(l(!0),r(h,null,_(c.b,(i,t)=>(l(),r("tr",{key:t},[(l(!0),r(h,null,_(c.b[t],(g,a)=>(l(),r("td",{key:a,class:x([{"text-green-600":e.step&&t==e.step.row_b&&a==e.step.col_b,"bg-orange-100":e.step&&a==e.step.col_b},"p-2"])},p(c.b[t][a]),3))),128))]))),128))])])]),e.started?(l(),r("div",{key:0,class:x(["m-2 w-72 border border-gray-400 sm:w-min",{"bg-green-200":e.done}])},[W,s("div",q,[s("table",G,[(l(!0),r(h,null,_(e.step.c,(i,t)=>(l(),r("tr",{key:t},[(l(!0),r(h,null,_(e.step.c[t],(g,a)=>(l(),r("td",{key:a,class:"p-2"},p(e.step.c[t][a]),1))),128))]))),128))])])],2)):m("",!0),e.started?(l(),r("div",H,[I,s("div",K,[(l(!0),r(h,null,_(e.step.all_steps,(i,t)=>(l(),r("div",{key:t},p(i),1))),128)),e.done?(l(),r("div",Q,"Done!")):m("",!0)])])):m("",!0)]),m("",!0)])}const Y=w(v,[["render",U]]);export{Y as default}; diff --git a/_nuxt/BzUOsEDD.js b/_nuxt/BzUOsEDD.js deleted file mode 100644 index 53c49d09..00000000 --- a/_nuxt/BzUOsEDD.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as t,a7 as n}from"./D6y6W-Zj.js";const s={};function c(e,a){return r(),t("strong",null,[n(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; diff --git a/_nuxt/TpgFGTwW.js b/_nuxt/Bzgpm7XF.js similarity index 67% rename from _nuxt/TpgFGTwW.js rename to _nuxt/Bzgpm7XF.js index 9008948a..abaf5427 100644 --- a/_nuxt/TpgFGTwW.js +++ b/_nuxt/Bzgpm7XF.js @@ -1 +1 @@ -import{_ as s,o as n,c,b as e,f as t,a7 as l,a9 as d}from"./D6y6W-Zj.js";const i={},f={class:"pin-b w-full p-4 text-xs font-bold text-white"},h=e("div",{class:"flex justify-center space-x-2"},[e("a",{class:"hover:cursor-pointer hover:text-blue-200",href:"https://github.com/cmpadden/cmpadden.github.io"}," © Colton Padden"),e("span",null,"•"),e("a",{class:"hover:cursor-pointer hover:text-blue-200",href:"/sitemap.xml"},"Sitemap"),e("span",null,"•"),e("a",{class:"hover:cursor-pointer hover:text-blue-200",href:"/atom"},"RSS")],-1),u=[h];function p(o,r){return n(),c("footer",f,u)}const m=s(i,[["render",p]]),x={},b={class:"bg-orange-500"},v={class:"rounded-3xl border-[10px] border-orange-500"},g={class:"flex min-h-screen flex-col rounded-3xl bg-background font-display"},$={class:"flex-1"};function S(o,r){const a=d,_=m;return n(),c("div",b,[e("div",v,[e("main",g,[t(a),e("main",$,[l(o.$slots,"default")]),t(_)])])])}const B=s(x,[["render",S]]);export{B as default}; +import{l as s,o as n,c,b as e,i as t,a7 as _,aa as d}from"./YC8jgtvV.js";const i={},f={class:"pin-b w-full p-4 text-xs font-bold text-white"},h=e("div",{class:"flex justify-center space-x-2"},[e("a",{class:"hover:cursor-pointer hover:text-blue-200",href:"https://github.com/cmpadden/cmpadden.github.io"}," © Colton Padden"),e("span",null,"•"),e("a",{class:"hover:cursor-pointer hover:text-blue-200",href:"/sitemap.xml"},"Sitemap"),e("span",null,"•"),e("a",{class:"hover:cursor-pointer hover:text-blue-200",href:"/atom"},"RSS")],-1),u=[h];function p(o,r){return n(),c("footer",f,u)}const m=s(i,[["render",p]]),x={},b={class:"bg-orange-500"},v={class:"rounded-3xl border-[10px] border-orange-500"},g={class:"flex min-h-screen flex-col rounded-3xl bg-background font-display"},$={class:"flex-1"};function S(o,r){const a=d,l=m;return n(),c("div",b,[e("div",v,[e("main",g,[t(a),e("main",$,[_(o.$slots,"default")]),t(l)])])])}const B=s(x,[["render",S]]);export{B as default}; diff --git a/_nuxt/C18jNCO7.js b/_nuxt/C18jNCO7.js new file mode 100644 index 00000000..93ae3a4b --- /dev/null +++ b/_nuxt/C18jNCO7.js @@ -0,0 +1 @@ +import{d as p,H as f,k as i,o as t,c as s,a as u,a7 as n}from"./YC8jgtvV.js";const l=["id"],d=["href"],_=p({__name:"ProseH3",props:{id:{}},setup(r){const a=r,{headings:o}=f().public.mdc,c=i(()=>{var e;return a.id&&(typeof(o==null?void 0:o.anchorLinks)=="boolean"&&(o==null?void 0:o.anchorLinks)===!0||typeof(o==null?void 0:o.anchorLinks)=="object"&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h3))});return(e,k)=>(t(),s("h3",{id:e.id},[e.id&&u(c)?(t(),s("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,d)):n(e.$slots,"default",{key:1})],8,l))}});export{_ as default}; diff --git a/_nuxt/C1UWh-7Q.js b/_nuxt/C1UWh-7Q.js deleted file mode 100644 index 35028a06..00000000 --- a/_nuxt/C1UWh-7Q.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as t,a7 as s}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),t("tbody",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/C1gyBLca.js b/_nuxt/C1gyBLca.js new file mode 100644 index 00000000..d8b3dadd --- /dev/null +++ b/_nuxt/C1gyBLca.js @@ -0,0 +1 @@ +import{_ as m}from"./V6DC4L2r.js";import"./YC8jgtvV.js";export{m as default}; diff --git a/_nuxt/C97JLsMV.js b/_nuxt/C97JLsMV.js deleted file mode 100644 index 576092e0..00000000 --- a/_nuxt/C97JLsMV.js +++ /dev/null @@ -1 +0,0 @@ -import{d as a,o as n,D as o,g as s,a7 as f,i as u}from"./D6y6W-Zj.js";const i=a({__name:"ProseA",props:{href:{type:String,default:""},target:{type:String,default:void 0,required:!1}},setup(e){return(t,c)=>{const r=u;return n(),o(r,{href:e.href,target:e.target},{default:s(()=>[f(t.$slots,"default")]),_:3},8,["href","target"])}}});export{i as default}; diff --git a/_nuxt/B3vgOLG7.js b/_nuxt/CGx64xBQ.js similarity index 81% rename from _nuxt/B3vgOLG7.js rename to _nuxt/CGx64xBQ.js index 67dee145..b4bee89d 100644 --- a/_nuxt/B3vgOLG7.js +++ b/_nuxt/CGx64xBQ.js @@ -1 +1 @@ -import{_ as c,k as l,c as d,f as o,g as n,b as e,t as f,S as m,o as p,m as u}from"./D6y6W-Zj.js";const h={setup(){return{show:l(!1)}}},g={class:"bg-gradeint-to-r flex min-h-screen items-center justify-center from-blue-400 to-indigo-500"},y={class:"flex w-96 items-center space-x-4 rounded-2xl bg-white p-4 shadow-xl"},_=e("h1",{class:"font-medium text-gray-900"},"Floofy McFloof",-1),x=e("p",{class:"mt-0.5 text-gray-500"}," Hey! I'm McFloof and I have been a very good boi this year. ",-1),v={class:"absolute inset-x-0 top-0 my-4 flex w-full items-center justify-center"};function w(r,a,b,t,k,H){const s=u,i=m;return p(),d("div",g,[o(i,{as:"template",show:t.show,enter:"transition transform duration-300 ease-out","enter-from":"translate-x-4 opacity-0","enter-to":"translate-x-0 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"opacity-0"},{default:n(()=>[e("div",y,[o(s,{as:"img",enter:"transition transform duration-300 ease-out","enter-from":"rotate-90 scale-50 opacity-0","enter-to":"rotate-0 scale-100 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"opacity-0",class:"h-16 w-16 rounded-full ring ring-indigo-500 ring-opacity-50 ring-offset-2",src:"/images/placeholder.png"}),o(s,{enter:"transition transform duration-300 ease-out","enter-from":"translate-x-12 opacity-0","enter-to":"translate-x-0 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"opacity-0"},{default:n(()=>[_,x]),_:1})])]),_:1},8,["show"]),e("div",v,[e("button",{class:"rounded-lg bg-blue-200 px-4 py-1.5 text-sm font-medium text-indigo-900 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-indigo-600",onClick:a[0]||(a[0]=S=>t.show=!t.show)},f(t.show?"Hide":"Show")+" profile ",1)])])}const C=c(h,[["render",w]]);export{C as default}; +import{l as c,j as l,c as d,i as o,g as n,b as e,t as f,S as m,o as p,q as u}from"./YC8jgtvV.js";const h={setup(){return{show:l(!1)}}},g={class:"bg-gradeint-to-r flex min-h-screen items-center justify-center from-blue-400 to-indigo-500"},y={class:"flex w-96 items-center space-x-4 rounded-2xl bg-white p-4 shadow-xl"},_=e("h1",{class:"font-medium text-gray-900"},"Floofy McFloof",-1),x=e("p",{class:"mt-0.5 text-gray-500"}," Hey! I'm McFloof and I have been a very good boi this year. ",-1),v={class:"absolute inset-x-0 top-0 my-4 flex w-full items-center justify-center"};function w(r,a,b,t,H,S){const s=u,i=m;return p(),d("div",g,[o(i,{as:"template",show:t.show,enter:"transition transform duration-300 ease-out","enter-from":"translate-x-4 opacity-0","enter-to":"translate-x-0 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"opacity-0"},{default:n(()=>[e("div",y,[o(s,{as:"img",enter:"transition transform duration-300 ease-out","enter-from":"rotate-90 scale-50 opacity-0","enter-to":"rotate-0 scale-100 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"opacity-0",class:"h-16 w-16 rounded-full ring ring-indigo-500 ring-opacity-50 ring-offset-2",src:"/images/placeholder.png"}),o(s,{enter:"transition transform duration-300 ease-out","enter-from":"translate-x-12 opacity-0","enter-to":"translate-x-0 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"opacity-0"},{default:n(()=>[_,x]),_:1})])]),_:1},8,["show"]),e("div",v,[e("button",{class:"rounded-lg bg-blue-200 px-4 py-1.5 text-sm font-medium text-indigo-900 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-indigo-600",onClick:a[0]||(a[0]=j=>t.show=!t.show)},f(t.show?"Hide":"Show")+" profile ",1)])])}const B=c(h,[["render",w]]);export{B as default}; diff --git a/_nuxt/CN6FzLjO.js b/_nuxt/CN6FzLjO.js deleted file mode 100644 index 67d65f2e..00000000 --- a/_nuxt/CN6FzLjO.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as s,a7 as t}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),s("ol",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/CNTXZiWI.js b/_nuxt/CNTXZiWI.js deleted file mode 100644 index bb5c0f9f..00000000 --- a/_nuxt/CNTXZiWI.js +++ /dev/null @@ -1 +0,0 @@ -import{d as j,$ as ln,a1 as en,v as w,K as z,a2 as on,a3 as P,a4 as tn,a5 as rn,o as an,D as un,a as sn}from"./D6y6W-Zj.js";import{p as F,k as cn}from"./C-v3KzvZ.js";import{u as pn}from"./DXU4rfre.js";class S{constructor(l,o,t){this.property=l,this.normal=o,t&&(this.space=t)}}S.prototype.property={};S.prototype.normal={};S.prototype.space=null;function H(n,l){const o={},t={};let r=-1;for(;++r4&&o.slice(0,4)==="data"&&fn.test(l)){if(l.charAt(4)==="-"){const a=l.slice(5).replace(_,kn);t="data"+a.charAt(0).toUpperCase()+a.slice(1)}else{const a=l.slice(4);if(!_.test(a)){let i=a.replace(yn,bn);i.charAt(0)!=="-"&&(i="-"+i),l="data"+i}}r=T}return new r(t,l)}function bn(n){return"-"+n.toLowerCase()}function kn(n){return n.charAt(1).toUpperCase()}const Cn=H([q,N,X,Y,hn],"html");H([q,N,X,Y,mn],"svg");const A=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"],R="default",$=/^@|^v-on:/,Z=/^:|^v-bind:/,J=/^v-model/,Sn=["select","textarea","input"],xn=Object.fromEntries(["p","a","blockquote","code","pre","code","em","h1","h2","h3","h4","h5","h6","hr","img","ul","ol","li","strong","table","thead","tbody","td","th","tr","script"].map(n=>[n,`prose-${n}`])),wn=j({name:"MDCRenderer",props:{body:{type:Object,required:!0},data:{type:Object,default:()=>({})},tag:{type:[String,Boolean],default:void 0},prose:{type:Boolean,default:void 0},components:{type:Object,default:()=>({})}},async setup(n){var i,s,c,g,f,p,y,B;const l=(c=(s=(i=ln())==null?void 0:i.appContext)==null?void 0:s.app)==null?void 0:c.$nuxt,o=(l==null?void 0:l.$route)||(l==null?void 0:l._route),{mdc:t}=((g=l==null?void 0:l.$config)==null?void 0:g.public)||{},r={...(f=t==null?void 0:t.components)!=null&&f.prose&&n.prose!==!1?xn:{},...((p=t==null?void 0:t.components)==null?void 0:p.map)||{},...en(((B=(y=n.data)==null?void 0:y.mdc)==null?void 0:B.components)||{}),...n.components},a=w(()=>{var U;const nn=(((U=n.body)==null?void 0:U.children)||[]).map(x=>x.tag||x.type).filter(x=>!A.includes(x));return Array.from(new Set(nn)).sort().join(".")});return await Un(n.body,{tags:r}),{tags:r,contentKey:a,route:o}},render(n){var f,p,y;const{tags:l,tag:o,body:t,data:r,contentKey:a,route:i}=n;if(!t)return null;const s={...r,tags:l,$route:i},c=o!==!1?E(o||((f=s.component)==null?void 0:f.name)||s.component||"div"):void 0,g=G(t,z,s,s);return c?z(c,{...(p=s.component)==null?void 0:p.props,...this.$attrs,key:a},g):(y=g.default)==null?void 0:y.call(g)}});function Pn(n,l,o,t={}){if(n.type==="text")return l(P,n.value);if(n.type==="comment")return l(tn,null,n.value);const r=n.tag,a=Q(n,o.tags);if(n.tag==="binding")return On(n,l,o,t);const i=E(a);typeof i=="object"&&(i.tag=r);const s=Dn(n,o);return l(i,s,G(n,l,o,{...t,...s}))}function On(n,l,o,t={}){var g,f;const r={...t,$document:o,$doc:o},a=/\.|\[(\d+)\]/,s=((g=n.props)==null?void 0:g.value.trim().split(a).filter(Boolean)).reduce((p,y)=>{if(p&&y in p)return typeof p[y]=="function"?p[y]():p[y]},r),c=(f=n.props)==null?void 0:f.defaultValue;return l(P,s??c??"")}function G(n,l,o,t){const a=(n.children||[]).reduce((s,c)=>{if(!En(c))return s[R].push(c),s;const g=An(c);return s[g]=s[g]||[],c.type==="element"&&s[g].push(...c.children||[]),s},{[R]:[]});return Object.entries(a).reduce((s,[c,g])=>(g.length&&(s[c]=()=>{const f=g.map(p=>Pn(p,l,o,t));return Bn(f)}),s),{})}function Dn(n,l){const{tag:o="",props:t={}}=n;return Object.keys(t).reduce(function(r,a){if(a==="__ignoreMap")return r;const i=t[a];if(J.test(a)&&!Sn.includes(o))return Ln(a,i,r,l);if(a==="v-bind")return Mn(a,i,r,l);if($.test(a))return Rn(a,i,r,l);if(Z.test(a))return Tn(a,i,r,l);const{attribute:s}=vn(Cn,a);return Array.isArray(i)&&i.every(c=>typeof c=="string")?(r[s]=i.join(" "),r):(r[s]=i,r)},{})}function Ln(n,l,o,t){const r=p=>+p,a=p=>p.trim(),i=p=>p,s=n.replace(J,"").split(".").filter(p=>p).reduce((p,y)=>(p[y]=!0,p),{}),c="value",g=s.lazy?"change":"input",f=s.number?r:s.trim?a:i;return o[c]=O(l,t),o.on=o.on||{},o.on[g]=p=>t[l]=f(p),o}function Mn(n,l,o,t){const r=O(l,t);return o=Object.assign(o,r),o}function Rn(n,l,o,t){return n=n.replace($,""),o.on=o.on||{},o.on[n]=()=>O(l,t),o}function Tn(n,l,o,t){return n=n.replace(Z,""),o[n]=O(l,t),o}const E=n=>{if(!A.includes(n)&&!(n!=null&&n.render)&&!(n!=null&&n.ssrRender)){const l=on(F(n),!1);if(typeof l=="object")return l}return n};function O(n,l){const o=n.split(".").reduce((t,r)=>typeof t=="object"?t[r]:void 0,l);return typeof o>"u"?rn(n):o}function An(n){let l="";for(const o of Object.keys(n.props||{}))if(!(!o.startsWith("#")&&!o.startsWith("v-slot:"))){l=o.split(/[:#]/,2)[1];break}return l||R}function En(n){return n.tag==="template"}function Bn(n){const l=[];for(const o of n){const t=l[l.length-1];o.type===P&&(t==null?void 0:t.type)===P?t.children=t.children+o.children:l.push(o)}return l}async function Un(n,l){if(!n)return;const o=Array.from(new Set(t(n,l)));await Promise.all(o.map(async r=>{if(r!=null&&r.render||r!=null&&r.ssrRender||r!=null&&r.__ssrInlineRender)return;const a=E(r);a!=null&&a.__asyncLoader&&!a.__asyncResolved&&await a.__asyncLoader()}));function t(r,a){const i=r.tag;if(r.type==="text"||i==="binding"||r.type==="comment")return[];const s=Q(r,a.tags),c=[];r.type!=="root"&&!A.includes(s)&&c.push(s);for(const g of r.children||[])c.push(...t(g,a));return c}}function Q(n,l){var t;const o=n.tag;return!o||typeof((t=n.props)==null?void 0:t.__ignoreMap)<"u"?o:l[o]||l[F(o)]||l[cn(n.tag)]||o}const jn=j({__name:"ContentRendererMarkdown",props:{value:{type:Object,required:!0},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"},components:{type:Object,default:()=>({})},data:{type:Object,default:()=>({})}},setup(n){const l=n,o=pn().isEnabled(),t=w(()=>{let i=l.value.body||l.value;return l.excerpt&&l.value.excerpt&&(i=l.value.excerpt),i}),r=w(()=>{const{body:i,excerpt:s,...c}=l.value;return{...c,...l.data}}),a=w(()=>({...l.components,...r.value._components||{}}));return(i,s)=>{const c=wn;return an(),un(c,{body:t.value,data:r.value,tag:n.tag,components:a.value,"data-content-id":sn(o)?n.value._id:void 0},null,8,["body","data","tag","components","data-content-id"])}}});export{jn as _}; diff --git a/_nuxt/CRLNagtS.js b/_nuxt/CRLNagtS.js new file mode 100644 index 00000000..7c0c22ab --- /dev/null +++ b/_nuxt/CRLNagtS.js @@ -0,0 +1 @@ +import{u as A,j as h,w as B,k as p,c as l,b as e,F as m,r as g,a as c,o as r,i as v,g as b,h as R,t as d,e as S,n as y,_ as j}from"./YC8jgtvV.js";import{_ as D}from"./DuCNYxTx.js";import F from"./Cj9zn9Hh.js";import{u as L}from"./DjmxGRUG.js";import{q as z}from"./NquB2IUV.js";import"./C-v3KzvZ.js";import"./Dnd51l0P.js";import"./JthqPOXk.js";import"./DvDH6DOc.js";const E={class:"container mx-auto"},M={class:"grid grid-cols-4 gap-4"},G={class:"col-span-4 lg:col-span-3"},H={class:"rounded-xl bg-black/50 text-white shadow-xl"},I={class:"relative mb-2 h-full"},J={class:"px-4 py-2"},K={class:"mb-2 text-xl font-bold"},O={class:"flex items-center text-sm"},P={class:"mb-3 px-4"},Q={class:"prose-sm"},U={class:"col-span-4 inline-block lg:col-span-1"},W={class:"mb-3 rounded-xl bg-black/50 text-white"},X=e("p",{class:"mb-0 px-3 py-2 text-xl font-bold"},"Categories",-1),Y=["onClick"],Z={class:"mb-3 rounded-xl bg-black/50 text-white"},ee=e("p",{class:"mb-0 px-3 py-2 text-xl font-bold"},"Tags",-1),te={class:"p-2"},se=["onClick"],me={__name:"index",async setup(oe){let i,x;const u=A(),o=h([]);u.query.category&&(o.value=[u.query.category]);const n=h([]);u.query.tag&&(n.value=[u.query.tag]);const{data:_}=([i,x]=B(()=>L("articles",()=>z().only(["_id","_path","title","description","date","img","author","tags","categories","img","excerpt","summary"]).sort({date:-1}).find())),i=await i,x(),i),k=p(()=>[...new Set(_.value.map(t=>t.categories).flat().sort())]),C=p(()=>[...new Set(_.value.map(t=>t.tags).flat().sort())]),w=p(()=>_.value.filter(t=>!(o.value.length>0&&!o.value.every(a=>t.categories.includes(a))||n.value.length>0&&!n.value.every(a=>t.tags.includes(a)))));function q(t){n.value.includes(t)?n.value=n.value.filter(a=>a!==t):n.value.push(t)}function N(t){o.value.includes(t)?o.value=o.value.filter(a=>a!==t):o.value.push(t)}return(t,a)=>{const T=j,V=D,$=F;return r(),l("section",E,[e("div",M,[e("div",G,[(r(!0),l(m,null,g(c(w),s=>(r(),l("div",{key:s._id},[e("div",H,[e("div",I,[e("div",J,[e("div",K,[v(T,{class:"border-b-2 border-orange-500 hover:text-orange-500",to:s._path},{default:b(()=>[R(d(s.title),1)]),_:2},1032,["to"])]),e("p",O,d(s.date),1)]),e("div",P,[e("p",Q,[v($,{class:"prose prose-sm mx-auto sm:prose lg:prose-lg xl:prose-2xl",value:s},{default:b(()=>[v(V,{value:{body:s.excerpt}},null,8,["value"])]),_:2},1032,["value"])])]),S("",!0)])])]))),128))]),e("div",U,[e("div",W,[X,(r(!0),l(m,null,g(c(k),s=>(r(),l("a",{key:s,class:y([{"bg-orange-500":c(o).includes(s)},"block cursor-pointer select-none border-t border-black px-4 py-1 text-orange-200 hover:bg-black"]),onClick:f=>N(s)},d(s),11,Y))),128))]),e("div",Z,[ee,e("div",te,[(r(!0),l(m,null,g(c(C),(s,f)=>(r(),l("span",{key:f,class:y([{"bg-orange-500":c(n).includes(s)},"mb-2 mr-2 inline-flex h-8 cursor-pointer select-none content-center justify-center bg-black px-3 py-2 text-sm leading-4 text-orange-200"]),onClick:ne=>q(s)},[e("div",null,d(s),1)],10,se))),128))])])])])])}}};export{me as default}; diff --git a/_nuxt/KkmkYs8s.js b/_nuxt/CSeyXkCN.js similarity index 77% rename from _nuxt/KkmkYs8s.js rename to _nuxt/CSeyXkCN.js index e90e42c3..51c4e27c 100644 --- a/_nuxt/KkmkYs8s.js +++ b/_nuxt/CSeyXkCN.js @@ -1 +1 @@ -import{d as n,K as e}from"./D6y6W-Zj.js";const r=n({name:"DocumentDrivenEmpty",props:{value:{type:Object,required:!0}},render({value:t}){return e("div",void 0,[e("p","Document is empty"),e("p",`Add content to it by opening ${t._source}/${t._file} file.`)])}});export{r as default}; +import{d as n,K as e}from"./YC8jgtvV.js";const r=n({name:"DocumentDrivenEmpty",props:{value:{type:Object,required:!0}},render({value:t}){return e("div",void 0,[e("p","Document is empty"),e("p",`Add content to it by opening ${t._source}/${t._file} file.`)])}});export{r as default}; diff --git a/_nuxt/CUFuiolx.js b/_nuxt/CUFuiolx.js deleted file mode 100644 index 413d65a0..00000000 --- a/_nuxt/CUFuiolx.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as t,a7 as s}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),t("th",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/CWeMlRBK.js b/_nuxt/CWeMlRBK.js new file mode 100644 index 00000000..246e4703 --- /dev/null +++ b/_nuxt/CWeMlRBK.js @@ -0,0 +1 @@ +import{_ as o}from"./DuCNYxTx.js";import"./YC8jgtvV.js";import"./C-v3KzvZ.js";import"./Dnd51l0P.js";import"./JthqPOXk.js";import"./DvDH6DOc.js";export{o as default}; diff --git a/_nuxt/CwYjkwfo.js b/_nuxt/CX8WYcQA.js similarity index 97% rename from _nuxt/CwYjkwfo.js rename to _nuxt/CX8WYcQA.js index a9c6dfe2..6f6c7931 100644 --- a/_nuxt/CwYjkwfo.js +++ b/_nuxt/CX8WYcQA.js @@ -1 +1 @@ -import{_ as u,c as s,h as r,b as t,n as f,t as n,F as c,r as h,e as m,o}from"./D6y6W-Zj.js";const v={mounted(){typeof navigator.requestMIDIAccess<"u"&&navigator.requestMIDIAccess().then(i=>{this.midi=i,this.midi.inputs.forEach(l=>{l.onmidimessage=_=>{this.events.push(_),this.events.length>15&&this.events.shift()}})},i=>{console.error(i)})},data(){return{tooltip:!1,midi:void 0,events:[]}},computed:{inputs(){if(typeof this.midi<"u")return Array.from(this.midi.inputs.values())},outputs(){if(typeof this.midi<"u")return Array.from(this.midi.outputs.values())}},filters:{midiCommand:i=>{switch(i){case 144:return"Note On";case 128:return"Note Off";default:return i}},midiNote:i=>`${["C","C# / Db","D","D# / Eb","E","F","F# / Bb","G","G# / Ab","A","A# / Bb","B"][i%12]} (${Math.floor(i/12)-2})`}},b={class:"h-2/3 bg-gradient-to-b from-green-100 to-green-50"},x={key:0,class:"p-4 text-center font-light tracking-wide"},g=t("a",{class:"text-blue-500 underline",href:"https://developer.mozilla.org/en-US/docs/Web/API/MIDIMessageEvent#browser_compatibility"},"not supported",-1),y={key:1},w={class:"flex flex-wrap"},k={class:"absolute bottom-16 right-2"},I=t("div",{class:"mb-0 rounded-t-lg border-b border-solid bg-green-600 p-3 font-semibold uppercase text-white opacity-75"}," MIDI Status ",-1),M={class:"p-3 font-mono text-orange-900"},N={class:"mb-2 font-bold"},D={class:"mb-2"},C=t("div",{class:"font-bold"},"Inputs:",-1),A={key:0,class:"p-4 text-center italic"},z={key:1},E={class:"flex-1"},V={class:"flex-1"},B={class:"mb-2"},F=t("div",{class:"font-bold"},"Outputs:",-1),S={key:0,class:"p-4 text-center italic"},O={key:1},P={class:"flex-1"},q={class:"flex-1"},G={class:"absolute bottom-2 right-2"},T=t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20",class:"h-10 w-10"},[t("g",{fill:"none"},[t("path",{d:"M2.5 4a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5h-15zm.5 6h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v5H3v-5zm2.75-2.5a.75.75 0 1 1 0-1.5a.75.75 0 0 1 0 1.5zm6.25-1a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm-3 .251a.75.75 0 1 1-1.5 0a.75.75 0 0 1 1.5 0z",fill:"currentColor"})])],-1),U=[T],W={class:"container mx-auto p-8"},H=t("div",{class:"font-display text-4xl font-light tracking-wide"}," MIDI Events ",-1),L={class:"w-full table-auto border-2 border-green-800 bg-green-50 text-sm"},R=t("thead",{class:"bg-green-800 font-semibold uppercase text-white"},[t("tr",null,[t("th",{class:"p-2 text-left"},"Timestamp"),t("th",{class:"p-2 text-left"},"Command #"),t("th",{class:"p-2 text-left"},"Command"),t("th",{class:"p-2 text-left"},"Note #"),t("th",{class:"p-2 text-left"},"Note"),t("th",{class:"p-2 text-left"},"Velocity"),t("th",{class:"p-2 text-right"},"MIDI Source")])],-1),Y={class:"divide-y divide-gray-100"},j={key:0},J=t("td",{class:"p-4 text-center italic",colspan:"7"}," Press a key, or turn a knob! ",-1),K=[J],Q={class:"p-2 text-left"},X={class:"p-2 text-left"},Z={class:"p-2 text-left"},$={class:"p-2 text-left"},tt={key:0,class:"p-2 text-left"},et={key:1,class:"p-2 text-left"},st={class:"p-2 text-left"},ot={class:"p-2 text-right"};function it(i,l,_,nt,d,a){return o(),s("div",b,[typeof d.midi>"u"?(o(),s("div",x,[r(" Unfortunately, the Web MIDI API is "),g,r(" in all browsers... ")])):(o(),s("div",y,[t("div",w,[t("div",k,[t("div",{class:f([{hidden:!d.tooltip,block:d.tooltip},"z-50 max-w-md break-words rounded-lg border-2 border-green-800 bg-yellow-200 text-sm font-normal leading-normal"])},[t("div",null,[I,t("div",M,[t("div",N,[r(" Enabled: "),t("span",null,n(typeof d.midi<"u"?"Yep!":"Nope"),1)]),t("div",D,[C,a.inputs.length===0?(o(),s("div",A," No input devices detected :( ")):(o(),s("div",z,[(o(!0),s(c,null,h(a.inputs,e=>(o(),s("div",{key:e.id,class:"flex"},[t("div",E,n(e.manufacturer),1),t("div",V,n(e.name),1)]))),128))]))]),t("div",B,[F,a.outputs.length===0?(o(),s("div",S," No output devices detected :( ")):(o(),s("div",O,[(o(!0),s(c,null,h(a.outputs,e=>(o(),s("div",{key:e.id,class:"flex"},[t("div",P,n(e.manufacturer),1),t("div",q,n(e.name),1)]))),128))]))])])])],2)]),t("div",G,[t("button",{ref:"btnRef",onClick:l[0]||(l[0]=e=>d.tooltip=!d.tooltip),class:"rounded-lg bg-green-800 px-2 py-1 text-white shadow hover:text-yellow-200 hover:shadow-lg",type:"button"},U,512)])]),t("div",W,[H,t("table",L,[R,t("tbody",Y,[d.events.length===0?(o(),s("tr",j,K)):m("",!0),(o(!0),s(c,null,h(d.events,(e,p)=>(o(),s("tr",{key:p},[t("td",Q,n(e.timeStamp.toFixed(2)),1),t("td",X,n(e.data[0]),1),t("td",Z,n(e.data[0]|i.midiCommand),1),t("td",$,n(e.data[1]),1),e.data[0]===144||e.data[0]==128?(o(),s("td",tt,n(e.data[1]|i.midiNote),1)):(o(),s("td",et,"-")),t("td",st,n(e.data[2]),1),t("td",ot,n(e.srcElement.name),1)]))),128))])])])]))])}const lt=u(v,[["render",it]]);export{lt as default}; +import{l as u,c as s,h as r,b as t,n as f,t as n,F as c,r as h,e as m,o}from"./YC8jgtvV.js";const v={mounted(){typeof navigator.requestMIDIAccess<"u"&&navigator.requestMIDIAccess().then(i=>{this.midi=i,this.midi.inputs.forEach(l=>{l.onmidimessage=_=>{this.events.push(_),this.events.length>15&&this.events.shift()}})},i=>{console.error(i)})},data(){return{tooltip:!1,midi:void 0,events:[]}},computed:{inputs(){if(typeof this.midi<"u")return Array.from(this.midi.inputs.values())},outputs(){if(typeof this.midi<"u")return Array.from(this.midi.outputs.values())}},filters:{midiCommand:i=>{switch(i){case 144:return"Note On";case 128:return"Note Off";default:return i}},midiNote:i=>`${["C","C# / Db","D","D# / Eb","E","F","F# / Bb","G","G# / Ab","A","A# / Bb","B"][i%12]} (${Math.floor(i/12)-2})`}},b={class:"h-2/3 bg-gradient-to-b from-green-100 to-green-50"},x={key:0,class:"p-4 text-center font-light tracking-wide"},g=t("a",{class:"text-blue-500 underline",href:"https://developer.mozilla.org/en-US/docs/Web/API/MIDIMessageEvent#browser_compatibility"},"not supported",-1),y={key:1},w={class:"flex flex-wrap"},k={class:"absolute bottom-16 right-2"},I=t("div",{class:"mb-0 rounded-t-lg border-b border-solid bg-green-600 p-3 font-semibold uppercase text-white opacity-75"}," MIDI Status ",-1),M={class:"p-3 font-mono text-orange-900"},N={class:"mb-2 font-bold"},D={class:"mb-2"},C=t("div",{class:"font-bold"},"Inputs:",-1),A={key:0,class:"p-4 text-center italic"},z={key:1},E={class:"flex-1"},V={class:"flex-1"},B={class:"mb-2"},F=t("div",{class:"font-bold"},"Outputs:",-1),S={key:0,class:"p-4 text-center italic"},O={key:1},P={class:"flex-1"},q={class:"flex-1"},G={class:"absolute bottom-2 right-2"},T=t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20",class:"h-10 w-10"},[t("g",{fill:"none"},[t("path",{d:"M2.5 4a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5h-15zm.5 6h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v5H3v-5zm2.75-2.5a.75.75 0 1 1 0-1.5a.75.75 0 0 1 0 1.5zm6.25-1a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm-3 .251a.75.75 0 1 1-1.5 0a.75.75 0 0 1 1.5 0z",fill:"currentColor"})])],-1),U=[T],W={class:"container mx-auto p-8"},H=t("div",{class:"font-display text-4xl font-light tracking-wide"}," MIDI Events ",-1),L={class:"w-full table-auto border-2 border-green-800 bg-green-50 text-sm"},R=t("thead",{class:"bg-green-800 font-semibold uppercase text-white"},[t("tr",null,[t("th",{class:"p-2 text-left"},"Timestamp"),t("th",{class:"p-2 text-left"},"Command #"),t("th",{class:"p-2 text-left"},"Command"),t("th",{class:"p-2 text-left"},"Note #"),t("th",{class:"p-2 text-left"},"Note"),t("th",{class:"p-2 text-left"},"Velocity"),t("th",{class:"p-2 text-right"},"MIDI Source")])],-1),Y={class:"divide-y divide-gray-100"},j={key:0},J=t("td",{class:"p-4 text-center italic",colspan:"7"}," Press a key, or turn a knob! ",-1),K=[J],Q={class:"p-2 text-left"},X={class:"p-2 text-left"},Z={class:"p-2 text-left"},$={class:"p-2 text-left"},tt={key:0,class:"p-2 text-left"},et={key:1,class:"p-2 text-left"},st={class:"p-2 text-left"},ot={class:"p-2 text-right"};function it(i,l,_,nt,d,a){return o(),s("div",b,[typeof d.midi>"u"?(o(),s("div",x,[r(" Unfortunately, the Web MIDI API is "),g,r(" in all browsers... ")])):(o(),s("div",y,[t("div",w,[t("div",k,[t("div",{class:f([{hidden:!d.tooltip,block:d.tooltip},"z-50 max-w-md break-words rounded-lg border-2 border-green-800 bg-yellow-200 text-sm font-normal leading-normal"])},[t("div",null,[I,t("div",M,[t("div",N,[r(" Enabled: "),t("span",null,n(typeof d.midi<"u"?"Yep!":"Nope"),1)]),t("div",D,[C,a.inputs.length===0?(o(),s("div",A," No input devices detected :( ")):(o(),s("div",z,[(o(!0),s(c,null,h(a.inputs,e=>(o(),s("div",{key:e.id,class:"flex"},[t("div",E,n(e.manufacturer),1),t("div",V,n(e.name),1)]))),128))]))]),t("div",B,[F,a.outputs.length===0?(o(),s("div",S," No output devices detected :( ")):(o(),s("div",O,[(o(!0),s(c,null,h(a.outputs,e=>(o(),s("div",{key:e.id,class:"flex"},[t("div",P,n(e.manufacturer),1),t("div",q,n(e.name),1)]))),128))]))])])])],2)]),t("div",G,[t("button",{ref:"btnRef",onClick:l[0]||(l[0]=e=>d.tooltip=!d.tooltip),class:"rounded-lg bg-green-800 px-2 py-1 text-white shadow hover:text-yellow-200 hover:shadow-lg",type:"button"},U,512)])]),t("div",W,[H,t("table",L,[R,t("tbody",Y,[d.events.length===0?(o(),s("tr",j,K)):m("",!0),(o(!0),s(c,null,h(d.events,(e,p)=>(o(),s("tr",{key:p},[t("td",Q,n(e.timeStamp.toFixed(2)),1),t("td",X,n(e.data[0]),1),t("td",Z,n(e.data[0]|i.midiCommand),1),t("td",$,n(e.data[1]),1),e.data[0]===144||e.data[0]==128?(o(),s("td",tt,n(e.data[1]|i.midiNote),1)):(o(),s("td",et,"-")),t("td",st,n(e.data[2]),1),t("td",ot,n(e.srcElement.name),1)]))),128))])])])]))])}const lt=u(v,[["render",it]]);export{lt as default}; diff --git a/_nuxt/CCipQ263.js b/_nuxt/CZ4lq9R5.js similarity index 63% rename from _nuxt/CCipQ263.js rename to _nuxt/CZ4lq9R5.js index 89e4d7ea..e71f6d64 100644 --- a/_nuxt/CCipQ263.js +++ b/_nuxt/CZ4lq9R5.js @@ -1 +1 @@ -import{_ as c,o as p,c as b,b as i,A as r,B as m,f as u}from"./D6y6W-Zj.js";const h={props:{id:{type:String,default:"canvas"},canvasHeight:{type:Number,default:250},type:{type:String,default:"sin"},diameter:{type:Number,default:15},amplitude:{type:Number,default:75},lambda:{type:Number,default:266}},mounted(){const o=e=>{const a=e.windowWidth>=450?this.canvasHeight:200,l=e.windowWidth>=450?800:300;let t=0,d=a/2,s=0;const n=100,_=125;e.setup=()=>{e.createCanvas(l,a),t=-this.diameter},e.draw=()=>{this.type==="sin"?d=this.amplitude*e.sin(t*(e.TWO_PI/this.lambda))+a/2:this.type==="cos"?d=this.amplitude*e.cos(t*(e.TWO_PI/this.lambda))+a/2:this.type==="tan"?d=this.amplitude*e.tan(t*(e.TWO_PI/this.lambda))+a/2:d=a/2,s=Math.round(e.map(d,-this.amplitude+a/2,this.amplitude+a/2,0,255)),t=t>=l+this.diameter?-this.diameter:t+1,e.noStroke(),e.fill(e.color(s,n,_)),e.ellipse(t,d,this.diameter,this.diameter)},e.mousePressed=()=>{e.clear()}};new this.$p5(o,this.id)},data(){return{}}},v=["id"];function w(o,e,a,l,t,d){return p(),b("div",{id:a.id},null,8,v)}const f=c(h,[["render",w]]),y={data(){return{wave:{amplitude:75,lambda:266,diameter:15}}}},x={class:"bg-gradient-to-b from-green-800 to-gray-800"},g={class:"grid h-screen place-items-center"},I={class:"font-mono text-white"},k={class:"my-2 items-end md:flex"},W=i("div",{class:"flex-none md:flex-1"},"y(x) = A sin((2π / λ) x)",-1),N={class:"hidden md:block"},T=i("label",{for:"aInput",class:"form-label inline-block"},"A",-1),A=i("label",{for:"lInput",class:"form-label inline-block"},"λ",-1),B=i("label",{for:"dInput",class:"form-label inline-block"},"◒",-1),H={class:"mb-2 border-2 border-white"},P=i("div",null,"y(x) = A cos((2π / λ) x)",-1),V={class:"mb-2 border-2 border-white"},O=i("div",null,"y(x) = A tan((2π / λ) x)",-1),S={class:"border-2 border-white"},U=i("div",{class:"my-2 w-48 md:w-full"}," Click or tap anywhere to clear the canvas! ",-1);function C(o,e,a,l,t,d){const s=f;return p(),b("div",x,[i("div",g,[i("div",I,[i("div",k,[W,i("div",N,[T,r(i("input",{id:"aInput","onUpdate:modelValue":e[0]||(e[0]=n=>t.wave.amplitude=n),type:"number",class:"w-16 border-2 border-white bg-transparent p-2 focus:outline-none"},null,512),[[m,t.wave.amplitude,void 0,{number:!0}]]),A,r(i("input",{id:"lInput","onUpdate:modelValue":e[1]||(e[1]=n=>t.wave.lambda=n),type:"number",class:"w-16 border-2 border-white bg-transparent p-2 focus:outline-none"},null,512),[[m,t.wave.lambda,void 0,{number:!0}]]),B,r(i("input",{id:"dInput","onUpdate:modelValue":e[2]||(e[2]=n=>t.wave.diameter=n),type:"number",class:"w-16 border-2 border-white bg-transparent p-2 focus:outline-none"},null,512),[[m,t.wave.diameter,void 0,{number:!0}]])])]),i("div",H,[u(s,{id:"canvas1",type:"sin",diameter:t.wave.diameter,amplitude:t.wave.amplitude,lambda:t.wave.lambda},null,8,["diameter","amplitude","lambda"])]),P,i("div",V,[u(s,{id:"canvas2",type:"cos",diameter:t.wave.diameter,amplitude:t.wave.amplitude,lambda:t.wave.lambda},null,8,["diameter","amplitude","lambda"])]),O,i("div",S,[u(s,{id:"canvas3",type:"tan",diameter:t.wave.diameter,amplitude:t.wave.amplitude,lambda:t.wave.lambda},null,8,["diameter","amplitude","lambda"])]),U])])])}const E=c(y,[["render",C]]);export{E as default}; +import{l as c,o as p,c as b,b as i,B as r,C as m,i as u}from"./YC8jgtvV.js";const _={props:{id:{type:String,default:"canvas"},canvasHeight:{type:Number,default:250},type:{type:String,default:"sin"},diameter:{type:Number,default:15},amplitude:{type:Number,default:75},lambda:{type:Number,default:266}},mounted(){const o=e=>{const a=e.windowWidth>=450?this.canvasHeight:200,l=e.windowWidth>=450?800:300;let t=0,d=a/2,s=0;const n=100,h=125;e.setup=()=>{e.createCanvas(l,a),t=-this.diameter},e.draw=()=>{this.type==="sin"?d=this.amplitude*e.sin(t*(e.TWO_PI/this.lambda))+a/2:this.type==="cos"?d=this.amplitude*e.cos(t*(e.TWO_PI/this.lambda))+a/2:this.type==="tan"?d=this.amplitude*e.tan(t*(e.TWO_PI/this.lambda))+a/2:d=a/2,s=Math.round(e.map(d,-this.amplitude+a/2,this.amplitude+a/2,0,255)),t=t>=l+this.diameter?-this.diameter:t+1,e.noStroke(),e.fill(e.color(s,n,h)),e.ellipse(t,d,this.diameter,this.diameter)},e.mousePressed=()=>{e.clear()}};new this.$p5(o,this.id)},data(){return{}}},v=["id"];function w(o,e,a,l,t,d){return p(),b("div",{id:a.id},null,8,v)}const f=c(_,[["render",w]]),y={data(){return{wave:{amplitude:75,lambda:266,diameter:15}}}},x={class:"bg-gradient-to-b from-green-800 to-gray-800"},g={class:"grid h-screen place-items-center"},I={class:"font-mono text-white"},k={class:"my-2 items-end md:flex"},W=i("div",{class:"flex-none md:flex-1"},"y(x) = A sin((2π / λ) x)",-1),N={class:"hidden md:block"},T=i("label",{for:"aInput",class:"form-label inline-block"},"A",-1),B=i("label",{for:"lInput",class:"form-label inline-block"},"λ",-1),H=i("label",{for:"dInput",class:"form-label inline-block"},"◒",-1),P={class:"mb-2 border-2 border-white"},V=i("div",null,"y(x) = A cos((2π / λ) x)",-1),A={class:"mb-2 border-2 border-white"},C=i("div",null,"y(x) = A tan((2π / λ) x)",-1),O={class:"border-2 border-white"},S=i("div",{class:"my-2 w-48 md:w-full"}," Click or tap anywhere to clear the canvas! ",-1);function U(o,e,a,l,t,d){const s=f;return p(),b("div",x,[i("div",g,[i("div",I,[i("div",k,[W,i("div",N,[T,r(i("input",{id:"aInput","onUpdate:modelValue":e[0]||(e[0]=n=>t.wave.amplitude=n),type:"number",class:"w-16 border-2 border-white bg-transparent p-2 focus:outline-none"},null,512),[[m,t.wave.amplitude,void 0,{number:!0}]]),B,r(i("input",{id:"lInput","onUpdate:modelValue":e[1]||(e[1]=n=>t.wave.lambda=n),type:"number",class:"w-16 border-2 border-white bg-transparent p-2 focus:outline-none"},null,512),[[m,t.wave.lambda,void 0,{number:!0}]]),H,r(i("input",{id:"dInput","onUpdate:modelValue":e[2]||(e[2]=n=>t.wave.diameter=n),type:"number",class:"w-16 border-2 border-white bg-transparent p-2 focus:outline-none"},null,512),[[m,t.wave.diameter,void 0,{number:!0}]])])]),i("div",P,[u(s,{id:"canvas1",type:"sin",diameter:t.wave.diameter,amplitude:t.wave.amplitude,lambda:t.wave.lambda},null,8,["diameter","amplitude","lambda"])]),V,i("div",A,[u(s,{id:"canvas2",type:"cos",diameter:t.wave.diameter,amplitude:t.wave.amplitude,lambda:t.wave.lambda},null,8,["diameter","amplitude","lambda"])]),C,i("div",O,[u(s,{id:"canvas3",type:"tan",diameter:t.wave.diameter,amplitude:t.wave.amplitude,lambda:t.wave.lambda},null,8,["diameter","amplitude","lambda"])]),S])])])}const E=c(y,[["render",U]]);export{E as default}; diff --git a/_nuxt/CZMejQjK.js b/_nuxt/CZMejQjK.js deleted file mode 100644 index 94b154a9..00000000 --- a/_nuxt/CZMejQjK.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as s,a7 as t}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),s("ul",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/CcZdBpHY.js b/_nuxt/CcZdBpHY.js deleted file mode 100644 index e810f5a1..00000000 --- a/_nuxt/CcZdBpHY.js +++ /dev/null @@ -1 +0,0 @@ -import{d as r,v as n,Q as c,J as h,H as o,R as d,o as l,c as u,a as f}from"./D6y6W-Zj.js";const g=["src","alt","width","height"],p=r({__name:"ProseImg",props:{src:{type:String,default:""},alt:{type:String,default:""},width:{type:[String,Number],default:void 0},height:{type:[String,Number],default:void 0}},setup(e){const t=e,i=n(()=>{var a;if((a=t.src)!=null&&a.startsWith("/")&&!t.src.startsWith("//")){const s=c(h(o().app.baseURL));if(s!=="/"&&!t.src.startsWith(s))return d(s,t.src)}return t.src});return(a,s)=>(l(),u("img",{src:f(i),alt:e.alt,width:e.width,height:e.height},null,8,g))}});export{p as default}; diff --git a/_nuxt/Ce-DNi_D.js b/_nuxt/Ce-DNi_D.js new file mode 100644 index 00000000..8b110bf4 --- /dev/null +++ b/_nuxt/Ce-DNi_D.js @@ -0,0 +1 @@ +import{l as o,o as r,c as t,a7 as a}from"./YC8jgtvV.js";const s={};function c(e,l){return r(),t("table",null,[a(e.$slots,"default")])}const f=o(s,[["render",c]]);export{f as default}; diff --git a/_nuxt/CeNIwOQb.js b/_nuxt/CeNIwOQb.js deleted file mode 100644 index a02cab1a..00000000 --- a/_nuxt/CeNIwOQb.js +++ /dev/null @@ -1 +0,0 @@ -import{_,c as s,h as l,b as e,n as v,t as d,F as c,r as h,f as b,g as y,T as M,o as r,e as g}from"./D6y6W-Zj.js";var O={};Object.defineProperty(O,"__esModule",{value:!0});var p=O.identify=void 0;const u=["C","C# / Db","D","D# / Eb","E","F","F# / Gb","G","G# / Ab","A","A# / Bb","B"],x={"0 1":{name:"No 3 Major 7",rootOffset:1},"0 2":{name:"No 3 7",rootOffset:2},"0 3":{name:"Minor",rootOffset:0},"0 4":{name:"",rootOffset:0},"0 5":{name:"5",rootOffset:5},"0 6":{name:"7",rootOffset:2},"0 7":{name:"5",rootOffset:0},"0 8":{name:"",rootOffset:8},"0 9":{name:"Minor",rootOffset:9},"0 10":{name:"No 3 7",rootOffset:0},"0 11":{name:"No 3 Major 7",rootOffset:0},"0 2 7":{name:"Suspended 2",rootOffset:0},"0 3 6 10":{name:"Half-diminished 7",rootOffset:0},"0 3 6 9":{name:"Diminished 7",rootOffset:0},"0 3 6":{name:"Diminished",rootOffset:0},"0 3 7 10":{name:"Minor 7",rootOffset:0},"0 3 7 11":{name:"Minor-major 7",rootOffset:0},"0 3 7 9":{name:"Minor 6",rootOffset:0},"0 3 7":{name:"Minor",rootOffset:0},"0 4 10":{name:"7",rootOffset:0},"0 4 11":{name:"Major 7",rootOffset:0},"0 4 5 7":{name:"Add 11",rootOffset:0},"0 4 6":{name:"Flat 5",rootOffset:0},"0 4 7 10":{name:"Dominant 7",rootOffset:0},"0 4 7 11":{name:"Major 7",rootOffset:0},"0 4 7 9":{name:"Major 6",rootOffset:0},"0 4 7":{name:"",rootOffset:0},"0 4 8 10":{name:"Augmented 7",rootOffset:0},"0 4 8":{name:"Augmented",rootOffset:0},"0 5 7":{name:"Suspended 4",rootOffset:0},"0 5 8":{name:"Minor",rootOffset:5},"0 5 9":{name:"",rootOffset:5},"0 4 9":{name:"Minor",rootOffset:9},"0 3 8":{name:"",rootOffset:8},"0 1 5":{name:"Major 7",rootOffset:1},"0 2 6":{name:"Major 7",rootOffset:2},"0 4 5":{name:"5 Major 7",rootOffset:5},"0 1 2":{name:"No 3 7 Major 7",rootOffset:2},"0 1 3":{name:"Minor Add Flat 9",rootOffset:0},"0 1 6":{name:"5 Sharp 11",rootOffset:6},"0 1 7":{name:"5 Add Flat 9",rootOffset:0},"0 1 8":{name:"5 Major 7",rootOffset:1},"0 1 9":{name:"Sharp 9",rootOffset:9},"0 1 10":{name:"Minor Add 9",rootOffset:10},"0 1 11":{name:"No 3 7 Major 7",rootOffset:1},"0 2 10":{name:"Add 9",rootOffset:10},"0 2 11":{name:"Minor Add Flat 9",rootOffset:11},"0 2 3":{name:"Minor Add 9",rootOffset:0},"0 2 4":{name:"Add 9",rootOffset:0},"0 2 5":{name:"Minor 7",rootOffset:2},"0 2 8":{name:"Flat 5",rootOffset:8},"0 2 9":{name:"5 7",rootOffset:2},"0 3 10":{name:"Minor 7",rootOffset:0},"0 3 4":{name:"Sharp 9",rootOffset:0},"0 3 5":{name:"5 7",rootOffset:5},"0 3 9":{name:"Minor 6",rootOffset:0},"0 5 10":{name:"Suspended 2",rootOffset:10},"0 5 11":{name:"5 Sharp 11",rootOffset:5},"0 5 6":{name:"5 Add Flat 9",rootOffset:5},"0 6 10":{name:"Flat 5",rootOffset:6},"0 6 7":{name:"5 Sharp 11",rootOffset:0},"0 6 8":{name:"7",rootOffset:8},"0 6 9":{name:"Minor 6",rootOffset:9},"0 7 10":{name:"5 7",rootOffset:0},"0 7 11":{name:"5 Major 7",rootOffset:0},"0 7 8":{name:"Major 7",rootOffset:8},"0 7 9":{name:"Minor 7",rootOffset:9},"0 8 10":{name:"Add 9",rootOffset:8},"0 8 11":{name:"Sharp 9",rootOffset:8},"0 9 10":{name:"Minor Add Flat 9",rootOffset:9},"0 9 11":{name:"Minor Add 9",rootOffset:9},"0 10 11":{name:"No 3 7 Major 7",rootOffset:0},"0 1 4":{name:"Sharp 9",rootOffset:9},"0 8 9":{name:"Sharp 9",rootOffset:5},"0 6 11":{name:"7/13",rootOffset:2},"0 3 11":{name:"Sharp 9",rootOffset:8}};function w(f){const a=f.map(t=>typeof t=="number"?t:u.indexOf(t));if(a.some(t=>t<0))throw new Error("Unsupported note letter or number provided");if(new Set(a.map(t=>t%12)).size===1)return{name:u[a[0]%12]};const i=a.sort((t,o)=>t-o)[0]%12,m=[...new Set(a.map(t=>(t-i)%12).sort((t,o)=>t-o))],n=x[m.join(" ")];if(n){const t=(i+n.rootOffset)%12,o=u[t];return{name:n.name!==""?`${o} ${n.name}`:o,interval:m,root:t}}else return{name:void 0}}p=O.identify=w;const A={mounted(){typeof navigator.requestMIDIAccess<"u"&&navigator.requestMIDIAccess().then(f=>{this.midi=f,this.midi.inputs.forEach(a=>{a.onmidimessage=i=>{i.data[0]===144&&(this.activeKeys.set(i.data[1],i.data),this.$forceUpdate()),i.data[0]===128&&(this.activeKeys.delete(i.data[1]),this.$forceUpdate())}})},f=>{console.error(f)})},data(){return{tooltip:!1,midi:void 0,activeKeys:new Map}},computed:{inputs(){if(typeof this.midi<"u")return Array.from(this.midi.inputs.values())},outputs(){if(typeof this.midi<"u")return Array.from(this.midi.outputs.values())}},methods:{orderedNotes(){return Array.from(this.activeKeys.keys()).sort()},chord(){const f=Array.from(this.activeKeys.keys());return p(f).name}}},k={class:"h-2/3 bg-gradient-to-b from-green-900 via-purple-900 to-indigo-900 text-white"},N={key:0,class:"p-4 text-center font-light tracking-wide"},S=e("a",{class:"text-blue-500 underline",href:"https://developer.mozilla.org/en-US/docs/Web/API/MIDIMessageEvent#browser_compatibility"},"not supported",-1),j={key:1},I={class:"flex flex-wrap"},D={class:"absolute bottom-16 right-2"},F=e("div",{class:"mb-0 rounded-t-lg border-b border-solid bg-green-600 p-3 font-semibold uppercase text-white opacity-75"}," MIDI Status ",-1),E={class:"p-3 font-mono text-orange-900"},z={class:"mb-2 font-bold"},V={class:"mb-2"},C=e("div",{class:"font-bold"},"Inputs:",-1),B={key:0,class:"p-4 text-center italic"},K={key:1},T={class:"flex-1"},P={class:"flex-1"},U={class:"mb-2"},G=e("div",{class:"font-bold"},"Outputs:",-1),L={key:0,class:"p-4 text-center italic"},q={key:1},H={class:"flex-1"},R={class:"flex-1"},W={class:"absolute bottom-2 right-2"},Y=e("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:"0 0 20 20",class:"h-10 w-10"},[e("g",{fill:"none"},[e("path",{d:"M2.5 4a.5.5 0 0 0-.5.5v11a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5h-15zm.5 6h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v3.5a.5.5 0 0 0 1 0V10h2v5H3v-5zm2.75-2.5a.75.75 0 1 1 0-1.5a.75.75 0 0 1 0 1.5zm6.25-1a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm-3 .251a.75.75 0 1 1-1.5 0a.75.75 0 0 1 1.5 0z",fill:"currentColor"})])],-1),J=[Y],Q={class:"absolute bottom-4 left-4"},X={class:"flex"},Z={class:"grid h-screen place-items-center"},$={class:"text-center text-4xl font-semibold tracking-wide"},ee={key:0};function te(f,a,i,m,n,t){return r(),s("div",k,[typeof n.midi>"u"?(r(),s("div",N,[l(" Unfortunately, the Web MIDI API is "),S,l(" in all browsers... ")])):(r(),s("div",j,[e("div",I,[e("div",D,[e("div",{class:v([{hidden:!n.tooltip,block:n.tooltip},"z-50 max-w-md break-words rounded-lg border-2 border-green-800 bg-yellow-200 text-sm font-normal leading-normal"])},[e("div",null,[F,e("div",E,[e("div",z,[l(" Enabled: "),e("span",null,d(typeof n.midi<"u"?"Yep!":"Nope"),1)]),e("div",V,[C,t.inputs.length===0?(r(),s("div",B," No input devices detected :( ")):(r(),s("div",K,[(r(!0),s(c,null,h(t.inputs,o=>(r(),s("div",{key:o.id,class:"flex"},[e("div",T,d(o.manufacturer),1),e("div",P,d(o.name),1)]))),128))]))]),e("div",U,[G,t.outputs.length===0?(r(),s("div",L," No output devices detected :( ")):(r(),s("div",q,[(r(!0),s(c,null,h(t.outputs,o=>(r(),s("div",{key:o.id,class:"flex"},[e("div",H,d(o.manufacturer),1),e("div",R,d(o.name),1)]))),128))]))])])])],2)]),e("div",W,[e("button",{onClick:a[0]||(a[0]=o=>n.tooltip=!n.tooltip),class:"border-3 rounded-lg border-green-600 bg-green-50 px-1 text-green-600 shadow hover:text-green-500 hover:shadow-lg",type:"button"},J)])]),e("div",Q,[e("div",X,[(r(!0),s(c,null,h(t.orderedNotes(),o=>(r(),s("div",{key:o,class:"p-4"},d(o),1))),128))])]),e("div",Z,[e("div",null,[e("div",$,[b(M,{"enter-active-class":"duration-500 ease-out","enter-class":"opacity-0 transform","enter-to-class":"opacity-100","leave-active-class":"duration-500","leave-class":"opacity-100","leave-to-class":"opacity-0 transform"},{default:y(()=>[n.activeKeys.size>=1?(r(),s("div",ee,d(t.chord()||"?"),1)):g("",!0)]),_:1})])])])]))])}const se=_(A,[["render",te]]);export{se as default}; diff --git a/_nuxt/DbZb_TqQ.js b/_nuxt/CfIOX_tU.js similarity index 72% rename from _nuxt/DbZb_TqQ.js rename to _nuxt/CfIOX_tU.js index 57bf54d2..3b4d15a7 100644 --- a/_nuxt/DbZb_TqQ.js +++ b/_nuxt/CfIOX_tU.js @@ -1 +1 @@ -import{l as q,p as D,q as T,o as y,c as b,b as t,d as E,k as W,s as R,f as k,a as x,F as A,r as F,t as u}from"./D6y6W-Zj.js";const M={id:"waveform-canvas-container",class:"bg-green h-full w-full"},N=["width","height"],P={__name:"Waveform",props:{timeDomainBufferHistory:{type:Array},canvasWidth:{type:Number},canvasHeight:{type:Number},fillStyle:{type:String,default:"rgba(0,0,0)"},strokeStyle:{type:String,default:"rgb(255, 255, 255)"}},setup(f){const n=f;return q(()=>{const d=document.getElementById("waveformCanvas2"),e=d.getContext("2d"),s=document.getElementById("waveform-canvas-container"),i=n.canvasHeight?n.canvasHeight:s.clientHeight,o=n.canvasWidth?n.canvasWidth:s.clientWidth;d.height=i,d.width=o,e.fillRect(0,0,o,i),D(n.timeDomainBufferHistory,a=>{e.fillStyle=n.fillStyle,e.fillRect(0,0,o,i),e.lineWidth=2,e.strokeStyle=n.strokeStyle,e.beginPath();const h=a.slice(-1)[0],_=h.length,v=o/_;let g=0;for(let l=0;l<_;l++){const m=h[l]/128*i/2;l===0?e.moveTo(g,m):e.lineTo(g,m),g+=v}e.lineTo(d.width,d.height/2),e.stroke()})}),T(()=>{}),(d,e)=>(y(),b("div",M,[t("canvas",{id:"waveformCanvas2",width:f.canvasWidth,height:f.canvasHeight},null,8,N)]))}},U={id:"spectrogram-canvas-container",class:"h-full w-full"},O=["width","height"],C=36,G={__name:"Spectrogram",props:{frequencyDomainBufferHistory:{type:Array},canvasWidth:{type:Number},canvasHeight:{type:Number},fillStyle:{type:String,default:"rgba(0,0,0)"}},setup(f){const n=f,d=(e,s,i,o,a)=>(e-s)*(a-s)/(i-s)+o;return q(()=>{const e=document.getElementById("spectrogramCanvas"),s=e.getContext("2d"),i=document.getElementById("spectrogram-canvas-container"),o=n.canvasHeight?n.canvasHeight:i.clientHeight,a=n.canvasWidth?n.canvasWidth:i.clientWidth;e.height=o,e.width=a,s.fillRect(0,0,a,o),D(n.frequencyDomainBufferHistory,h=>{s.fillStyle=n.fillStyle,s.fillRect(0,0,a,o);const _=h.slice(-C),v=a/128,g=o/C;for(let l=0;l<128;l++)for(let c=0;c(y(),b("div",null,[t("div",U,[t("canvas",{id:"spectrogramCanvas",width:f.canvasWidth,height:f.canvasHeight},null,8,O)])]))}},L={id:"bar-graph-container",class:"h-full w-full"},V=["width","height"],I=2,Y={__name:"FrequencyBarGraph",props:{audioBufferHistory:{type:Array},canvasWidth:{type:Number},canvasHeight:{type:Number},fillStyle:{type:String,default:"rgba(0,0,0)"},strokeStyle:{type:String,default:"rgb(255, 255, 255)"}},setup(f){const n=f,d=(e,s,i,o,a)=>(e-s)*(a-s)/(i-s)+o;return q(()=>{const e=document.getElementById("frequencyBarGraphCanvas"),s=e.getContext("2d"),i=document.getElementById("bar-graph-container"),o=n.canvasHeight?n.canvasHeight:i.clientHeight,a=n.canvasWidth?n.canvasWidth:i.clientWidth;e.height=o,e.width=a,s.fillRect(0,0,a,o),D(n.audioBufferHistory,h=>{s.fillStyle=n.fillStyle,s.fillRect(0,0,a,o);const _=h.slice(-1)[0],v=a/_.length-I;let g=0;for(let l=0;l<_.length;l++){const c=_[l],m=d(c,0,255,0,o);s.fillStyle=`rgb(${c},0,${c})`,s.fillRect(g,o-m,v,m),g+=v+I}})}),(e,s)=>(y(),b("div",null,[t("div",L,[t("canvas",{id:"frequencyBarGraphCanvas",width:f.canvasWidth,height:f.canvasHeight},null,8,V)])]))}},z={class:"container mx-auto font-mono"},K={class:"bg-background text-white"},X={class:"grid grid-cols-3 gap-4"},Z={class:"col-span-3 rounded-xl bg-black/75 p-4 lg:col-span-1"},j=t("div",{class:"mb-2 text-xl font-bold"},"Time Domain Waveform",-1),J={class:"col-span-3 rounded-xl bg-black/75 p-4 lg:col-span-1"},Q=t("div",{class:"mb-2 text-xl font-bold"},"Frequency Spectrogram",-1),tt={class:"col-span-3 rounded-xl bg-black/75 p-4 lg:col-span-1"},et=t("div",{class:"mb-2 text-xl font-bold"},"Frequency Bar Chart",-1),st={class:"col-span-3 rounded-xl bg-black/75 p-4"},nt=t("div",{class:"mb-2 text-xl font-bold"},"Frequency Buffer History",-1),ot={class:"w-full table-fixed"},at=t("thead",{class:"collapse border-b-2 md:visible"},[t("tr",null,[t("th",{class:"text-left"},"Index"),t("th",{class:"text-left"},"Mean"),t("th",{class:"text-left"},"Min"),t("th",{class:"text-left"},"Max"),t("th",{class:"text-left"},"FFT"),t("th",{class:"text-right"},"Buffer")])],-1),lt={class:"text-left font-bold"},it={class:"text-left"},ct={class:"text-left"},rt={class:"text-left"},dt={class:"text-left"},ht={class:"truncate text-right"},ut={class:"col-span-3 rounded-xl bg-black/75 p-4"},ft=t("div",{class:"mb-2 text-xl font-bold"},"Time Domain Buffer History",-1),gt={class:"w-full table-fixed"},_t=t("thead",{class:"collapse border-b-2 md:visible"},[t("tr",null,[t("th",{class:"text-left"},"Index"),t("th",{class:"text-left"},"Mean"),t("th",{class:"text-left"},"Min"),t("th",{class:"text-left"},"Max"),t("th",{class:"text-left"},"FFT"),t("th",{class:"text-right"},"Buffer")])],-1),mt={class:"text-left font-bold"},vt={class:"text-left"},yt={class:"text-left"},bt={class:"text-left"},pt={class:"text-left"},xt={class:"truncate text-right"},B=256,wt=E({__name:"index",setup(f){let n=null,d=null,e=null,s=null,i=null,o=W([]),a=null,h=W([]);W(!1);const _=()=>{requestAnimationFrame(_),e.getByteTimeDomainData(i),i!==null&&(o.value.push(i.slice()),o.value.length>B&&o.value.shift()),e.getByteFrequencyData(a),a!==null&&(h.value.push(a.slice()),h.value.length>B&&h.value.shift())},v=()=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(l=>{n=l,d=new(window.AudioContext||window.webkitAudioContext),e=d.createAnalyser(),s=d.createMediaStreamSource(n),s.connect(e),e.fftSize=2048,i=new Uint8Array(e.frequencyBinCount),a=new Uint8Array(e.frequencyBinCount);for(let c=0;c{n!==null&&n.active&&n.getAudioTracks().forEach(l=>{l.stop()})};return R(()=>{console.log("disabling"),g()}),(l,c)=>{const m=P,w=G,$=Y;return y(),b("div",z,[t("div",K,[t("div",X,[t("div",{class:"col-span-3 space-x-2"},[t("div",{class:"inline-block rounded-lg bg-black px-6 py-2 text-sm font-bold uppercase text-white shadow-lg shadow-green-400/25 transition duration-150 ease-in-out hover:cursor-pointer hover:shadow-white/25",onClick:v}," Enable "),t("div",{class:"inline-block rounded-lg bg-black px-6 py-2 text-sm font-bold uppercase text-white shadow-lg shadow-red-400/25 transition duration-150 ease-in-out hover:cursor-pointer hover:shadow-white/25",onClick:g}," Disable ")]),t("div",Z,[j,k(m,{timeDomainBufferHistory:x(o),strokeStyle:"rgb(255, 0, 255)",class:"h-72 border-2 border-gray-400"},null,8,["timeDomainBufferHistory"])]),t("div",J,[Q,k(w,{frequencyDomainBufferHistory:x(h),class:"h-72 border-2 border-gray-400"},null,8,["frequencyDomainBufferHistory"])]),t("div",tt,[et,k($,{audioBufferHistory:x(h),class:"h-72 border-2 border-gray-400"},null,8,["audioBufferHistory"])]),t("div",st,[nt,t("div",null,[t("table",ot,[at,t("tbody",null,[(y(!0),b(A,null,F(x(h).slice(-10),(r,p)=>(y(),b("tr",{key:p},[t("td",lt,u(p),1),t("td",it,u((r.reduce((H,S)=>H+S)/r.length).toFixed(2)),1),t("td",ct,u(Math.min(...r)),1),t("td",rt,u(Math.max(...r)),1),t("td",dt,u(r.length),1),t("td",ht,u(r.slice(0,4))+" ... "+u(r.slice(-4)),1)]))),128))])])])]),t("div",ut,[ft,t("div",null,[t("table",gt,[_t,t("tbody",null,[(y(!0),b(A,null,F(x(o).slice(-10),(r,p)=>(y(),b("tr",{key:p},[t("td",mt,u(p),1),t("td",vt,u((r.reduce((H,S)=>H+S)/r.length).toFixed(2)),1),t("td",yt,u(Math.min(...r)),1),t("td",bt,u(Math.max(...r)),1),t("td",pt,u(r.length),1),t("td",xt,u(r.slice(0,4))+" ... "+u(r.slice(-4)),1)]))),128))])])])])])])])}}});export{wt as default}; +import{p as D,s as q,v as T,o as y,c as b,b as t,d as E,j as W,x as R,i as C,a as x,F as A,r as F,t as u}from"./YC8jgtvV.js";const M={id:"waveform-canvas-container",class:"bg-green h-full w-full"},N=["width","height"],P={__name:"Waveform",props:{timeDomainBufferHistory:{type:Array},canvasWidth:{type:Number},canvasHeight:{type:Number},fillStyle:{type:String,default:"rgba(0,0,0)"},strokeStyle:{type:String,default:"rgb(255, 255, 255)"}},setup(f){const n=f;return D(()=>{const d=document.getElementById("waveformCanvas2"),e=d.getContext("2d"),s=document.getElementById("waveform-canvas-container"),i=n.canvasHeight?n.canvasHeight:s.clientHeight,o=n.canvasWidth?n.canvasWidth:s.clientWidth;d.height=i,d.width=o,e.fillRect(0,0,o,i),q(n.timeDomainBufferHistory,a=>{e.fillStyle=n.fillStyle,e.fillRect(0,0,o,i),e.lineWidth=2,e.strokeStyle=n.strokeStyle,e.beginPath();const h=a.slice(-1)[0],_=h.length,m=o/_;let g=0;for(let l=0;l<_;l++){const v=h[l]/128*i/2;l===0?e.moveTo(g,v):e.lineTo(g,v),g+=m}e.lineTo(d.width,d.height/2),e.stroke()})}),T(()=>{}),(d,e)=>(y(),b("div",M,[t("canvas",{id:"waveformCanvas2",width:f.canvasWidth,height:f.canvasHeight},null,8,N)]))}},U={id:"spectrogram-canvas-container",class:"h-full w-full"},O=["width","height"],k=36,G={__name:"Spectrogram",props:{frequencyDomainBufferHistory:{type:Array},canvasWidth:{type:Number},canvasHeight:{type:Number},fillStyle:{type:String,default:"rgba(0,0,0)"}},setup(f){const n=f,d=(e,s,i,o,a)=>(e-s)*(a-s)/(i-s)+o;return D(()=>{const e=document.getElementById("spectrogramCanvas"),s=e.getContext("2d"),i=document.getElementById("spectrogram-canvas-container"),o=n.canvasHeight?n.canvasHeight:i.clientHeight,a=n.canvasWidth?n.canvasWidth:i.clientWidth;e.height=o,e.width=a,s.fillRect(0,0,a,o),q(n.frequencyDomainBufferHistory,h=>{s.fillStyle=n.fillStyle,s.fillRect(0,0,a,o);const _=h.slice(-k),m=a/128,g=o/k;for(let l=0;l<128;l++)for(let c=0;c(y(),b("div",null,[t("div",U,[t("canvas",{id:"spectrogramCanvas",width:f.canvasWidth,height:f.canvasHeight},null,8,O)])]))}},L={id:"bar-graph-container",class:"h-full w-full"},V=["width","height"],I=2,Y={__name:"FrequencyBarGraph",props:{audioBufferHistory:{type:Array},canvasWidth:{type:Number},canvasHeight:{type:Number},fillStyle:{type:String,default:"rgba(0,0,0)"},strokeStyle:{type:String,default:"rgb(255, 255, 255)"}},setup(f){const n=f,d=(e,s,i,o,a)=>(e-s)*(a-s)/(i-s)+o;return D(()=>{const e=document.getElementById("frequencyBarGraphCanvas"),s=e.getContext("2d"),i=document.getElementById("bar-graph-container"),o=n.canvasHeight?n.canvasHeight:i.clientHeight,a=n.canvasWidth?n.canvasWidth:i.clientWidth;e.height=o,e.width=a,s.fillRect(0,0,a,o),q(n.audioBufferHistory,h=>{s.fillStyle=n.fillStyle,s.fillRect(0,0,a,o);const _=h.slice(-1)[0],m=a/_.length-I;let g=0;for(let l=0;l<_.length;l++){const c=_[l],v=d(c,0,255,0,o);s.fillStyle=`rgb(${c},0,${c})`,s.fillRect(g,o-v,m,v),g+=m+I}})}),(e,s)=>(y(),b("div",null,[t("div",L,[t("canvas",{id:"frequencyBarGraphCanvas",width:f.canvasWidth,height:f.canvasHeight},null,8,V)])]))}},j={class:"container mx-auto font-mono"},z={class:"bg-background text-white"},K={class:"grid grid-cols-3 gap-4"},X={class:"col-span-3 rounded-xl bg-black/75 p-4 lg:col-span-1"},Z=t("div",{class:"mb-2 text-xl font-bold"},"Time Domain Waveform",-1),J={class:"col-span-3 rounded-xl bg-black/75 p-4 lg:col-span-1"},Q=t("div",{class:"mb-2 text-xl font-bold"},"Frequency Spectrogram",-1),tt={class:"col-span-3 rounded-xl bg-black/75 p-4 lg:col-span-1"},et=t("div",{class:"mb-2 text-xl font-bold"},"Frequency Bar Chart",-1),st={class:"col-span-3 rounded-xl bg-black/75 p-4"},nt=t("div",{class:"mb-2 text-xl font-bold"},"Frequency Buffer History",-1),ot={class:"w-full table-fixed"},at=t("thead",{class:"collapse border-b-2 md:visible"},[t("tr",null,[t("th",{class:"text-left"},"Index"),t("th",{class:"text-left"},"Mean"),t("th",{class:"text-left"},"Min"),t("th",{class:"text-left"},"Max"),t("th",{class:"text-left"},"FFT"),t("th",{class:"text-right"},"Buffer")])],-1),lt={class:"text-left font-bold"},it={class:"text-left"},ct={class:"text-left"},rt={class:"text-left"},dt={class:"text-left"},ht={class:"truncate text-right"},ut={class:"col-span-3 rounded-xl bg-black/75 p-4"},ft=t("div",{class:"mb-2 text-xl font-bold"},"Time Domain Buffer History",-1),gt={class:"w-full table-fixed"},_t=t("thead",{class:"collapse border-b-2 md:visible"},[t("tr",null,[t("th",{class:"text-left"},"Index"),t("th",{class:"text-left"},"Mean"),t("th",{class:"text-left"},"Min"),t("th",{class:"text-left"},"Max"),t("th",{class:"text-left"},"FFT"),t("th",{class:"text-right"},"Buffer")])],-1),vt={class:"text-left font-bold"},mt={class:"text-left"},yt={class:"text-left"},bt={class:"text-left"},pt={class:"text-left"},xt={class:"truncate text-right"},B=256,wt=E({__name:"index",setup(f){let n=null,d=null,e=null,s=null,i=null,o=W([]),a=null,h=W([]);W(!1);const _=()=>{requestAnimationFrame(_),e.getByteTimeDomainData(i),i!==null&&(o.value.push(i.slice()),o.value.length>B&&o.value.shift()),e.getByteFrequencyData(a),a!==null&&(h.value.push(a.slice()),h.value.length>B&&h.value.shift())},m=()=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(l=>{n=l,d=new(window.AudioContext||window.webkitAudioContext),e=d.createAnalyser(),s=d.createMediaStreamSource(n),s.connect(e),e.fftSize=2048,i=new Uint8Array(e.frequencyBinCount),a=new Uint8Array(e.frequencyBinCount);for(let c=0;c{n!==null&&n.active&&n.getAudioTracks().forEach(l=>{l.stop()})};return R(()=>{console.log("disabling"),g()}),(l,c)=>{const v=P,w=G,$=Y;return y(),b("div",j,[t("div",z,[t("div",K,[t("div",{class:"col-span-3 space-x-2"},[t("div",{class:"inline-block rounded-lg bg-black px-6 py-2 text-sm font-bold uppercase text-white shadow-lg shadow-green-400/25 transition duration-150 ease-in-out hover:cursor-pointer hover:shadow-white/25",onClick:m}," Enable "),t("div",{class:"inline-block rounded-lg bg-black px-6 py-2 text-sm font-bold uppercase text-white shadow-lg shadow-red-400/25 transition duration-150 ease-in-out hover:cursor-pointer hover:shadow-white/25",onClick:g}," Disable ")]),t("div",X,[Z,C(v,{timeDomainBufferHistory:x(o),strokeStyle:"rgb(255, 0, 255)",class:"h-72 border-2 border-gray-400"},null,8,["timeDomainBufferHistory"])]),t("div",J,[Q,C(w,{frequencyDomainBufferHistory:x(h),class:"h-72 border-2 border-gray-400"},null,8,["frequencyDomainBufferHistory"])]),t("div",tt,[et,C($,{audioBufferHistory:x(h),class:"h-72 border-2 border-gray-400"},null,8,["audioBufferHistory"])]),t("div",st,[nt,t("div",null,[t("table",ot,[at,t("tbody",null,[(y(!0),b(A,null,F(x(h).slice(-10),(r,p)=>(y(),b("tr",{key:p},[t("td",lt,u(p),1),t("td",it,u((r.reduce((H,S)=>H+S)/r.length).toFixed(2)),1),t("td",ct,u(Math.min(...r)),1),t("td",rt,u(Math.max(...r)),1),t("td",dt,u(r.length),1),t("td",ht,u(r.slice(0,4))+" ... "+u(r.slice(-4)),1)]))),128))])])])]),t("div",ut,[ft,t("div",null,[t("table",gt,[_t,t("tbody",null,[(y(!0),b(A,null,F(x(o).slice(-10),(r,p)=>(y(),b("tr",{key:p},[t("td",vt,u(p),1),t("td",mt,u((r.reduce((H,S)=>H+S)/r.length).toFixed(2)),1),t("td",yt,u(Math.min(...r)),1),t("td",bt,u(Math.max(...r)),1),t("td",pt,u(r.length),1),t("td",xt,u(r.slice(0,4))+" ... "+u(r.slice(-4)),1)]))),128))])])])])])])])}}});export{wt as default}; diff --git a/_nuxt/ChVNnOb8.js b/_nuxt/ChVNnOb8.js deleted file mode 100644 index 794dad04..00000000 --- a/_nuxt/ChVNnOb8.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as r,o,c as t,a7 as s}from"./D6y6W-Zj.js";const c={};function n(e,a){return o(),t("tr",null,[s(e.$slots,"default")])}const _=r(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/DQRguPdo.js b/_nuxt/Ci9WvbVQ.js similarity index 91% rename from _nuxt/DQRguPdo.js rename to _nuxt/Ci9WvbVQ.js index 2bb3d5a9..9ee9c1f6 100644 --- a/_nuxt/DQRguPdo.js +++ b/_nuxt/Ci9WvbVQ.js @@ -1 +1 @@ -import{d as f,o,c as s,b as e,e as g,h as n,f as a,g as u,F as b,r as x,t as _,i as v,w,a as y}from"./D6y6W-Zj.js";import{_ as k,a as $}from"./6h42708l.js";import{q as C}from"./ElOT_Ul4.js";import"./DvDH6DOc.js";import"./DXU4rfre.js";const D={class:"container mx-auto pb-8"},S={class:"flex flex-wrap"},A={class:"w-full"},B={class:"lg:text-normal space-y-4 font-medium tracking-wide text-white sm:text-base"},I=e("div",null,[n(" Currently, I am helping educate engineers and building the future of data orchestration at "),e("a",{class:"border-b-2 border-orange-500",target:"_blank",rel:"noopener noreferrer",href:"https://dagster.io/"},"Dagster"),n(". ")],-1),N=e("div",null,[n(" Previously, I worked at "),e("a",{class:"border-b-2 border-orange-500",target:"_blank",rel:"noopener noreferrer",href:"https://www.gemini.com/"},"Gemini"),n(" building the data platform that provided company-wide insights into the exchange and business. At Georgetown University's "),e("a",{class:"border-b-2 border-orange-500",target:"_blank",rel:"noopener noreferrer",href:"https://mccourt.georgetown.edu/research/the-massive-data-institute/"},"Massive Data Institute"),n(" building data warehousing, processing solutions, and portals to aid social scientists and researchers to leverage large-scale organic data. And previously I provided consulting for financial institutions and government agencies in the D.C. area around data practices, and identity and access management. ")],-1),P=f({__name:"AboutMe",setup(i){return(t,c)=>(o(),s("section",D,[e("div",S,[e("div",A,[e("div",B,[g("",!0),I,N])])])]))}}),L={class:"bg-gradient-to-b from-background to-transparent"},M={class:"container mx-auto space-y-4"},V={class:"mb-4 grid grid-cols-1 gap-4 md:grid-cols-2"},q={class:"space-y-4 rounded-xl bg-black bg-opacity-70 p-4 text-white drop-shadow-lg hover:ring-1 hover:ring-white"},F={class:""},G={class:"flex-1 text-lg font-bold md:text-xl"},T={key:0,class:"text-sm font-light text-gray-400"},U={class:"line-clamp-3 text-sm"},E={__name:"BlogPosts",props:{articles:[],show_dates:!1},setup(i){return(t,c)=>{const d=v,m=k;return o(),s("section",L,[e("div",M,[a(d,{to:"/articles",class:"font-mono text-3xl font-semibold text-white underline decoration-orange-500 underline-offset-4 hover:text-orange-500"},{default:u(()=>[n(" blog posts ")]),_:1}),e("div",V,[(o(!0),s(b,null,x(i.articles,(r,l)=>(o(),s("div",{key:l},[a(d,{to:r._path,external:""},{default:u(()=>[e("div",q,[e("div",F,[e("div",G,_(r.title),1),i.show_dates?(o(),s("div",T,_(new Date(r.date).toLocaleDateString("en-US",{month:"long",day:"numeric",year:"numeric"})),1)):g("",!0)]),e("div",U,_(r.description),1)])]),_:2},1032,["to"])]))),128))]),e("div",null,[a(m,{to:"/articles"})])])])}}},j={class:"bg-emerald-950 bg-[url('/images/noise.svg')]"},Q={__name:"index",async setup(i){let t,c;const d=([t,c]=w(()=>C().only(["_id","_path","title","description","date","img","author","tags"]).sort({date:-1}).limit(4).find()),t=await t,c(),t);return(m,r)=>{const l=P,h=E,p=$;return o(),s("div",null,[a(l),e("div",j,[g("",!0),a(h,{articles:y(d),show_dates:!0},null,8,["articles"]),a(p,{limit:8,showImages:"",linkToPlayground:""})])])}}};export{Q as default}; +import{d as f,o,c as s,b as e,e as g,h as n,i as a,g as u,F as b,r as x,t as _,_ as v,w,a as y}from"./YC8jgtvV.js";import{_ as k,a as $}from"./VupGr2ZG.js";import{q as C}from"./NquB2IUV.js";import"./DvDH6DOc.js";import"./JthqPOXk.js";const D={class:"container mx-auto pb-8"},S={class:"flex flex-wrap"},A={class:"w-full"},B={class:"lg:text-normal space-y-4 font-medium tracking-wide text-white sm:text-base"},I=e("div",null,[n(" Currently, I am helping educate engineers and building the future of data orchestration at "),e("a",{class:"border-b-2 border-orange-500",target:"_blank",rel:"noopener noreferrer",href:"https://dagster.io/"},"Dagster"),n(". ")],-1),N=e("div",null,[n(" Previously, I worked at "),e("a",{class:"border-b-2 border-orange-500",target:"_blank",rel:"noopener noreferrer",href:"https://www.gemini.com/"},"Gemini"),n(" building the data platform that provided company-wide insights into the exchange and business. At Georgetown University's "),e("a",{class:"border-b-2 border-orange-500",target:"_blank",rel:"noopener noreferrer",href:"https://mccourt.georgetown.edu/research/the-massive-data-institute/"},"Massive Data Institute"),n(" building data warehousing, processing solutions, and portals to aid social scientists and researchers to leverage large-scale organic data. And previously I provided consulting for financial institutions and government agencies in the D.C. area around data practices, and identity and access management. ")],-1),P=f({__name:"AboutMe",setup(i){return(t,c)=>(o(),s("section",D,[e("div",S,[e("div",A,[e("div",B,[g("",!0),I,N])])])]))}}),L={class:"bg-gradient-to-b from-background to-transparent"},M={class:"container mx-auto space-y-4"},V={class:"mb-4 grid grid-cols-1 gap-4 md:grid-cols-2"},q={class:"space-y-4 rounded-xl bg-black bg-opacity-70 p-4 text-white drop-shadow-lg hover:ring-1 hover:ring-white"},F={class:""},G={class:"flex-1 text-lg font-bold md:text-xl"},T={key:0,class:"text-sm font-light text-gray-400"},U={class:"line-clamp-3 text-sm"},E={__name:"BlogPosts",props:{articles:[],show_dates:!1},setup(i){return(t,c)=>{const d=v,m=k;return o(),s("section",L,[e("div",M,[a(d,{to:"/articles",class:"font-mono text-3xl font-semibold text-white underline decoration-orange-500 underline-offset-4 hover:text-orange-500"},{default:u(()=>[n(" blog posts ")]),_:1}),e("div",V,[(o(!0),s(b,null,x(i.articles,(r,l)=>(o(),s("div",{key:l},[a(d,{to:r._path,external:""},{default:u(()=>[e("div",q,[e("div",F,[e("div",G,_(r.title),1),i.show_dates?(o(),s("div",T,_(new Date(r.date).toLocaleDateString("en-US",{month:"long",day:"numeric",year:"numeric"})),1)):g("",!0)]),e("div",U,_(r.description),1)])]),_:2},1032,["to"])]))),128))]),e("div",null,[a(m,{to:"/articles"})])])])}}},j={class:"bg-emerald-950 bg-[url('/images/noise.svg')]"},Q={__name:"index",async setup(i){let t,c;const d=([t,c]=w(()=>C().only(["_id","_path","title","description","date","img","author","tags"]).sort({date:-1}).limit(4).find()),t=await t,c(),t);return(m,r)=>{const l=P,h=E,p=$;return o(),s("div",null,[a(l),e("div",j,[g("",!0),a(h,{articles:y(d),show_dates:!0},null,8,["articles"]),a(p,{limit:8,showImages:"",linkToPlayground:""})])])}}};export{Q as default}; diff --git a/_nuxt/Cj9zn9Hh.js b/_nuxt/Cj9zn9Hh.js new file mode 100644 index 00000000..d29620a5 --- /dev/null +++ b/_nuxt/Cj9zn9Hh.js @@ -0,0 +1 @@ +import{_ as f}from"./DuCNYxTx.js";import{d as s,s as l,I as d,K as c}from"./YC8jgtvV.js";import"./C-v3KzvZ.js";import"./Dnd51l0P.js";import"./JthqPOXk.js";import"./DvDH6DOc.js";const $=s({name:"ContentRenderer",props:{value:{type:Object,required:!1,default:()=>({})},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"}},setup(t){l(()=>t.excerpt,n=>{var e,i,a;n&&!((e=t.value)!=null&&e.excerpt)&&(console.warn(`No excerpt found for document content/${(i=t==null?void 0:t.value)==null?void 0:i._path}.${(a=t==null?void 0:t.value)==null?void 0:a._extension}!`),console.warn("Make sure to use in your content if you want to use excerpt feature."))},{immediate:!0})},render(t){var u,o;const n=d(),{value:e,excerpt:i,tag:a}=t,r=i?e==null?void 0:e.excerpt:e==null?void 0:e.body;return!((u=r==null?void 0:r.children)!=null&&u.length)&&(n!=null&&n.empty)?n.empty({value:e,excerpt:i,tag:a,...this.$attrs}):n!=null&&n.default?n.default({value:e,excerpt:i,tag:a,...this.$attrs}):(r==null?void 0:r.type)==="root"&&((o=r==null?void 0:r.children)!=null&&o.length)?c(f,{value:e,excerpt:i,tag:a,...this.$attrs}):c("pre",null,JSON.stringify({message:"You should use slots with ",value:e,excerpt:i,tag:a},null,2))}});export{$ as default}; diff --git a/_nuxt/CkwidRNk.js b/_nuxt/CkwidRNk.js deleted file mode 100644 index 98d0c7b9..00000000 --- a/_nuxt/CkwidRNk.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as x,c as o,b as t,F as d,r as _,o as l,f as g,g as p,h as f,t as a,n as u,i as v}from"./D6y6W-Zj.js";import{_ as k}from"./CNTXZiWI.js";import y from"./BLy52rwp.js";import{q as C}from"./ElOT_Ul4.js";import"./C-v3KzvZ.js";import"./DXU4rfre.js";import"./DvDH6DOc.js";const w={async setup(){return{articles:await C().only(["_id","_path","title","description","date","img","author","tags","categories","img","excerpt","summary"]).sort({date:-1}).find()}},data(){return{selected_tags:[],selected_categories:[]}},computed:{categories(){return[...new Set(this.articles.map(s=>s.categories).flat().sort())]},tags(){return[...new Set(this.articles.map(s=>s.tags).flat().sort())]},visible_articles(){return this.articles.filter(s=>!(this.selected_categories.length>0&&!this.selected_categories.every(c=>s.categories.includes(c))||this.selected_tags.length>0&&!this.selected_tags.every(c=>s.tags.includes(c))))}},methods:{toggle_tag(s){this.selected_tags.includes(s)?this.selected_tags=this.selected_tags.filter(c=>c!==s):this.selected_tags.push(s)},toggle_category(s){this.selected_categories.includes(s)?this.selected_categories=this.selected_categories.filter(c=>c!==s):this.selected_categories.push(s)}}},N={class:"container mx-auto"},B={class:"grid grid-cols-4 gap-4"},S={class:"col-span-4 lg:col-span-3"},V={class:"rounded-xl bg-black/50 text-white shadow-xl"},q={class:"relative mb-2 h-full"},F={class:"px-4 py-2"},L={class:"mb-2 text-xl font-bold"},R={class:"flex items-center text-sm"},T={class:"mb-3 px-4 pb-12"},j={class:"prose-sm"},z={class:"absolute bottom-0 right-0 mb-4"},D={class:"tag"},E={class:"col-span-4 inline-block lg:col-span-1"},M={class:"mb-3 rounded-xl bg-black/50 text-white"},A=t("p",{class:"mb-0 px-3 py-2 text-xl font-bold"},"Categories",-1),G=["onClick"],H={class:"mb-3 rounded-xl bg-black/50 text-white"},I=t("p",{class:"mb-0 px-3 py-2 text-xl font-bold"},"Tags",-1),J={class:"p-2"},K=["onClick"];function O(s,c,P,Q,r,i){const h=v,m=k,b=y;return l(),o("section",N,[t("div",B,[t("div",S,[(l(!0),o(d,null,_(i.visible_articles,e=>(l(),o("div",{key:e._id},[t("div",V,[t("div",q,[t("div",F,[t("div",L,[g(h,{class:"border-b-2 border-orange-500 hover:text-orange-500",to:e._path},{default:p(()=>[f(a(e.title),1)]),_:2},1032,["to"])]),t("p",R,a(e.date),1)]),t("div",T,[t("p",j,[g(b,{class:"prose prose-sm mx-auto sm:prose lg:prose-lg xl:prose-2xl",value:e},{default:p(()=>[g(m,{value:{body:e.excerpt}},null,8,["value"])]),_:2},1032,["value"])])]),t("div",z,[(l(!0),o(d,null,_(e.tags,n=>(l(),o("span",{key:n,class:u([{"bg-green-600":r.selected_tags.includes(n)},"mr-2 inline-block select-none bg-black px-3 py-1 text-sm text-orange-200"])},[t("div",D,a(n),1)],2))),128))])])])]))),128))]),t("div",E,[t("div",M,[A,(l(!0),o(d,null,_(i.categories,e=>(l(),o("a",{key:e,class:u([{"bg-green-600":r.selected_categories.includes(e),"hover:bg-red-600":r.selected_categories.includes(e)},"block cursor-pointer select-none border-t border-black px-4 py-1 text-orange-200 hover:bg-black"]),onClick:n=>i.toggle_category(e)},a(e),11,G))),128))]),t("div",H,[I,t("div",J,[(l(!0),o(d,null,_(i.tags,(e,n)=>(l(),o("span",{key:n,class:u([{"bg-green-600":r.selected_tags.includes(e),"hover:bg-red-600":r.selected_tags.includes(e)},"mb-2 mr-2 inline-flex h-8 cursor-pointer select-none content-center justify-center bg-black px-3 py-2 text-sm leading-4 text-orange-200"]),onClick:U=>i.toggle_tag(e)},[t("div",null,a(e),1)],10,K))),128))])])])])])}const se=x(w,[["render",O]]);export{se as default}; diff --git a/_nuxt/Clp480GU.js b/_nuxt/Clp480GU.js deleted file mode 100644 index a9e0d7cf..00000000 --- a/_nuxt/Clp480GU.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,o as r,c}from"./D6y6W-Zj.js";const o={};function t(n,s){return r(),c("hr")}const a=e(o,[["render",t]]);export{a as default}; diff --git a/_nuxt/ClxUSaue.js b/_nuxt/ClxUSaue.js new file mode 100644 index 00000000..71715168 --- /dev/null +++ b/_nuxt/ClxUSaue.js @@ -0,0 +1 @@ +import{d as p,H as f,k as i,o as t,c as s,a as u,a7 as n}from"./YC8jgtvV.js";const l=["id"],d=["href"],_=p({__name:"ProseH4",props:{id:{}},setup(r){const a=r,{headings:o}=f().public.mdc,c=i(()=>{var e;return a.id&&(typeof(o==null?void 0:o.anchorLinks)=="boolean"&&(o==null?void 0:o.anchorLinks)===!0||typeof(o==null?void 0:o.anchorLinks)=="object"&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h4))});return(e,k)=>(t(),s("h4",{id:e.id},[e.id&&u(c)?(t(),s("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,d)):n(e.$slots,"default",{key:1})],8,l))}});export{_ as default}; diff --git a/_nuxt/CmyKjUr8.js b/_nuxt/CmyKjUr8.js new file mode 100644 index 00000000..3ce19fa4 --- /dev/null +++ b/_nuxt/CmyKjUr8.js @@ -0,0 +1 @@ +import{a as o}from"./VupGr2ZG.js";import{l as c,c as n,i as t,o as a}from"./YC8jgtvV.js";const r={};function s(_,i){const e=o;return a(),n("div",null,[t(e,{showImages:""})])}const l=c(r,[["render",s]]);export{l as default}; diff --git a/_nuxt/CsmMkizg.js b/_nuxt/CsmMkizg.js deleted file mode 100644 index 443c6476..00000000 --- a/_nuxt/CsmMkizg.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as n,c as r,a7 as c}from"./D6y6W-Zj.js";const s={};function t(e,a){return n(),r("code",null,[c(e.$slots,"default")])}const _=o(s,[["render",t]]);export{_ as default}; diff --git a/_nuxt/Cuqb2hhI.js b/_nuxt/Cuqb2hhI.js new file mode 100644 index 00000000..a4804b28 --- /dev/null +++ b/_nuxt/Cuqb2hhI.js @@ -0,0 +1 @@ +import{l as o,o as r,c as s,a7 as t}from"./YC8jgtvV.js";const c={};function n(e,a){return r(),s("em",null,[t(e.$slots,"default")])}const f=o(c,[["render",n]]);export{f as default}; diff --git a/_nuxt/CvqFk8MA.js b/_nuxt/CvqFk8MA.js new file mode 100644 index 00000000..50305d74 --- /dev/null +++ b/_nuxt/CvqFk8MA.js @@ -0,0 +1 @@ +import{f as i}from"./Dnd51l0P.js";import{d as u,I as f,k as c,K as a,$ as d}from"./YC8jgtvV.js";const p=u({name:"MDCSlot",functional:!0,props:{name:{type:String,default:"default"},unwrap:{type:[Boolean,String],default:!1},use:{type:Function,default:void 0}},setup(t){const{parent:s}=d(),{default:o}=f(),r=c(()=>typeof t.unwrap=="string"?t.unwrap.split(" "):["*"]);return{fallbackSlot:o,tags:r,parent:s}},render({use:t,unwrap:s,fallbackSlot:o,tags:r,parent:e}){var l;try{let n=t;return typeof t=="string"&&(n=(e==null?void 0:e.slots[t])||((l=e==null?void 0:e.parent)==null?void 0:l.slots[t]),console.warn(`Please set :use="$slots.${t}" in component to enable reactivity`)),n?s?i(n(),r):[n()]:o?o():a("div")}catch{return a("div")}}}),g=u({props:{use:{type:Function,default:void 0},unwrap:{type:[Boolean,String],default:!1}},render(t){return a(p,t)}});export{g as default}; diff --git a/_nuxt/Cw7Lqm3I.js b/_nuxt/Cw7Lqm3I.js deleted file mode 100644 index fe1948fd..00000000 --- a/_nuxt/Cw7Lqm3I.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as s,a7 as t}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),s("em",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/CxFdcY6a.js b/_nuxt/CxFdcY6a.js new file mode 100644 index 00000000..f803ac50 --- /dev/null +++ b/_nuxt/CxFdcY6a.js @@ -0,0 +1 @@ +import{d as a,o as n,f as o,g as s,a7 as f,_ as u}from"./YC8jgtvV.js";const d=a({__name:"ProseA",props:{href:{type:String,default:""},target:{type:String,default:void 0,required:!1}},setup(e){return(t,_)=>{const r=u;return n(),o(r,{href:e.href,target:e.target},{default:s(()=>[f(t.$slots,"default")]),_:3},8,["href","target"])}}});export{d as default}; diff --git a/_nuxt/D0cw7U9Q.js b/_nuxt/D0cw7U9Q.js new file mode 100644 index 00000000..63e98b92 --- /dev/null +++ b/_nuxt/D0cw7U9Q.js @@ -0,0 +1 @@ +import{d as p,H as f,k as u,o as t,c as s,a as i,a7 as n}from"./YC8jgtvV.js";const l=["id"],d=["href"],_=p({__name:"ProseH1",props:{id:{}},setup(r){const c=r,{headings:o}=f().public.mdc,a=u(()=>{var e;return c.id&&(typeof(o==null?void 0:o.anchorLinks)=="boolean"&&(o==null?void 0:o.anchorLinks)===!0||typeof(o==null?void 0:o.anchorLinks)=="object"&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h1))});return(e,k)=>(t(),s("h1",{id:e.id},[i(a)?(t(),s("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,d)):n(e.$slots,"default",{key:1})],8,l))}});export{_ as default}; diff --git a/_nuxt/D23fXkMy.js b/_nuxt/D23fXkMy.js deleted file mode 100644 index 49fe946d..00000000 --- a/_nuxt/D23fXkMy.js +++ /dev/null @@ -1 +0,0 @@ -import{d as i,H as c,v as p,o as s,c as n,a as u,a7 as t}from"./D6y6W-Zj.js";const f=["id"],l=["href"],k=i({__name:"ProseH2",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=p(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h2)});return(e,m)=>(s(),n("h2",{id:e.id},[e.id&&u(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/DC0DmFcz.js b/_nuxt/DC0DmFcz.js deleted file mode 100644 index ffd41648..00000000 --- a/_nuxt/DC0DmFcz.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as t,a7 as a}from"./D6y6W-Zj.js";const s={};function c(e,n){return r(),t("table",null,[a(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; diff --git a/_nuxt/DGUXyVWA.js b/_nuxt/DGUXyVWA.js deleted file mode 100644 index 7b60168f..00000000 --- a/_nuxt/DGUXyVWA.js +++ /dev/null @@ -1 +0,0 @@ -import{a as d,p as w,u as y,E as D,G as H,H as g,d as S,I as _,J as b,K as p}from"./D6y6W-Zj.js";import q from"./BLy52rwp.js";import x from"./BTH0oiOj.js";import"./CNTXZiWI.js";import"./C-v3KzvZ.js";import"./DXU4rfre.js";import"./DvDH6DOc.js";import"./T8qFVnUA.js";import"./ElOT_Ul4.js";const a=(u,s=y())=>{const e=d(u),f=g();w(()=>d(u),(n=e)=>{if(!s.path||!n)return;const t=Object.assign({},(n==null?void 0:n.head)||{});t.meta=[...t.meta||[]],t.link=[...t.link||[]];const r=t.title||(n==null?void 0:n.title);r&&(t.title=r),f.public.content.host;const c=(t==null?void 0:t.description)||(n==null?void 0:n.description);c&&t.meta.filter(l=>l.name==="description").length===0&&t.meta.push({name:"description",content:c}),t!=null&&t.image||(n==null||n.image),D(()=>H(t))},{immediate:!0})},$=S({name:"ContentDoc",props:{tag:{type:String,required:!1,default:"div"},excerpt:{type:Boolean,default:!1},path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0},head:{type:Boolean,required:!1,default:void 0}},render(u){const{contentHead:s}=g().public.content,e=_(),{tag:f,excerpt:m,path:n,query:t,head:r}=u,c=r===void 0?s:r,l={...t||{},path:n||(t==null?void 0:t.path)||b(y().path),find:"one"},C=(o,i)=>p("pre",null,JSON.stringify({message:"You should use slots with ",slot:o,data:i},null,2));return p(x,l,{default:e!=null&&e.default?({data:o,refresh:i,isPartial:v})=>{var h;return c&&a(o),(h=e.default)==null?void 0:h.call(e,{doc:o,refresh:i,isPartial:v,excerpt:m,...this.$attrs})}:({data:o})=>(c&&a(o),p(q,{value:o,excerpt:m,tag:f,...this.$attrs},{empty:i=>e!=null&&e.empty?e.empty(i):C("default",o)})),empty:o=>{var i;return((i=e==null?void 0:e.empty)==null?void 0:i.call(e,o))||p("p",null,"Document is empty, overwrite this content with #empty slot in .")},"not-found":o=>{var i;return((i=e==null?void 0:e["not-found"])==null?void 0:i.call(e,o))||p("p",null,"Document not found, overwrite this content with #not-found slot in .")}})}}),E=$;export{E as default}; diff --git a/_nuxt/DHgolSFm.js b/_nuxt/DHgolSFm.js deleted file mode 100644 index 095df7dc..00000000 --- a/_nuxt/DHgolSFm.js +++ /dev/null @@ -1 +0,0 @@ -import{d as p,I as m,v as A,K as l,$ as w}from"./D6y6W-Zj.js";const S=["p","h1","h2","h3","h4","h5","h6","li"];function f(r,t){return r.type===t||typeof r.type=="object"&&r.type.tag===t||r.tag===t}function s(r){return f(r,"text")||f(r,Symbol.for("v-txt"))}function y(r){var t;return Array.isArray(r.children)||typeof r.children=="string"?r.children:typeof((t=r.children)==null?void 0:t.default)=="function"?r.children.default():[]}function a(r){if(!r)return"";if(Array.isArray(r))return r.map(a).join("");if(s(r))return r.children||r.value||"";const t=y(r);return Array.isArray(t)?t.map(a).filter(Boolean).join(""):""}function c(r,t=[]){if(Array.isArray(r))return r.flatMap(n=>c(n,t));let e=r;return t.some(n=>n==="*"||f(r,n))&&(e=y(r)||r,!Array.isArray(e)&&S.some(n=>f(r,n))&&(e=[e])),e}function h(r,t=[]){return r=Array.isArray(r)?r:[r],t.length?r.flatMap(e=>h(c(e,[t[0]]),t.slice(1))).filter(e=>!(s(e)&&a(e).trim()==="")):r}function g(r,t=[]){return typeof t=="string"&&(t=t.split(",").map(e=>e.trim()).filter(Boolean)),t.length?h(r,t).reduce((e,n)=>(s(n)?typeof e[e.length-1]=="string"?e[e.length-1]+=n.children:e.push(n.children):e.push(n),e),[]):r}const C=p({name:"MDCSlot",functional:!0,props:{name:{type:String,default:"default"},unwrap:{type:[Boolean,String],default:!1},use:{type:Function,default:void 0}},setup(r){const{parent:t}=w(),{default:e}=m(),n=A(()=>typeof r.unwrap=="string"?r.unwrap.split(" "):["*"]);return{fallbackSlot:e,tags:n,parent:t}},render({use:r,unwrap:t,fallbackSlot:e,tags:n,parent:i}){var o;try{let u=r;return typeof r=="string"&&(u=(i==null?void 0:i.slots[r])||((o=i==null?void 0:i.parent)==null?void 0:o.slots[r]),console.warn(`Please set :use="$slots.${r}" in component to enable reactivity`)),u?t?g(u(),n):[u()]:e?e():l("div")}catch{return l("div")}}}),_=p({props:{use:{type:Function,default:void 0},unwrap:{type:[Boolean,String],default:!1}},render(r){return l(C,r)}});export{_ as default}; diff --git a/_nuxt/EoZQkp_H.js b/_nuxt/DNWUxvYV.js similarity index 78% rename from _nuxt/EoZQkp_H.js rename to _nuxt/DNWUxvYV.js index 4c584cc6..7e1fb85c 100644 --- a/_nuxt/EoZQkp_H.js +++ b/_nuxt/DNWUxvYV.js @@ -1 +1 @@ -import{c as e,o as t,b as o}from"./D6y6W-Zj.js";const s={class:"flex h-[768px] justify-center border-2 border-gray-500"},r=o("iframe",{src:"https://simple-tempo.com",width:"100%",height:"100%"},null,-1),c=[r],i={__name:"metronome",setup(a){return(n,_)=>(t(),e("main",s,c))}};export{i as default}; +import{c as e,o as t,b as o}from"./YC8jgtvV.js";const s={class:"flex h-[768px] justify-center border-2 border-gray-500"},r=o("iframe",{src:"https://simple-tempo.com",width:"100%",height:"100%"},null,-1),c=[r],i={__name:"metronome",setup(a){return(n,_)=>(t(),e("main",s,c))}};export{i as default}; diff --git a/_nuxt/DO0L514y.js b/_nuxt/DO0L514y.js new file mode 100644 index 00000000..fe7e95ba --- /dev/null +++ b/_nuxt/DO0L514y.js @@ -0,0 +1 @@ +import{l as o,o as t,c,a7 as r}from"./YC8jgtvV.js";const s={};function l(e,n){return t(),c("blockquote",null,[r(e.$slots,"default")])}const f=o(s,[["render",l]]);export{f as default}; diff --git a/_nuxt/DQnJMeWU.js b/_nuxt/DQnJMeWU.js deleted file mode 100644 index 9a1dd2ec..00000000 --- a/_nuxt/DQnJMeWU.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as m}from"./C7cmTvz1.js";import"./D6y6W-Zj.js";export{m as default}; diff --git a/_nuxt/igSZO63y.js b/_nuxt/DRDFsaxg.js similarity index 72% rename from _nuxt/igSZO63y.js rename to _nuxt/DRDFsaxg.js index e06ecf77..b6269254 100644 --- a/_nuxt/igSZO63y.js +++ b/_nuxt/DRDFsaxg.js @@ -1 +1 @@ -import{d as o,a as s,o as n,c as r,h as e,e as a,b as t}from"./D6y6W-Zj.js";const c={key:0},i=t("code",null,"script",-1),d=t("code",null,"ProseScript",-1),f=o({__name:"ProseScript",props:{src:{type:String,default:""}},setup(l){return(_,m)=>s(!1)?(n(),r("div",c,[e(" Rendering the "),i,e(" element is dangerous and is disabled by default. Consider implementing your own "),d,e(" element to have control over script rendering. ")])):a("",!0)}});export{f as default}; +import{d as o,a as s,o as n,c as r,h as e,e as a,b as t}from"./YC8jgtvV.js";const c={key:0},i=t("code",null,"script",-1),d=t("code",null,"ProseScript",-1),f=o({__name:"ProseScript",props:{src:{type:String,default:""}},setup(l){return(_,m)=>s(!1)?(n(),r("div",c,[e(" Rendering the "),i,e(" element is dangerous and is disabled by default. Consider implementing your own "),d,e(" element to have control over script rendering. ")])):a("",!0)}});export{f as default}; diff --git a/_nuxt/DYKfhnuI.js b/_nuxt/DYKfhnuI.js new file mode 100644 index 00000000..f29cddeb --- /dev/null +++ b/_nuxt/DYKfhnuI.js @@ -0,0 +1 @@ +import{l as o,o as r,c as s,a7 as t}from"./YC8jgtvV.js";const c={};function n(e,a){return r(),s("li",null,[t(e.$slots,"default")])}const f=o(c,[["render",n]]);export{f as default}; diff --git a/_nuxt/DZjQgdbh.js b/_nuxt/DZjQgdbh.js deleted file mode 100644 index 0f829cb8..00000000 --- a/_nuxt/DZjQgdbh.js +++ /dev/null @@ -1 +0,0 @@ -import r from"./DHgolSFm.js";import{d as o,I as u,v as f,$ as c}from"./D6y6W-Zj.js";const i=o({name:"Markdown",extends:r,setup(t){const{parent:e}=c(),{between:n,default:a}=u(),s=f(()=>typeof t.unwrap=="string"?t.unwrap.split(" "):["*"]);return{fallbackSlot:a,tags:s,between:n,parent:e}}});export{i as default}; diff --git a/_nuxt/T8qFVnUA.js b/_nuxt/DjmxGRUG.js similarity index 84% rename from _nuxt/T8qFVnUA.js rename to _nuxt/DjmxGRUG.js index 2918778f..87e54ef5 100644 --- a/_nuxt/T8qFVnUA.js +++ b/_nuxt/DjmxGRUG.js @@ -1 +1 @@ -import{V as C,k as y,W as w,M as b,X as O,s as B,p as M,Y as _,N as E,Z as H,a as R,$ as S,a0 as z}from"./D6y6W-Zj.js";const N=s=>s==="defer"||s===!1;function F(...s){var m;const i=typeof s[s.length-1]=="string"?s.pop():void 0;typeof s[0]!="string"&&s.unshift(i);let[t,u,a={}]=s;if(typeof t!="string")throw new TypeError("[nuxt] [asyncData] key must be a string.");if(typeof u!="function")throw new TypeError("[nuxt] [asyncData] handler must be a function.");const e=E(),v=u,p=()=>null,g=()=>e.isHydrating?e.payload.data[t]:e.static.data[t];a.server=a.server??!0,a.default=a.default??p,a.getCachedData=a.getCachedData??g,a.lazy=a.lazy??!1,a.immediate=a.immediate??!0,a.deep=a.deep??C.deep,a.dedupe=a.dedupe??"cancel";const d=()=>a.getCachedData(t,e)!=null;if(!e._asyncData[t]||!a.immediate){(m=e.payload._errors)[t]??(m[t]=null);const o=a.deep?y:w;e._asyncData[t]={data:o(a.getCachedData(t,e)??a.default()),pending:y(!d()),error:b(e.payload._errors,t),status:y("idle")}}const r={...e._asyncData[t]};r.refresh=r.execute=(o={})=>{if(e._asyncDataPromises[t]){if(N(o.dedupe??a.dedupe))return e._asyncDataPromises[t];e._asyncDataPromises[t].cancelled=!0}if((o._initial||e.isHydrating&&o._initial!==!1)&&d())return Promise.resolve(a.getCachedData(t,e));r.pending.value=!0,r.status.value="pending";const l=new Promise((c,n)=>{try{c(v(e))}catch(f){n(f)}}).then(async c=>{if(l.cancelled)return e._asyncDataPromises[t];let n=c;a.transform&&(n=await a.transform(c)),a.pick&&(n=K(n,a.pick)),e.payload.data[t]=n,r.data.value=n,r.error.value=null,r.status.value="success"}).catch(c=>{if(l.cancelled)return e._asyncDataPromises[t];r.error.value=H(c),r.data.value=R(a.default()),r.status.value="error"}).finally(()=>{l.cancelled||(r.pending.value=!1,delete e._asyncDataPromises[t])});return e._asyncDataPromises[t]=l,e._asyncDataPromises[t]},r.clear=()=>j(e,t);const D=()=>r.refresh({_initial:!0}),P=a.server!==!1&&e.payload.serverRendered;{const o=S();if(o&&!o._nuxtOnBeforeMountCbs){o._nuxtOnBeforeMountCbs=[];const n=o._nuxtOnBeforeMountCbs;O(()=>{n.forEach(f=>{f()}),n.splice(0,n.length)}),B(()=>n.splice(0,n.length))}P&&e.isHydrating&&(r.error.value||d())?(r.pending.value=!1,r.status.value=r.error.value?"error":"success"):o&&(e.payload.serverRendered&&e.isHydrating||a.lazy)&&a.immediate?o._nuxtOnBeforeMountCbs.push(D):a.immediate&&D();const l=z();if(a.watch){const n=M(a.watch,()=>r.refresh());l&&_(n)}const c=e.hook("app:data:refresh",async n=>{(!n||n.includes(t))&&await r.refresh()});l&&_(c)}const h=Promise.resolve(e._asyncDataPromises[t]).then(()=>r);return Object.assign(h,r),h}function j(s,i){i in s.payload.data&&(s.payload.data[i]=void 0),i in s.payload._errors&&(s.payload._errors[i]=null),s._asyncData[i]&&(s._asyncData[i].data.value=void 0,s._asyncData[i].error.value=null,s._asyncData[i].pending.value=!1,s._asyncData[i].status.value="idle"),i in s._asyncDataPromises&&(s._asyncDataPromises[i].cancelled=!0,s._asyncDataPromises[i]=void 0)}function K(s,i){const t={};for(const u of i)t[u]=s[u];return t}export{F as u}; +import{V as C,j as y,W as w,M as b,X as O,x as B,s as M,Y as _,N as E,Z as H,a as R,$ as S,a0 as j}from"./YC8jgtvV.js";const z=s=>s==="defer"||s===!1;function x(...s){var m;const i=typeof s[s.length-1]=="string"?s.pop():void 0;typeof s[0]!="string"&&s.unshift(i);let[t,u,a={}]=s;if(typeof t!="string")throw new TypeError("[nuxt] [asyncData] key must be a string.");if(typeof u!="function")throw new TypeError("[nuxt] [asyncData] handler must be a function.");const e=E(),v=u,p=()=>null,g=()=>e.isHydrating?e.payload.data[t]:e.static.data[t];a.server=a.server??!0,a.default=a.default??p,a.getCachedData=a.getCachedData??g,a.lazy=a.lazy??!1,a.immediate=a.immediate??!0,a.deep=a.deep??C.deep,a.dedupe=a.dedupe??"cancel";const d=()=>a.getCachedData(t,e)!=null;if(!e._asyncData[t]||!a.immediate){(m=e.payload._errors)[t]??(m[t]=null);const o=a.deep?y:w;e._asyncData[t]={data:o(a.getCachedData(t,e)??a.default()),pending:y(!d()),error:b(e.payload._errors,t),status:y("idle")}}const r={...e._asyncData[t]};r.refresh=r.execute=(o={})=>{if(e._asyncDataPromises[t]){if(z(o.dedupe??a.dedupe))return e._asyncDataPromises[t];e._asyncDataPromises[t].cancelled=!0}if((o._initial||e.isHydrating&&o._initial!==!1)&&d())return Promise.resolve(a.getCachedData(t,e));r.pending.value=!0,r.status.value="pending";const l=new Promise((c,n)=>{try{c(v(e))}catch(f){n(f)}}).then(async c=>{if(l.cancelled)return e._asyncDataPromises[t];let n=c;a.transform&&(n=await a.transform(c)),a.pick&&(n=K(n,a.pick)),e.payload.data[t]=n,r.data.value=n,r.error.value=null,r.status.value="success"}).catch(c=>{if(l.cancelled)return e._asyncDataPromises[t];r.error.value=H(c),r.data.value=R(a.default()),r.status.value="error"}).finally(()=>{l.cancelled||(r.pending.value=!1,delete e._asyncDataPromises[t])});return e._asyncDataPromises[t]=l,e._asyncDataPromises[t]},r.clear=()=>N(e,t);const D=()=>r.refresh({_initial:!0}),P=a.server!==!1&&e.payload.serverRendered;{const o=S();if(o&&!o._nuxtOnBeforeMountCbs){o._nuxtOnBeforeMountCbs=[];const n=o._nuxtOnBeforeMountCbs;O(()=>{n.forEach(f=>{f()}),n.splice(0,n.length)}),B(()=>n.splice(0,n.length))}P&&e.isHydrating&&(r.error.value||d())?(r.pending.value=!1,r.status.value=r.error.value?"error":"success"):o&&(e.payload.serverRendered&&e.isHydrating||a.lazy)&&a.immediate?o._nuxtOnBeforeMountCbs.push(D):a.immediate&&D();const l=j();if(a.watch){const n=M(a.watch,()=>r.refresh());l&&_(n)}const c=e.hook("app:data:refresh",async n=>{(!n||n.includes(t))&&await r.refresh()});l&&_(c)}const h=Promise.resolve(e._asyncDataPromises[t]).then(()=>r);return Object.assign(h,r),h}function N(s,i){i in s.payload.data&&(s.payload.data[i]=void 0),i in s.payload._errors&&(s.payload._errors[i]=null),s._asyncData[i]&&(s._asyncData[i].data.value=void 0,s._asyncData[i].error.value=null,s._asyncData[i].pending.value=!1,s._asyncData[i].status.value="idle"),i in s._asyncDataPromises&&(s._asyncDataPromises[i].cancelled=!0,s._asyncDataPromises[i]=void 0)}function K(s,i){const t={};for(const u of i)t[u]=s[u];return t}export{x as u}; diff --git a/_nuxt/DkUCuJrl.js b/_nuxt/DkUCuJrl.js new file mode 100644 index 00000000..28d374ab --- /dev/null +++ b/_nuxt/DkUCuJrl.js @@ -0,0 +1 @@ +import{d as p,H as f,k as i,o as t,c as s,a as u,a7 as n}from"./YC8jgtvV.js";const l=["id"],d=["href"],_=p({__name:"ProseH6",props:{id:{}},setup(r){const a=r,{headings:o}=f().public.mdc,c=i(()=>{var e;return a.id&&(typeof(o==null?void 0:o.anchorLinks)=="boolean"&&(o==null?void 0:o.anchorLinks)===!0||typeof(o==null?void 0:o.anchorLinks)=="object"&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h6))});return(e,k)=>(t(),s("h6",{id:e.id},[e.id&&u(c)?(t(),s("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,d)):n(e.$slots,"default",{key:1})],8,l))}});export{_ as default}; diff --git a/_nuxt/DmPqpNC_.js b/_nuxt/DmPqpNC_.js deleted file mode 100644 index b36b1785..00000000 --- a/_nuxt/DmPqpNC_.js +++ /dev/null @@ -1 +0,0 @@ -import{d as c,H as i,v as p,o as s,c as t,a as u,a7 as n}from"./D6y6W-Zj.js";const f=["id"],l=["href"],_=c({__name:"ProseH1",props:{id:{}},setup(a){const r=a,{headings:o}=i().public.mdc,d=p(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h1)});return(e,m)=>(s(),t("h1",{id:e.id},[u(d)?(s(),t("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,l)):n(e.$slots,"default",{key:1})],8,f))}});export{_ as default}; diff --git a/_nuxt/Dnd51l0P.js b/_nuxt/Dnd51l0P.js new file mode 100644 index 00000000..64cd7557 --- /dev/null +++ b/_nuxt/Dnd51l0P.js @@ -0,0 +1 @@ +const y=["p","h1","h2","h3","h4","h5","h6","li"];function f(r,t){return r.type===t||typeof r.type=="object"&&r.type.tag===t||r.tag===t}function u(r){return f(r,"text")||f(r,Symbol.for("v-txt"))}function l(r){var t;return Array.isArray(r.children)||typeof r.children=="string"?r.children:typeof((t=r.children)==null?void 0:t.default)=="function"?r.children.default():[]}function n(r){if(!r)return"";if(Array.isArray(r))return r.map(n).join("");if(u(r))return r.children||r.value||"";const t=l(r);return Array.isArray(t)?t.map(n).filter(Boolean).join(""):""}function h(r,t=[]){if(Array.isArray(r))return r.flatMap(e=>h(e,t));let i=r;return t.some(e=>e==="*"||f(r,e))&&(i=l(r)||r,!Array.isArray(i)&&y.some(e=>f(r,e))&&(i=[i])),i}function p(r,t=[]){return r=Array.isArray(r)?r:[r],t.length?r.flatMap(i=>p(h(i,[t[0]]),t.slice(1))).filter(i=>!(u(i)&&n(i).trim()==="")):r}function a(r,t=[]){return typeof t=="string"&&(t=t.split(",").map(i=>i.trim()).filter(Boolean)),t.length?p(r,t).reduce((i,e)=>(u(e)?typeof i[i.length-1]=="string"?i[i.length-1]+=e.children:i.push(e.children):i.push(e),i),[]):r}export{a as f}; diff --git a/_nuxt/Drhxu60M.js b/_nuxt/Drhxu60M.js deleted file mode 100644 index f8efee8b..00000000 --- a/_nuxt/Drhxu60M.js +++ /dev/null @@ -1 +0,0 @@ -import{a as o}from"./6h42708l.js";import{_ as c,c as n,f as t,o as a}from"./D6y6W-Zj.js";const r={};function s(_,f){const e=o;return a(),n("div",null,[t(e,{showImages:""})])}const d=c(r,[["render",s]]);export{d as default}; diff --git a/_nuxt/DuCNYxTx.js b/_nuxt/DuCNYxTx.js new file mode 100644 index 00000000..928e8b03 --- /dev/null +++ b/_nuxt/DuCNYxTx.js @@ -0,0 +1 @@ +import{d as F,$ as ln,a1 as en,k as w,K as D,a2 as on,a3 as P,a4 as tn,a5 as rn,o as an,f as un,a as sn}from"./YC8jgtvV.js";import{p as H,k as cn}from"./C-v3KzvZ.js";import{f as pn}from"./Dnd51l0P.js";import{u as dn}from"./JthqPOXk.js";class S{constructor(l,o,t){this.property=l,this.normal=o,t&&(this.space=t)}}S.prototype.property={};S.prototype.normal={};S.prototype.space=null;function V(n,l){const o={},t={};let r=-1;for(;++r4&&o.slice(0,4)==="data"&&yn.test(l)){if(l.charAt(4)==="-"){const a=l.slice(5).replace(j,Cn);t="data"+a.charAt(0).toUpperCase()+a.slice(1)}else{const a=l.slice(4);if(!j.test(a)){let i=a.replace(vn,kn);i.charAt(0)!=="-"&&(i="-"+i),l="data"+i}}r=E}return new r(t,l)}function kn(n){return"-"+n.toLowerCase()}function Cn(n){return n.charAt(1).toUpperCase()}const Sn=V([K,q,Y,$,fn],"html");V([K,q,Y,$,mn],"svg");const B=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"],T="default",Z=/^@|^v-on:/,J=/^:|^v-bind:/,G=/^v-model/,xn=["select","textarea","input"],wn=Object.fromEntries(["p","a","blockquote","code","pre","code","em","h1","h2","h3","h4","h5","h6","hr","img","ul","ol","li","strong","table","thead","tbody","td","th","tr","script"].map(n=>[n,`prose-${n}`])),Pn=F({name:"MDCRenderer",props:{body:{type:Object,required:!0},data:{type:Object,default:()=>({})},class:{type:[String,Object],default:void 0},tag:{type:[String,Boolean],default:void 0},prose:{type:Boolean,default:void 0},components:{type:Object,default:()=>({})},unwrap:{type:[Boolean,String],default:!1}},async setup(n){var i,s,c,h,f,p,y,z;const l=(c=(s=(i=ln())==null?void 0:i.appContext)==null?void 0:s.app)==null?void 0:c.$nuxt,o=(l==null?void 0:l.$route)||(l==null?void 0:l._route),{mdc:t}=((h=l==null?void 0:l.$config)==null?void 0:h.public)||{},r={...(f=t==null?void 0:t.components)!=null&&f.prose&&n.prose!==!1?wn:{},...((p=t==null?void 0:t.components)==null?void 0:p.map)||{},...en(((z=(y=n.data)==null?void 0:y.mdc)==null?void 0:z.components)||{}),...n.components},a=w(()=>{var _;const nn=(((_=n.body)==null?void 0:_.children)||[]).map(x=>x.tag||x.type).filter(x=>!B.includes(x));return Array.from(new Set(nn)).sort().join(".")});return await zn(n.body,{tags:r}),{tags:r,contentKey:a,route:o}},render(n){var p,y;const{tags:l,tag:o,body:t,data:r,contentKey:a,route:i,unwrap:s}=n;if(!t)return null;const c={...r,tags:l,$route:i},h=o!==!1?U(o||((p=c.component)==null?void 0:p.name)||c.component||"div"):void 0;return h?D(h,{...(y=c.component)==null?void 0:y.props,class:n.class,...this.$attrs,key:a},{default:f}):f==null?void 0:f();function f(){return s?pn(A(t,D,c,c).default(),typeof s=="string"?s.split(" "):["*"]):A(t,D,c,c).default()}}});function On(n,l,o,t={}){if(n.type==="text")return l(P,n.value);if(n.type==="comment")return l(tn,null,n.value);const r=n.tag,a=Q(n,o.tags);if(n.tag==="binding")return Dn(n,l,o,t);const i=U(a);typeof i=="object"&&(i.tag=r);const s=Ln(n,o);return l(i,s,A(n,l,o,{...t,...s}))}function Dn(n,l,o,t={}){var h,f;const r={...t,$document:o,$doc:o},a=/\.|\[(\d+)\]/,s=((h=n.props)==null?void 0:h.value.trim().split(a).filter(Boolean)).reduce((p,y)=>{if(p&&y in p)return typeof p[y]=="function"?p[y]():p[y]},r),c=(f=n.props)==null?void 0:f.defaultValue;return l(P,s??c??"")}function A(n,l,o,t){const a=(n.children||[]).reduce((s,c)=>{if(!Bn(c))return s[T].push(c),s;const h=En(c);return s[h]=s[h]||[],c.type==="element"&&s[h].push(...c.children||[]),s},{[T]:[]});return Object.entries(a).reduce((s,[c,h])=>(h.length&&(s[c]=()=>{const f=h.map(p=>On(p,l,o,t));return Un(f)}),s),{})}function Ln(n,l){const{tag:o="",props:t={}}=n;return Object.keys(t).reduce(function(r,a){if(a==="__ignoreMap")return r;const i=t[a];if(G.test(a)&&!xn.includes(o))return Mn(a,i,r,l);if(a==="v-bind")return Rn(a,i,r,l);if(Z.test(a))return Tn(a,i,r,l);if(J.test(a))return An(a,i,r,l);const{attribute:s}=bn(Sn,a);return Array.isArray(i)&&i.every(c=>typeof c=="string")?(r[s]=i.join(" "),r):(r[s]=i,r)},{})}function Mn(n,l,o,t){const r=p=>+p,a=p=>p.trim(),i=p=>p,s=n.replace(G,"").split(".").filter(p=>p).reduce((p,y)=>(p[y]=!0,p),{}),c="value",h=s.lazy?"change":"input",f=s.number?r:s.trim?a:i;return o[c]=O(l,t),o.on=o.on||{},o.on[h]=p=>t[l]=f(p),o}function Rn(n,l,o,t){const r=O(l,t);return o=Object.assign(o,r),o}function Tn(n,l,o,t){return n=n.replace(Z,""),o.on=o.on||{},o.on[n]=()=>O(l,t),o}function An(n,l,o,t){return n=n.replace(J,""),o[n]=O(l,t),o}const U=n=>{if(!B.includes(n)&&!(n!=null&&n.render)&&!(n!=null&&n.ssrRender)){const l=on(H(n),!1);if(typeof l=="object")return l}return n};function O(n,l){const o=n.split(".").reduce((t,r)=>typeof t=="object"?t[r]:void 0,l);return typeof o>"u"?rn(n):o}function En(n){let l="";for(const o of Object.keys(n.props||{}))if(!(!o.startsWith("#")&&!o.startsWith("v-slot:"))){l=o.split(/[:#]/,2)[1];break}return l||T}function Bn(n){return n.tag==="template"}function Un(n){const l=[];for(const o of n){const t=l[l.length-1];o.type===P&&(t==null?void 0:t.type)===P?t.children=t.children+o.children:l.push(o)}return l}async function zn(n,l){if(!n)return;const o=Array.from(new Set(t(n,l)));await Promise.all(o.map(async r=>{if(r!=null&&r.render||r!=null&&r.ssrRender||r!=null&&r.__ssrInlineRender)return;const a=U(r);a!=null&&a.__asyncLoader&&!a.__asyncResolved&&await a.__asyncLoader()}));function t(r,a){const i=r.tag;if(r.type==="text"||i==="binding"||r.type==="comment")return[];const s=Q(r,a.tags),c=[];r.type!=="root"&&!B.includes(s)&&c.push(s);for(const h of r.children||[])c.push(...t(h,a));return c}}function Q(n,l){var t;const o=n.tag;return!o||typeof((t=n.props)==null?void 0:t.__ignoreMap)<"u"?o:l[o]||l[H(o)]||l[cn(n.tag)]||o}const _n=Pn,Vn=F({__name:"ContentRendererMarkdown",props:{value:{type:Object,required:!0},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"},components:{type:Object,default:()=>({})},data:{type:Object,default:()=>({})}},setup(n){const l=n,o=dn().isEnabled(),t=w(()=>{let i=l.value.body||l.value;return l.excerpt&&l.value.excerpt&&(i=l.value.excerpt),i}),r=w(()=>{const{body:i,excerpt:s,...c}=l.value;return{...c,...l.data}}),a=w(()=>({...l.components,...r.value._components||{}}));return(i,s)=>{const c=_n;return an(),un(c,{body:t.value,data:r.value,tag:n.tag,components:a.value,"data-content-id":sn(o)?n.value._id:void 0},null,8,["body","data","tag","components","data-content-id"])}}});export{Vn as _}; diff --git a/_nuxt/DyDTWd_r.js b/_nuxt/DyDTWd_r.js deleted file mode 100644 index 497c97aa..00000000 --- a/_nuxt/DyDTWd_r.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as t,a7 as a}from"./D6y6W-Zj.js";const s={};function c(e,n){return r(),t("thead",null,[a(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; diff --git a/_nuxt/DyabY-Dr.js b/_nuxt/DyabY-Dr.js deleted file mode 100644 index b82a75f6..00000000 --- a/_nuxt/DyabY-Dr.js +++ /dev/null @@ -1 +0,0 @@ -import{d as i,H as c,v as p,o as s,c as n,a as u,a7 as t}from"./D6y6W-Zj.js";const f=["id"],l=["href"],k=i({__name:"ProseH3",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=p(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h3)});return(e,m)=>(s(),n("h3",{id:e.id},[e.id&&u(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/DzpNuskE.js b/_nuxt/DzpNuskE.js new file mode 100644 index 00000000..de8c2b1f --- /dev/null +++ b/_nuxt/DzpNuskE.js @@ -0,0 +1 @@ +import{l as o,o as r,c as t,a7 as s}from"./YC8jgtvV.js";const c={};function n(e,a){return r(),t("td",null,[s(e.$slots,"default")])}const d=o(c,[["render",n]]);export{d as default}; diff --git a/_nuxt/tdBs6IZL.js b/_nuxt/Dzt8DsnY.js similarity index 99% rename from _nuxt/tdBs6IZL.js rename to _nuxt/Dzt8DsnY.js index acc9e0ce..2a41ea56 100644 --- a/_nuxt/tdBs6IZL.js +++ b/_nuxt/Dzt8DsnY.js @@ -1 +1 @@ -import{_ as w,o as c,c as h,j as y,k as n,l as _,a as s,n as v,f as u,e as p,b as t,t as i,F as x}from"./D6y6W-Zj.js";const V={},k={version:"1.1",id:"Layer_1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",x:"0px",y:"0px",viewBox:"0 0 1160 1160","enable-background":"new 0 0 1160 1160","xml:space":"preserve"},H=y('',2),M=[H];function S(o,r){return c(),h("svg",k,M)}const C=w(V,[["render",S]]),P=window.setInterval,z={class:"bg-slate-800"},B={class:"flex h-screen items-center justify-center"},j={class:"mb-4 space-y-2 text-sm"},F=t("div",{class:"flex items-center"},[t("div",{class:"flex-none pr-2"},"Name"),t("div",{class:"flex-grow border-b border-dotted"}),t("div",{class:"flex-none pl-2"},"Colton")],-1),N={class:"flex items-center"},W=t("div",{class:"flex-none pr-2"},"Profession",-1),$=t("div",{class:"flex-grow border-b border-dotted"},null,-1),A={class:"flex-none pl-2"},I={class:"flex items-center"},D=t("div",{class:"flex-none pr-2"},"Hobby",-1),E=t("div",{class:"flex-grow border-b border-dotted"},null,-1),L={class:"flex-none pl-2"},R="TL;DR",Z={__name:"card",setup(o){const r=n(!1),a=n(0),l=n(0),f=(e,g)=>e[g%e.length];_(()=>{P(function(){a.value>l.value?l.value+=1:a.value+=1},1500)});const m=["Skydiving","Bungee jumping","Rock climbing","White water rafting","Paragliding","Scuba diving","Base jumping","Mountain biking","Surfing","Snowboarding","Wakeboarding","Motorsports","Parkour","Zip-lining","Off-roading","Cave diving","Kiteboarding","Hang gliding","Free solo climbing","Bull riding","Ice climbing","Wing suit flying","Extreme skiing","Cliff jumping","Cave exploring"],d=["Astronaut","Archaeologist","Professional athlete","Chef","Fashion designer","Film director","Investigative journalist","Marine biologist","Musician","Photographer","Pilot","Professional gamer","Professor","Sculptor","Spy","Stand-up comedian","Surfing instructor","Travel writer","Wildlife photographer","Wine connoisseur","Yacht captain","Yoga instructor","Zookeeper","Adventure tour guide","Art curator"];return(e,g)=>{const b=C;return c(),h(x,null,[s(r)?(c(),h("div",{key:0,class:v(["absolute bottom-2 right-2 h-24 w-24",e.dynamic_bg])},[u(b)],2)):p("",!0),t("main",z,[t("div",B,[t("div",{id:"_card",onClick:g[0]||(g[0]=T=>r.value=!s(r)),class:"md:w-512px w-[350px] border border-white bg-black p-4 font-mono uppercase text-white shadow-xl shadow-yellow-950 transition-all hover:scale-102 hover:cursor-pointer"},[t("div",{class:"mb-2 font-extrabold tracking-wide"},i(R)),t("div",j,[F,t("div",N,[W,$,t("div",A,i(f(d,s(a))),1)]),t("div",I,[D,E,t("div",L,i(f(m,s(l))),1)])])])])])],64)}}};export{Z as default}; +import{l as w,o as c,c as h,m as y,j as n,p as _,a as s,n as v,i as p,e as u,b as t,t as i,F as x}from"./YC8jgtvV.js";const V={},k={version:"1.1",id:"Layer_1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",x:"0px",y:"0px",viewBox:"0 0 1160 1160","enable-background":"new 0 0 1160 1160","xml:space":"preserve"},H=y('',2),M=[H];function S(o,r){return c(),h("svg",k,M)}const C=w(V,[["render",S]]),P=window.setInterval,z={class:"bg-slate-800"},B={class:"flex h-screen items-center justify-center"},j={class:"mb-4 space-y-2 text-sm"},F=t("div",{class:"flex items-center"},[t("div",{class:"flex-none pr-2"},"Name"),t("div",{class:"flex-grow border-b border-dotted"}),t("div",{class:"flex-none pl-2"},"Colton")],-1),N={class:"flex items-center"},W=t("div",{class:"flex-none pr-2"},"Profession",-1),$=t("div",{class:"flex-grow border-b border-dotted"},null,-1),A={class:"flex-none pl-2"},I={class:"flex items-center"},D=t("div",{class:"flex-none pr-2"},"Hobby",-1),E=t("div",{class:"flex-grow border-b border-dotted"},null,-1),L={class:"flex-none pl-2"},R="TL;DR",Z={__name:"card",setup(o){const r=n(!1),a=n(0),l=n(0),f=(e,g)=>e[g%e.length];_(()=>{P(function(){a.value>l.value?l.value+=1:a.value+=1},1500)});const m=["Skydiving","Bungee jumping","Rock climbing","White water rafting","Paragliding","Scuba diving","Base jumping","Mountain biking","Surfing","Snowboarding","Wakeboarding","Motorsports","Parkour","Zip-lining","Off-roading","Cave diving","Kiteboarding","Hang gliding","Free solo climbing","Bull riding","Ice climbing","Wing suit flying","Extreme skiing","Cliff jumping","Cave exploring"],d=["Astronaut","Archaeologist","Professional athlete","Chef","Fashion designer","Film director","Investigative journalist","Marine biologist","Musician","Photographer","Pilot","Professional gamer","Professor","Sculptor","Spy","Stand-up comedian","Surfing instructor","Travel writer","Wildlife photographer","Wine connoisseur","Yacht captain","Yoga instructor","Zookeeper","Adventure tour guide","Art curator"];return(e,g)=>{const b=C;return c(),h(x,null,[s(r)?(c(),h("div",{key:0,class:v(["absolute bottom-2 right-2 h-24 w-24",e.dynamic_bg])},[p(b)],2)):u("",!0),t("main",z,[t("div",B,[t("div",{id:"_card",onClick:g[0]||(g[0]=T=>r.value=!s(r)),class:"md:w-512px w-[350px] border border-white bg-black p-4 font-mono uppercase text-white shadow-xl shadow-yellow-950 transition-all hover:scale-102 hover:cursor-pointer"},[t("div",{class:"mb-2 font-extrabold tracking-wide"},i(R)),t("div",j,[F,t("div",N,[W,$,t("div",A,i(f(d,s(a))),1)]),t("div",I,[D,E,t("div",L,i(f(m,s(l))),1)])])])])])],64)}}};export{Z as default}; diff --git a/_nuxt/BTH0oiOj.js b/_nuxt/EFdih8x4.js similarity index 82% rename from _nuxt/BTH0oiOj.js rename to _nuxt/EFdih8x4.js index 58bdf6c0..38f2332e 100644 --- a/_nuxt/BTH0oiOj.js +++ b/_nuxt/EFdih8x4.js @@ -1 +1 @@ -import{u as g}from"./T8qFVnUA.js";import{q as m}from"./ElOT_Ul4.js";import{d as C,O as S,v as b,H as O,p as _,I as k,K as A}from"./D6y6W-Zj.js";import{h as N}from"./DvDH6DOc.js";import"./DXU4rfre.js";const Q=C({name:"ContentQuery",props:{path:{type:String,required:!1,default:void 0},only:{type:Array,required:!1,default:void 0},without:{type:Array,required:!1,default:void 0},where:{type:Object,required:!1,default:void 0},sort:{type:Object,required:!1,default:void 0},limit:{type:Number,required:!1,default:void 0},skip:{type:Number,required:!1,default:void 0},locale:{type:String,required:!1,default:void 0},find:{type:String,required:!1,default:void 0}},async setup(u){const{path:t,only:r,without:o,where:a,sort:f,limit:l,skip:d,locale:s,find:p}=S(u),y=b(()=>{var e;return(e=t.value)==null?void 0:e.includes("/_")}),h=!O().public.content.experimental.advanceQuery;_(()=>u,()=>n(),{deep:!0});const i=e=>h?e!=null&&e.surround?e.surround:e!=null&&e._id||Array.isArray(e)?e:e==null?void 0:e.result:e.result,{data:v,refresh:n}=await g(`content-query-${N(u)}`,()=>{let e;return t.value?e=m(t.value):e=m(),r.value&&(e=e.only(r.value)),o.value&&(e=e.without(o.value)),a.value&&(e=e.where(a.value)),f.value&&(e=e.sort(f.value)),l.value&&(e=e.limit(l.value)),d.value&&(e=e.skip(d.value)),s.value&&(e=e.where({_locale:s.value})),p.value==="one"?e.findOne().then(i):p.value==="surround"?t.value?h?e.findSurround(t.value):e.withSurround(t.value).findOne().then(i):(console.warn("[Content] Surround queries requires `path` prop to be set."),console.warn("[Content] Query without `path` will return regular `find()` results."),e.find().then(i)):e.find().then(i)});return{isPartial:y,data:v,refresh:n}},render(u){var c;const t=k(),{data:r,refresh:o,isPartial:a,path:f,only:l,without:d,where:s,sort:p,limit:y,skip:h,locale:i,find:v}=u,n={path:f,only:l,without:d,where:s,sort:p,limit:y,skip:h,locale:i,find:v};if(n.find==="one"){if(!r&&(t!=null&&t["not-found"]))return t["not-found"]({props:n,...this.$attrs});if(t!=null&&t.empty&&(r==null?void 0:r._type)==="markdown"&&!((c=r==null?void 0:r.body)!=null&&c.children.length))return t.empty({props:n,...this.$attrs})}else if((!r||!r.length)&&t!=null&&t["not-found"])return t["not-found"]({props:n,...this.$attrs});return t!=null&&t.default?t.default({data:r,refresh:o,isPartial:a,props:n,...this.$attrs}):((w,q)=>A("pre",null,JSON.stringify({message:"You should use slots with !",slot:w,data:q},null,2)))("default",{data:r,props:n,isPartial:a})}}),B=Q;export{B as default}; +import{u as g}from"./DjmxGRUG.js";import{q as m}from"./NquB2IUV.js";import{d as C,O as S,k as b,H as k,s as O,I as _,K as A}from"./YC8jgtvV.js";import{h as N}from"./DvDH6DOc.js";import"./JthqPOXk.js";const Q=C({name:"ContentQuery",props:{path:{type:String,required:!1,default:void 0},only:{type:Array,required:!1,default:void 0},without:{type:Array,required:!1,default:void 0},where:{type:Object,required:!1,default:void 0},sort:{type:Object,required:!1,default:void 0},limit:{type:Number,required:!1,default:void 0},skip:{type:Number,required:!1,default:void 0},locale:{type:String,required:!1,default:void 0},find:{type:String,required:!1,default:void 0}},async setup(u){const{path:t,only:r,without:o,where:a,sort:f,limit:l,skip:d,locale:s,find:p}=S(u),y=b(()=>{var e;return(e=t.value)==null?void 0:e.includes("/_")}),h=!k().public.content.experimental.advanceQuery;O(()=>u,()=>n(),{deep:!0});const i=e=>h?e!=null&&e.surround?e.surround:e!=null&&e._id||Array.isArray(e)?e:e==null?void 0:e.result:e.result,{data:v,refresh:n}=await g(`content-query-${N(u)}`,()=>{let e;return t.value?e=m(t.value):e=m(),r.value&&(e=e.only(r.value)),o.value&&(e=e.without(o.value)),a.value&&(e=e.where(a.value)),f.value&&(e=e.sort(f.value)),l.value&&(e=e.limit(l.value)),d.value&&(e=e.skip(d.value)),s.value&&(e=e.where({_locale:s.value})),p.value==="one"?e.findOne().then(i):p.value==="surround"?t.value?h?e.findSurround(t.value):e.withSurround(t.value).findOne().then(i):(console.warn("[Content] Surround queries requires `path` prop to be set."),console.warn("[Content] Query without `path` will return regular `find()` results."),e.find().then(i)):e.find().then(i)});return{isPartial:y,data:v,refresh:n}},render(u){var c;const t=_(),{data:r,refresh:o,isPartial:a,path:f,only:l,without:d,where:s,sort:p,limit:y,skip:h,locale:i,find:v}=u,n={path:f,only:l,without:d,where:s,sort:p,limit:y,skip:h,locale:i,find:v};if(n.find==="one"){if(!r&&(t!=null&&t["not-found"]))return t["not-found"]({props:n,...this.$attrs});if(t!=null&&t.empty&&(r==null?void 0:r._type)==="markdown"&&!((c=r==null?void 0:r.body)!=null&&c.children.length))return t.empty({props:n,...this.$attrs})}else if((!r||!r.length)&&t!=null&&t["not-found"])return t["not-found"]({props:n,...this.$attrs});return t!=null&&t.default?t.default({data:r,refresh:o,isPartial:a,props:n,...this.$attrs}):((w,q)=>A("pre",null,JSON.stringify({message:"You should use slots with !",slot:w,data:q},null,2)))("default",{data:r,props:n,isPartial:a})}}),B=Q;export{B as default}; diff --git a/_nuxt/Gb-Mbhdk.js b/_nuxt/Gb-Mbhdk.js new file mode 100644 index 00000000..b604b8cd --- /dev/null +++ b/_nuxt/Gb-Mbhdk.js @@ -0,0 +1 @@ +import{d as h,u as g,w as b,a as o,o as a,c as r,b as e,e as l,t as i,F as v,r as y,f as k,g as _,h as w,i as d,_ as C}from"./YC8jgtvV.js";import{_ as N}from"./DuCNYxTx.js";import B from"./Cj9zn9Hh.js";import{u as V}from"./DjmxGRUG.js";import{q as R}from"./NquB2IUV.js";import"./C-v3KzvZ.js";import"./Dnd51l0P.js";import"./JthqPOXk.js";import"./DvDH6DOc.js";const $={key:0,class:"container mx-auto"},q={class:"mb-10 bg-gray-200 p-10 shadow-lg"},A={class:"flex flex-auto items-center"},D=["src"],F={class:"space-y-2"},L={class:"text-xl font-bold text-gray-700 md:text-3xl"},E={class:"flex space-x-2"},M=e("div",{class:"my-4 border-b border-gray-400"},null,-1),O={class:"prose max-w-none prose-a:font-bold prose-a:no-underline hover:prose-a:text-orange-500 prose-pre:bg-white prose-pre:text-black"},W=h({__name:"[...slug]",async setup(S){let s,n;const m=g(),{data:t}=([s,n]=b(()=>V("page-data",()=>R(m.path).findOne())),s=await s,n(),s);return(T,j)=>{const p=C,u=N,x=B;return o(t)?(a(),r("div",$,[e("article",q,[e("div",A,[o(t).cover_image?(a(),r("img",{key:0,class:"mr-4 h-16 border-2 border-black",src:o(t).cover_image},null,8,D)):l("",!0),e("div",F,[e("div",null,[e("h1",L,i(o(t).title),1)]),e("div",null,[e("div",E,[(a(!0),r(v,null,y(o(t).tags,(c,f)=>(a(),k(p,{class:"rounded-md bg-background px-2 text-sm font-bold text-white hover:cursor-pointer",key:f,to:`/articles?tag=${c}`},{default:_(()=>[w(i(c),1)]),_:2},1032,["to"]))),128))])])])]),M,e("article",O,[d(x,null,{default:_(()=>[d(u,{value:o(t)},null,8,["value"])]),_:1})])])])):l("",!0)}}});export{W as default}; diff --git a/_nuxt/I56hc03J.js b/_nuxt/I56hc03J.js new file mode 100644 index 00000000..8c998660 --- /dev/null +++ b/_nuxt/I56hc03J.js @@ -0,0 +1 @@ +import{l as o,o as n,c as r,a7 as c}from"./YC8jgtvV.js";const s={};function t(e,a){return n(),r("code",null,[c(e.$slots,"default")])}const d=o(s,[["render",t]]);export{d as default}; diff --git a/_nuxt/DXU4rfre.js b/_nuxt/JthqPOXk.js similarity index 97% rename from _nuxt/DXU4rfre.js rename to _nuxt/JthqPOXk.js index a27af3da..15e0a909 100644 --- a/_nuxt/DXU4rfre.js +++ b/_nuxt/JthqPOXk.js @@ -1 +1 @@ -import{k as S,a0 as T,Y as E,p as C,a6 as A,a5 as O,E as P,u as h}from"./D6y6W-Zj.js";import{i as I}from"./DvDH6DOc.js";const m=/^[\u0009\u0020-\u007E\u0080-\u00FF]+$/;function R(e,i){if(typeof e!="string")throw new TypeError("argument str must be a string");const o={},a=(i||{}).decode||N;let s=0;for(;sO(decodeURIComponent(e)),encode:e=>encodeURIComponent(typeof e=="string"?e:JSON.stringify(e))},U=void 0;function y(e,i){var f;const o={...L,...i},t=b(o)||{};let a;o.maxAge!==void 0?a=o.maxAge*1e3:o.expires&&(a=o.expires.getTime()-Date.now());const s=a!==void 0&&a<=0,r=u(s?void 0:t[e]??((f=o.default)==null?void 0:f.call(o))),n=a&&!s?B(r,a,o.watch&&o.watch!=="shallow"):S(r);{let c=null;try{!U&&typeof BroadcastChannel<"u"&&(c=new BroadcastChannel(`nuxt:cookies:${e}`))}catch{}const l=()=>{o.readonly||I(n.value,t[e])||(q(e,n.value,o),t[e]=u(n.value),c==null||c.postMessage({value:o.encode(n.value)}))},p=w=>{var v;const j=w.refresh?(v=b(o))==null?void 0:v[e]:o.decode(w.value);d=!0,t[e]=n.value=j,P(()=>{d=!1})};let d=!1;T()&&E(()=>{d=!0,l(),c==null||c.close()}),c&&(c.onmessage=({data:w})=>p(w)),o.watch?C(n,()=>{d||l()},{deep:o.watch!=="shallow"}):l()}return n}function b(e={}){return R(document.cookie,e)}function _(e,i,o={}){return i==null?g(e,i,{...o,maxAge:-1}):g(e,i,o)}function q(e,i,o={}){document.cookie=_(e,i,o)}const k=2147483647;function B(e,i,o){let t,a,s=0;const r=o?S(e):{value:e};return T()&&E(()=>{a==null||a(),clearTimeout(t)}),A((n,f)=>{o&&(a=C(r,f));function c(){clearTimeout(t);const l=i-s,p=l{if(s+=p,s({isEnabled:()=>{const t=h().query;return Object.prototype.hasOwnProperty.call(t,"preview")&&!t.preview?!1:!!(t.preview||y("previewToken").value||sessionStorage.getItem("previewToken"))},getPreviewToken:()=>y("previewToken").value||sessionStorage.getItem("previewToken")||void 0,setPreviewToken:t=>{y("previewToken").value=t,h().query.preview=t||"",t?sessionStorage.setItem("previewToken",t):sessionStorage.removeItem("previewToken"),window.location.reload()}});export{z as u}; +import{j as S,a0 as T,Y as E,s as C,a6 as A,a5 as O,E as P,u as h}from"./YC8jgtvV.js";import{i as I}from"./DvDH6DOc.js";const m=/^[\u0009\u0020-\u007E\u0080-\u00FF]+$/;function R(e,i){if(typeof e!="string")throw new TypeError("argument str must be a string");const o={},a=(i||{}).decode||N;let s=0;for(;sO(decodeURIComponent(e)),encode:e=>encodeURIComponent(typeof e=="string"?e:JSON.stringify(e))},U=void 0;function y(e,i){var f;const o={...L,...i},t=b(o)||{};let a;o.maxAge!==void 0?a=o.maxAge*1e3:o.expires&&(a=o.expires.getTime()-Date.now());const s=a!==void 0&&a<=0,r=u(s?void 0:t[e]??((f=o.default)==null?void 0:f.call(o))),n=a&&!s?B(r,a,o.watch&&o.watch!=="shallow"):S(r);{let c=null;try{!U&&typeof BroadcastChannel<"u"&&(c=new BroadcastChannel(`nuxt:cookies:${e}`))}catch{}const l=()=>{o.readonly||I(n.value,t[e])||(q(e,n.value,o),t[e]=u(n.value),c==null||c.postMessage({value:o.encode(n.value)}))},p=w=>{var v;const j=w.refresh?(v=b(o))==null?void 0:v[e]:o.decode(w.value);d=!0,t[e]=n.value=j,P(()=>{d=!1})};let d=!1;T()&&E(()=>{d=!0,l(),c==null||c.close()}),c&&(c.onmessage=({data:w})=>p(w)),o.watch?C(n,()=>{d||l()},{deep:o.watch!=="shallow"}):l()}return n}function b(e={}){return R(document.cookie,e)}function _(e,i,o={}){return i==null?g(e,i,{...o,maxAge:-1}):g(e,i,o)}function q(e,i,o={}){document.cookie=_(e,i,o)}const k=2147483647;function B(e,i,o){let t,a,s=0;const r=o?S(e):{value:e};return T()&&E(()=>{a==null||a(),clearTimeout(t)}),A((n,f)=>{o&&(a=C(r,f));function c(){clearTimeout(t);const l=i-s,p=l{if(s+=p,s({isEnabled:()=>{const t=h().query;return Object.prototype.hasOwnProperty.call(t,"preview")&&!t.preview?!1:!!(t.preview||y("previewToken").value||sessionStorage.getItem("previewToken"))},getPreviewToken:()=>y("previewToken").value||sessionStorage.getItem("previewToken")||void 0,setPreviewToken:t=>{y("previewToken").value=t,h().query.preview=t||"",t?sessionStorage.setItem("previewToken",t):sessionStorage.removeItem("previewToken"),window.location.reload()}});export{z as u}; diff --git a/_nuxt/wZXg-9-z.js b/_nuxt/KYfJ1yMs.js similarity index 94% rename from _nuxt/wZXg-9-z.js rename to _nuxt/KYfJ1yMs.js index f8587020..c884effd 100644 --- a/_nuxt/wZXg-9-z.js +++ b/_nuxt/KYfJ1yMs.js @@ -1 +1 @@ -import{v as C,x as O,y as R,z as _,d as U,k as N,w as V,p as E,o as r,c as n,b as o,a,F as y,A as q,B as I,C as K,r as k,h as B,t as x,e as S}from"./D6y6W-Zj.js";import{h as W}from"./DvDH6DOc.js";import{u as M}from"./T8qFVnUA.js";function G(h,l,v){const[e={},c]=typeof l=="string"?[{},l]:[l,v],s=C(()=>_(h)),t=e.key||W([c,typeof s.value=="string"?s.value:"",...H(e)]);if(!t||typeof t!="string")throw new TypeError("[nuxt] [useFetch] key must be a string: "+t);const d=t===c?"$f"+t:t;if(!e.baseURL&&typeof s.value=="string"&&s.value[0]==="/"&&s.value[1]==="/")throw new Error('[nuxt] [useFetch] the request URL must not start with "//".');const{server:m,lazy:w,default:j,transform:D,pick:F,watch:u,immediate:p,getCachedData:i,deep:g,dedupe:L,...$}=e,b=O({...R,...$,cache:typeof e.cache=="boolean"?void 0:e.cache}),A={server:m,lazy:w,default:j,transform:D,pick:F,immediate:p,getCachedData:i,deep:g,dedupe:L,watch:u===!1?[]:[b,s,...u||[]]};let f;return M(d,()=>{var z;(z=f==null?void 0:f.abort)==null||z.call(f),f=typeof AbortController<"u"?new AbortController:{};const T=_(e.timeout);return T&&setTimeout(()=>f.abort(),T),(e.$fetch||globalThis.$fetch)(s.value,{signal:f.signal,...b})},A)}function H(h){var v;const l=[((v=_(h.method))==null?void 0:v.toUpperCase())||"GET",_(h.baseURL)];for(const e of[h.params||h.query]){const c=_(e);if(!c)continue;const s={};for(const[t,d]of Object.entries(c))s[_(t)]=_(d);l.push(s)}return l}const P={class:"flex h-screen flex-col font-mono"},Q={class:"flex flex-1 overflow-hidden"},J=o("div",{class:"flex w-20 bg-amber-500"},[o("div",{class:"absolute bottom-10 w-20 -rotate-90 transform whitespace-nowrap"},[o("div",{class:"text-4xl font-bold text-white"}," 1000 French Conjugations ")])],-1),X={class:"flex flex-1 flex-col overflow-y-auto bg-amber-100 p-8"},Y=o("div",{class:"flex rounded-xl bg-amber-500 p-4"},[o("div",{class:"text-center text-xl italic text-white"}," Click a word to the left or right to cycle through the 1000 most popular French verb conjugations! ")],-1),Z={class:"inline-flex flex-col justify-center py-4 text-gray-600"},ee={key:0,class:"mt-2 w-full border border-gray-100 bg-white"},te=["onClick"],oe=o("svg",{class:"absolute left-2 top-2 h-4 w-4",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor"},[o("path",{d:"M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z"})],-1),se={class:"flex p-4"},ae={class:"text-cyan-600 flex-1 text-center text-3xl font-bold"},re={class:"text-amber-500"},ne={class:"grid grid-cols-1 gap-8 md:grid-cols-3 xl:grid-cols-4 xl:gap-12"},le={class:"border-cyan-600 h-full space-y-3 rounded-md border-2 bg-white p-4 shadow shadow-amber-500"},ce={class:"text-2xl font-semibold capitalize text-gray-700"},ie={class:"text-gray-500"},ue={key:1,class:"italic"},xe=U({__name:"index",async setup(h){let l,v;const e=N(0),c=N(""),s=N([]),{data:t}=([l,v]=V(()=>G("/1000_french_conjugations.json",{transform:u=>u},"$lRKQKt9Al2")),l=await l,v(),l),d=C(()=>{if(t.value)return t.value[e.value]}),m=C(()=>{if(t.value!==null)return e.value===0?void 0:t.value[e.value-1]}),w=C(()=>{if(t.value!==null)return e.value+1===t.value.length?void 0:t.value[e.value+1]});E(c,u=>{if(s.value=[],!u)return;let p=0;s.value=t.value.filter(i=>i.word.normalize("NFD").replace(new RegExp("\\p{Diacritic}","gu"),"").includes(u)&&p<=5?(p++,!0):!1)});const j=()=>{t.value&&e.value{e.value>0&&(e.value-=1)},F=u=>{c.value="",s.value=[],e.value=u.word_popularity-1};return(u,p)=>(r(),n("div",P,[o("div",Q,[J,o("div",X,[a(t)&&a(t).length>0&&a(d)?(r(),n(y,{key:0},[Y,o("div",Z,[q(o("input",{"onUpdate:modelValue":p[0]||(p[0]=i=>K(c)?c.value=i:null),class:"rounded-xl border border-2 border-gray-400 p-2 pl-8 focus:border-amber-500 focus:outline-none",type:"search",autocomplete:"off",placeholder:"Search Words"},null,512),[[I,a(c)]]),a(s).length>0?(r(),n("ul",ee,[(r(!0),n(y,null,k(a(s),i=>(r(),n("li",{key:i.word,class:"relative cursor-pointer py-1 pl-8 pr-2 hover:bg-yellow-50 hover:text-gray-900",onClick:g=>F(i)},[oe,B(" "+x(i.word),1)],8,te))),128))])):S("",!0)]),o("div",se,[o("div",{class:"flex-1 cursor-pointer select-none text-center text-2xl text-gray-400",onClick:D},x(a(m)?a(m).word:"-"),1),o("div",ae,[o("span",re," #"+x(a(d).word_popularity),1),B(" "+x(a(d).word),1)]),o("div",{class:"flex-1 cursor-pointer select-none text-center text-2xl text-gray-400",onClick:j},x(a(w)?a(w).word:"-"),1)]),o("div",ne,[(r(!0),n(y,null,k(a(d).conjugations,(i,g)=>(r(),n("div",{key:g},[o("div",le,[o("h1",ce,x(g),1),o("div",ie,[(r(!0),n(y,null,k(i,(L,$)=>(r(),n("p",{key:$},[(r(!0),n(y,null,k(L,(b,A)=>(r(),n("i",{key:A},x(b.text),1))),128))]))),128))])])]))),128))])],64)):(r(),n("div",ue,"Loading..."))])])]))}});export{xe as default}; +import{k as C,y as _,z as O,A as R,d as U,j as N,w as V,s as E,o as r,c as n,b as o,a,F as y,B as q,C as I,D as K,r as k,h as B,t as x,e as S}from"./YC8jgtvV.js";import{h as W}from"./DvDH6DOc.js";import{u as M}from"./DjmxGRUG.js";function G(h,l,v){const[e={},c]=typeof l=="string"?[{},l]:[l,v],s=C(()=>_(h)),t=e.key||W([c,typeof s.value=="string"?s.value:"",...H(e)]);if(!t||typeof t!="string")throw new TypeError("[nuxt] [useFetch] key must be a string: "+t);const d=t===c?"$f"+t:t;if(!e.baseURL&&typeof s.value=="string"&&s.value[0]==="/"&&s.value[1]==="/")throw new Error('[nuxt] [useFetch] the request URL must not start with "//".');const{server:m,lazy:w,default:j,transform:D,pick:F,watch:u,immediate:p,getCachedData:i,deep:g,dedupe:L,...$}=e,b=O({...R,...$,cache:typeof e.cache=="boolean"?void 0:e.cache}),A={server:m,lazy:w,default:j,transform:D,pick:F,immediate:p,getCachedData:i,deep:g,dedupe:L,watch:u===!1?[]:[b,s,...u||[]]};let f;return M(d,()=>{var z;(z=f==null?void 0:f.abort)==null||z.call(f),f=typeof AbortController<"u"?new AbortController:{};const T=_(e.timeout);return T&&setTimeout(()=>f.abort(),T),(e.$fetch||globalThis.$fetch)(s.value,{signal:f.signal,...b})},A)}function H(h){var v;const l=[((v=_(h.method))==null?void 0:v.toUpperCase())||"GET",_(h.baseURL)];for(const e of[h.params||h.query]){const c=_(e);if(!c)continue;const s={};for(const[t,d]of Object.entries(c))s[_(t)]=_(d);l.push(s)}return l}const P={class:"flex h-screen flex-col font-mono"},Q={class:"flex flex-1 overflow-hidden"},J=o("div",{class:"flex w-20 bg-amber-500"},[o("div",{class:"absolute bottom-10 w-20 -rotate-90 transform whitespace-nowrap"},[o("div",{class:"text-4xl font-bold text-white"}," 1000 French Conjugations ")])],-1),X={class:"flex flex-1 flex-col overflow-y-auto bg-amber-100 p-8"},Y=o("div",{class:"flex rounded-xl bg-amber-500 p-4"},[o("div",{class:"text-center text-xl italic text-white"}," Click a word to the left or right to cycle through the 1000 most popular French verb conjugations! ")],-1),Z={class:"inline-flex flex-col justify-center py-4 text-gray-600"},ee={key:0,class:"mt-2 w-full border border-gray-100 bg-white"},te=["onClick"],oe=o("svg",{class:"absolute left-2 top-2 h-4 w-4",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor"},[o("path",{d:"M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z"})],-1),se={class:"flex p-4"},ae={class:"text-cyan-600 flex-1 text-center text-3xl font-bold"},re={class:"text-amber-500"},ne={class:"grid grid-cols-1 gap-8 md:grid-cols-3 xl:grid-cols-4 xl:gap-12"},le={class:"border-cyan-600 h-full space-y-3 rounded-md border-2 bg-white p-4 shadow shadow-amber-500"},ce={class:"text-2xl font-semibold capitalize text-gray-700"},ie={class:"text-gray-500"},ue={key:1,class:"italic"},xe=U({__name:"index",async setup(h){let l,v;const e=N(0),c=N(""),s=N([]),{data:t}=([l,v]=V(()=>G("/1000_french_conjugations.json",{transform:u=>u},"$lRKQKt9Al2")),l=await l,v(),l),d=C(()=>{if(t.value)return t.value[e.value]}),m=C(()=>{if(t.value!==null)return e.value===0?void 0:t.value[e.value-1]}),w=C(()=>{if(t.value!==null)return e.value+1===t.value.length?void 0:t.value[e.value+1]});E(c,u=>{if(s.value=[],!u)return;let p=0;s.value=t.value.filter(i=>i.word.normalize("NFD").replace(new RegExp("\\p{Diacritic}","gu"),"").includes(u)&&p<=5?(p++,!0):!1)});const j=()=>{t.value&&e.value{e.value>0&&(e.value-=1)},F=u=>{c.value="",s.value=[],e.value=u.word_popularity-1};return(u,p)=>(r(),n("div",P,[o("div",Q,[J,o("div",X,[a(t)&&a(t).length>0&&a(d)?(r(),n(y,{key:0},[Y,o("div",Z,[q(o("input",{"onUpdate:modelValue":p[0]||(p[0]=i=>K(c)?c.value=i:null),class:"rounded-xl border border-2 border-gray-400 p-2 pl-8 focus:border-amber-500 focus:outline-none",type:"search",autocomplete:"off",placeholder:"Search Words"},null,512),[[I,a(c)]]),a(s).length>0?(r(),n("ul",ee,[(r(!0),n(y,null,k(a(s),i=>(r(),n("li",{key:i.word,class:"relative cursor-pointer py-1 pl-8 pr-2 hover:bg-yellow-50 hover:text-gray-900",onClick:g=>F(i)},[oe,B(" "+x(i.word),1)],8,te))),128))])):S("",!0)]),o("div",se,[o("div",{class:"flex-1 cursor-pointer select-none text-center text-2xl text-gray-400",onClick:D},x(a(m)?a(m).word:"-"),1),o("div",ae,[o("span",re," #"+x(a(d).word_popularity),1),B(" "+x(a(d).word),1)]),o("div",{class:"flex-1 cursor-pointer select-none text-center text-2xl text-gray-400",onClick:j},x(a(w)?a(w).word:"-"),1)]),o("div",ne,[(r(!0),n(y,null,k(a(d).conjugations,(i,g)=>(r(),n("div",{key:g},[o("div",le,[o("h1",ce,x(g),1),o("div",ie,[(r(!0),n(y,null,k(i,(L,$)=>(r(),n("p",{key:$},[(r(!0),n(y,null,k(L,(b,A)=>(r(),n("i",{key:A},x(b.text),1))),128))]))),128))])])]))),128))])],64)):(r(),n("div",ue,"Loading..."))])])]))}});export{xe as default}; diff --git a/_nuxt/KhVY6nTr.js b/_nuxt/KhVY6nTr.js new file mode 100644 index 00000000..b41952ab --- /dev/null +++ b/_nuxt/KhVY6nTr.js @@ -0,0 +1 @@ +import{Z as u,d as c,H as r,k as d,Q as l,J as h,R as m,o as g,f,a as i,a9 as p}from"./YC8jgtvV.js";function x(t){throw u({fatal:!0,statusCode:500,statusMessage:`${t} is provided by @nuxt/image. Check your console to install it or run 'npx nuxi@latest module add @nuxt/image'`})}const S={setup:()=>x("")},w=c({__name:"ProseImg",props:{src:{type:String,default:""},alt:{type:String,default:""},width:{type:[String,Number],default:void 0},height:{type:[String,Number],default:void 0}},setup(t){const n=r().public.mdc.useNuxtImage?S:"img",e=t,o=d(()=>{var a;if((a=e.src)!=null&&a.startsWith("/")&&!e.src.startsWith("//")){const s=l(h(r().app.baseURL));if(s!=="/"&&!e.src.startsWith(s))return m(s,e.src)}return e.src});return(a,s)=>(g(),f(p(i(n)),{src:i(o),alt:t.alt,width:t.width,height:t.height},null,8,["src","alt","width","height"]))}});export{w as default}; diff --git a/_nuxt/MGGx6DJ7.js b/_nuxt/MGGx6DJ7.js new file mode 100644 index 00000000..efc22a2b --- /dev/null +++ b/_nuxt/MGGx6DJ7.js @@ -0,0 +1 @@ +import{l as o,o as r,c as s,a7 as t}from"./YC8jgtvV.js";const c={};function l(e,n){return r(),s("ol",null,[t(e.$slots,"default")])}const f=o(c,[["render",l]]);export{f as default}; diff --git a/_nuxt/ElOT_Ul4.js b/_nuxt/NquB2IUV.js similarity index 73% rename from _nuxt/ElOT_Ul4.js rename to _nuxt/NquB2IUV.js index 1f3d7068..d0c755bd 100644 --- a/_nuxt/ElOT_Ul4.js +++ b/_nuxt/NquB2IUV.js @@ -1,2 +1,2 @@ -const __vite__fileDeps=["./U3g5PXV_.js","./D6y6W-Zj.js","./C-v3KzvZ.js","./DXU4rfre.js","./DvDH6DOc.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); -import{P,H as h,L as $,Q as b,R as C,U as E}from"./D6y6W-Zj.js";import{h as l}from"./DvDH6DOc.js";import{u as w}from"./DXU4rfre.js";const d=(t,r)=>r.split(".").reduce((n,i)=>n&&n[i],t),f=(t,r)=>Object.keys(t).filter(r).reduce((n,i)=>Object.assign(n,{[i]:t[i]}),{}),B=t=>r=>t&&t.length?f(r,n=>!t.includes(n)):r,j=t=>r=>Array.isArray(r)?r.map(n=>t(n)):t(r),m=t=>{const r=[],n=[];for(const i of t)["$","_"].includes(i)?r.push(i):n.push(i);return{prefixes:r,properties:n}},q=(t=[])=>r=>{if(t.length===0||!r)return r;const{prefixes:n,properties:i}=m(t);return f(r,o=>!i.includes(o)&&!n.includes(o[0]))},Q=(t=[])=>r=>{if(t.length===0||!r)return r;const{prefixes:n,properties:i}=m(t);return f(r,o=>i.includes(o)||n.includes(o[0]))},I=(t,r)=>{const n=new Intl.Collator(r.$locale,{numeric:r.$numeric,caseFirst:r.$caseFirst,sensitivity:r.$sensitivity}),i=Object.keys(r).filter(o=>!o.startsWith("$"));for(const o of i)t=t.sort((a,e)=>{const s=[d(a,o),d(e,o)].map(c=>{if(c!==null)return c instanceof Date?c.toISOString():c});return r[o]===-1&&s.reverse(),n.compare(s[0],s[1])});return t},F=(t,r="Expected an array")=>{if(!Array.isArray(t))throw new TypeError(r)},u=t=>Array.isArray(t)?t:[void 0,null].includes(t)?[]:[t],S=["sort","where","only","without"];function x(t,r={}){const n={};for(const e of Object.keys(r.initialParams||{}))n[e]=S.includes(e)?u(r.initialParams[e]):r.initialParams[e];const i=(e,s=c=>c)=>(...c)=>(n[e]=s(...c),a),o=e=>{var s;return r.legacy?e!=null&&e.surround?e.surround:e&&(e!=null&&e.dirConfig&&(e.result={_path:(s=e.dirConfig)==null?void 0:s._path,...e.result,_dir:e.dirConfig}),e!=null&&e._path||Array.isArray(e)||!Object.prototype.hasOwnProperty.call(e,"result")?e:e==null?void 0:e.result):e},a={params:()=>({...n,...n.where?{where:[...u(n.where)]}:{},...n.sort?{sort:[...u(n.sort)]}:{}}),only:i("only",u),without:i("without",u),where:i("where",e=>[...u(n.where),...u(e)]),sort:i("sort",e=>[...u(n.sort),...u(e)]),limit:i("limit",e=>parseInt(String(e),10)),skip:i("skip",e=>parseInt(String(e),10)),find:()=>t(a).then(o),findOne:()=>t(i("first")(!0)).then(o),count:()=>t(i("count")(!0)).then(o),locale:e=>a.where({_locale:e}),withSurround:i("surround",(e,s)=>({query:e,...s})),withDirConfig:()=>i("dirConfig")(!0)};return r.legacy&&(a.findSurround=(e,s)=>a.withSurround(e,s).find().then(o)),a}function g(t){return JSON.stringify(t,A)}function A(t,r){return r instanceof RegExp?`--REGEX ${r.toString()}`:r}const O=t=>{let r=g(t);return r=typeof Buffer<"u"?Buffer.from(r).toString("base64"):btoa(r),r=r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,""),(r.match(/.{1,100}/g)||[]).join("/")},y=t=>P(t,h().public.content.api.baseURL),U=()=>{throw console.warn("useContent is only accessible when you are using `documentDriven` mode."),console.warn("Learn more by visiting: https://content.nuxt.com/document-driven"),new Error("useContent is only accessible when you are using `documentDriven` mode.")},D=()=>{const{experimental:t}=h().public.content;return t.clientDB?!0:w().isEnabled()},L=()=>async t=>{const{content:r}=h().public,n=t.params(),i=r.experimental.stripQueryParameters?y(`/query/${`${l(n)}.${r.integrity}`}/${O(n)}.json`):y(`/query/${l(n)}.${r.integrity}.json`);if(D())return(await $(()=>import("./U3g5PXV_.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url).then(e=>e.useContentDatabase())).fetch(t);const o=await $fetch(i,{method:"GET",responseType:"json",params:r.experimental.stripQueryParameters?void 0:{_params:g(n),previewToken:w().getPreviewToken()}});if(typeof o=="string"&&o.startsWith(""))throw new Error("Not found");return o};function G(t,...r){const{content:n}=h().public,i=x(L(),{initialParams:typeof t!="string"?t:{},legacy:!0});let o;typeof t=="string"&&(o=b(C(t,...r)));const a=i.params;return i.params=()=>{var s,c,p;const e=a();return o&&(e.where=e.where||[],e.first&&(e.where||[]).length===0?e.where.push({_path:E(o)}):e.where.push({_path:new RegExp(`^${o.replace(/[-[\]{}()*+.,^$\s/]/g,"\\$&")}`)})),(s=e.sort)!=null&&s.length||(e.sort=[{_file:1,$numeric:!0}]),n.locales.length&&((p=(c=e.where)==null?void 0:c.find(_=>_._locale))!=null&&p._locale||(e.where=e.where||[],e.where.push({_locale:n.defaultLocale}))),e},i}export{F as a,u as b,I as c,j as d,O as e,q as f,d as g,Q as h,x as i,g as j,B as o,G as q,D as s,U as u,y as w}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./B4Ww-T0F.js","./YC8jgtvV.js","./C-v3KzvZ.js","./JthqPOXk.js","./DvDH6DOc.js"])))=>i.map(i=>d[i]); +import{P,H as h,Q as $,R as b,U as C,L as E}from"./YC8jgtvV.js";import{h as l}from"./DvDH6DOc.js";import{u as m}from"./JthqPOXk.js";const d=(t,r)=>r.split(".").reduce((n,i)=>n&&n[i],t),p=(t,r)=>Object.keys(t).filter(r).reduce((n,i)=>Object.assign(n,{[i]:t[i]}),{}),B=t=>r=>t&&t.length?p(r,n=>!t.includes(n)):r,j=t=>r=>Array.isArray(r)?r.map(n=>t(n)):t(r),w=t=>{const r=[],n=[];for(const i of t)["$","_"].includes(i)?r.push(i):n.push(i);return{prefixes:r,properties:n}},q=(t=[])=>r=>{if(t.length===0||!r)return r;const{prefixes:n,properties:i}=w(t);return p(r,o=>!i.includes(o)&&!n.includes(o[0]))},Q=(t=[])=>r=>{if(t.length===0||!r)return r;const{prefixes:n,properties:i}=w(t);return p(r,o=>i.includes(o)||n.includes(o[0]))},I=(t,r)=>{const n=new Intl.Collator(r.$locale,{numeric:r.$numeric,caseFirst:r.$caseFirst,sensitivity:r.$sensitivity}),i=Object.keys(r).filter(o=>!o.startsWith("$"));for(const o of i)t=t.sort((a,e)=>{const s=[d(a,o),d(e,o)].map(c=>{if(c!==null)return c instanceof Date?c.toISOString():c});return r[o]===-1&&s.reverse(),n.compare(s[0],s[1])});return t},F=(t,r="Expected an array")=>{if(!Array.isArray(t))throw new TypeError(r)},u=t=>Array.isArray(t)?t:[void 0,null].includes(t)?[]:[t],S=["sort","where","only","without"];function x(t,r={}){const n={};for(const e of Object.keys(r.initialParams||{}))n[e]=S.includes(e)?u(r.initialParams[e]):r.initialParams[e];const i=(e,s=c=>c)=>(...c)=>(n[e]=s(...c),a),o=e=>{var s;return r.legacy?e!=null&&e.surround?e.surround:e&&(e!=null&&e.dirConfig&&(e.result={_path:(s=e.dirConfig)==null?void 0:s._path,...e.result,_dir:e.dirConfig}),e!=null&&e._path||Array.isArray(e)||!Object.prototype.hasOwnProperty.call(e,"result")?e:e==null?void 0:e.result):e},a={params:()=>({...n,...n.where?{where:[...u(n.where)]}:{},...n.sort?{sort:[...u(n.sort)]}:{}}),only:i("only",u),without:i("without",u),where:i("where",e=>[...u(n.where),...u(e)]),sort:i("sort",e=>[...u(n.sort),...u(e)]),limit:i("limit",e=>parseInt(String(e),10)),skip:i("skip",e=>parseInt(String(e),10)),find:()=>t(a).then(o),findOne:()=>t(i("first")(!0)).then(o),count:()=>t(i("count")(!0)).then(o),locale:e=>a.where({_locale:e}),withSurround:i("surround",(e,s)=>({query:e,...s})),withDirConfig:()=>i("dirConfig")(!0)};return r.legacy&&(a.findSurround=(e,s)=>a.withSurround(e,s).find().then(o)),a}function g(t){return JSON.stringify(t,A)}function A(t,r){return r instanceof RegExp?`--REGEX ${r.toString()}`:r}const O=t=>{let r=g(t);return r=typeof Buffer<"u"?Buffer.from(r).toString("base64"):btoa(r),r=r.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,""),(r.match(/.{1,100}/g)||[]).join("/")},y=t=>P(t,h().public.content.api.baseURL),U=()=>{throw console.warn("useContent is only accessible when you are using `documentDriven` mode."),console.warn("Learn more by visiting: https://content.nuxt.com/document-driven"),new Error("useContent is only accessible when you are using `documentDriven` mode.")},D=()=>{const{experimental:t}=h().public.content;return t.clientDB?!0:m().isEnabled()},L=()=>async t=>{const{content:r}=h().public,n=t.params(),i=r.experimental.stripQueryParameters?y(`/query/${`${l(n)}.${r.integrity}`}/${O(n)}.json`):y(`/query/${l(n)}.${r.integrity}.json`);if(D())return(await E(()=>import("./B4Ww-T0F.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url).then(e=>e.useContentDatabase())).fetch(t);const o=await $fetch(i,{method:"GET",responseType:"json",params:r.experimental.stripQueryParameters?void 0:{_params:g(n),previewToken:m().getPreviewToken()}});if(typeof o=="string"&&o.startsWith(""))throw new Error("Not found");return o};function G(t,...r){const{content:n}=h().public,i=x(L(),{initialParams:typeof t!="string"?t:{},legacy:!0});let o;typeof t=="string"&&(o=$(b(t,...r)));const a=i.params;return i.params=()=>{var s,c,f;const e=a();return o&&(e.where=e.where||[],e.first&&(e.where||[]).length===0?e.where.push({_path:C(o)}):e.where.push({_path:new RegExp(`^${o.replace(/[-[\]{}()*+.,^$\s/]/g,"\\$&")}`)})),(s=e.sort)!=null&&s.length||(e.sort=[{_stem:1,$numeric:!0}]),n.locales.length&&((f=(c=e.where)==null?void 0:c.find(_=>_._locale))!=null&&f._locale||(e.where=e.where||[],e.where.push({_locale:n.defaultLocale}))),e},i}export{F as a,u as b,I as c,j as d,O as e,q as f,d as g,Q as h,x as i,g as j,B as o,G as q,D as s,U as u,y as w}; diff --git a/_nuxt/OhHb1YIJ.js b/_nuxt/OhHb1YIJ.js deleted file mode 100644 index a9083c47..00000000 --- a/_nuxt/OhHb1YIJ.js +++ /dev/null @@ -1 +0,0 @@ -import{d as i,H as c,v as p,o as s,c as n,a as u,a7 as t}from"./D6y6W-Zj.js";const f=["id"],l=["href"],k=i({__name:"ProseH4",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=p(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h4)});return(e,m)=>(s(),n("h4",{id:e.id},[e.id&&u(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/T-PpGVH_.js b/_nuxt/T-PpGVH_.js new file mode 100644 index 00000000..8a89ba97 --- /dev/null +++ b/_nuxt/T-PpGVH_.js @@ -0,0 +1 @@ +import{l as o,o as r,c as s,a7 as t}from"./YC8jgtvV.js";const c={};function l(e,n){return r(),s("ul",null,[t(e.$slots,"default")])}const f=o(c,[["render",l]]);export{f as default}; diff --git a/_nuxt/U3g5PXV_.js b/_nuxt/U3g5PXV_.js deleted file mode 100644 index d47279cc..00000000 --- a/_nuxt/U3g5PXV_.js +++ /dev/null @@ -1 +0,0 @@ -import{a5 as _,R as W,aa as B,H as M,P as T,N as H}from"./D6y6W-Zj.js";import{g as J,a as P,b as E,o as k,c as b,d as $,f as j,h as D,i as G}from"./ElOT_Ul4.js";import{p as Z}from"./C-v3KzvZ.js";import{u as U}from"./DXU4rfre.js";import"./DvDH6DOc.js";const q="memory",F=()=>{const t=new Map;return{name:q,options:{},hasItem(r){return t.has(r)},getItem(r){return t.get(r)??null},getItemRaw(r){return t.get(r)??null},setItem(r,n){t.set(r,n)},setItemRaw(r,n){t.set(r,n)},removeItem(r){t.delete(r)},getKeys(){return Array.from(t.keys())},clear(){t.clear()},dispose(){t.clear()}}};function V(t){return!t||typeof t.then!="function"?Promise.resolve(t):t}function p(t,...r){try{return V(t(...r))}catch(n){return Promise.reject(n)}}function Q(t){const r=typeof t;return t===null||r!=="object"&&r!=="function"}function X(t){const r=Object.getPrototypeOf(t);return!r||r.isPrototypeOf(Object)}function K(t){if(Q(t))return String(t);if(X(t)||Array.isArray(t))return JSON.stringify(t);if(typeof t.toJSON=="function")return K(t.toJSON());throw new Error("[unstorage] Cannot stringify value!")}function z(){if(typeof Buffer===void 0)throw new TypeError("[unstorage] Buffer is not supported!")}const C="base64:";function ee(t){if(typeof t=="string")return t;z();const r=Buffer.from(t).toString("base64");return C+r}function te(t){return typeof t!="string"||!t.startsWith(C)?t:(z(),Buffer.from(t.slice(C.length),"base64"))}const re=["hasItem","getItem","getItemRaw","setItem","setItemRaw","removeItem","getMeta","setMeta","removeMeta","getKeys","clear","mount","unmount"];function ne(t,r){if(r=A(r),!r)return t;const n={...t};for(const a of re)n[a]=(l="",...c)=>t[a](r+l,...c);return n.getKeys=(a="",...l)=>t.getKeys(r+a,...l).then(c=>c.map(o=>o.slice(r.length))),n}function d(t){return t?t.split("?")[0].replace(/[/\\]/g,":").replace(/:+/g,":").replace(/^:|:$/g,""):""}function ie(...t){return d(t.join(":"))}function A(t){return t=d(t),t?t+":":""}const ae="memory",se=()=>{const t=new Map;return{name:ae,options:{},hasItem(r){return t.has(r)},getItem(r){return t.get(r)??null},getItemRaw(r){return t.get(r)??null},setItem(r,n){t.set(r,n)},setItemRaw(r,n){t.set(r,n)},removeItem(r){t.delete(r)},getKeys(){return Array.from(t.keys())},clear(){t.clear()},dispose(){t.clear()}}};function oe(t={}){const r={mounts:{"":t.driver||se()},mountpoints:[""],watching:!1,watchListeners:[],unwatch:{}},n=e=>{for(const i of r.mountpoints)if(e.startsWith(i))return{base:i,relativeKey:e.slice(i.length),driver:r.mounts[i]};return{base:"",relativeKey:e,driver:r.mounts[""]}},a=(e,i)=>r.mountpoints.filter(s=>s.startsWith(e)||i&&e.startsWith(s)).map(s=>({relativeBase:e.length>s.length?e.slice(s.length):void 0,mountpoint:s,driver:r.mounts[s]})),l=(e,i)=>{if(r.watching){i=d(i);for(const s of r.watchListeners)s(e,i)}},c=async()=>{if(!r.watching){r.watching=!0;for(const e in r.mounts)r.unwatch[e]=await x(r.mounts[e],l,e)}},o=async()=>{if(r.watching){for(const e in r.unwatch)await r.unwatch[e]();r.unwatch={},r.watching=!1}},h=(e,i,s)=>{const u=new Map,f=m=>{let y=u.get(m.base);return y||(y={driver:m.driver,base:m.base,items:[]},u.set(m.base,y)),y};for(const m of e){const y=typeof m=="string",v=d(y?m:m.key),w=y?void 0:m.value,I=y||!m.options?i:{...i,...m.options},O=n(v);f(O).items.push({key:v,value:w,relativeKey:O.relativeKey,options:I})}return Promise.all([...u.values()].map(m=>s(m))).then(m=>m.flat())},g={hasItem(e,i={}){e=d(e);const{relativeKey:s,driver:u}=n(e);return p(u.hasItem,s,i)},getItem(e,i={}){e=d(e);const{relativeKey:s,driver:u}=n(e);return p(u.getItem,s,i).then(f=>_(f))},getItems(e,i){return h(e,i,s=>s.driver.getItems?p(s.driver.getItems,s.items.map(u=>({key:u.relativeKey,options:u.options})),i).then(u=>u.map(f=>({key:ie(s.base,f.key),value:_(f.value)}))):Promise.all(s.items.map(u=>p(s.driver.getItem,u.relativeKey,u.options).then(f=>({key:u.key,value:_(f)})))))},getItemRaw(e,i={}){e=d(e);const{relativeKey:s,driver:u}=n(e);return u.getItemRaw?p(u.getItemRaw,s,i):p(u.getItem,s,i).then(f=>te(f))},async setItem(e,i,s={}){if(i===void 0)return g.removeItem(e);e=d(e);const{relativeKey:u,driver:f}=n(e);f.setItem&&(await p(f.setItem,u,K(i),s),f.watch||l("update",e))},async setItems(e,i){await h(e,i,async s=>{if(s.driver.setItems)return p(s.driver.setItems,s.items.map(u=>({key:u.relativeKey,value:K(u.value),options:u.options})),i);s.driver.setItem&&await Promise.all(s.items.map(u=>p(s.driver.setItem,u.relativeKey,K(u.value),u.options)))})},async setItemRaw(e,i,s={}){if(i===void 0)return g.removeItem(e,s);e=d(e);const{relativeKey:u,driver:f}=n(e);if(f.setItemRaw)await p(f.setItemRaw,u,i,s);else if(f.setItem)await p(f.setItem,u,ee(i),s);else return;f.watch||l("update",e)},async removeItem(e,i={}){typeof i=="boolean"&&(i={removeMeta:i}),e=d(e);const{relativeKey:s,driver:u}=n(e);u.removeItem&&(await p(u.removeItem,s,i),(i.removeMeta||i.removeMata)&&await p(u.removeItem,s+"$",i),u.watch||l("remove",e))},async getMeta(e,i={}){typeof i=="boolean"&&(i={nativeOnly:i}),e=d(e);const{relativeKey:s,driver:u}=n(e),f=Object.create(null);if(u.getMeta&&Object.assign(f,await p(u.getMeta,s,i)),!i.nativeOnly){const m=await p(u.getItem,s+"$",i).then(y=>_(y));m&&typeof m=="object"&&(typeof m.atime=="string"&&(m.atime=new Date(m.atime)),typeof m.mtime=="string"&&(m.mtime=new Date(m.mtime)),Object.assign(f,m))}return f},setMeta(e,i,s={}){return this.setItem(e+"$",i,s)},removeMeta(e,i={}){return this.removeItem(e+"$",i)},async getKeys(e,i={}){e=A(e);const s=a(e,!0);let u=[];const f=[];for(const m of s){const v=(await p(m.driver.getKeys,m.relativeBase,i)).map(w=>m.mountpoint+d(w)).filter(w=>!u.some(I=>w.startsWith(I)));f.push(...v),u=[m.mountpoint,...u.filter(w=>!w.startsWith(m.mountpoint))]}return e?f.filter(m=>m.startsWith(e)&&!m.endsWith("$")):f.filter(m=>!m.endsWith("$"))},async clear(e,i={}){e=A(e),await Promise.all(a(e,!1).map(async s=>{if(s.driver.clear)return p(s.driver.clear,s.relativeBase,i);if(s.driver.removeItem){const u=await s.driver.getKeys(s.relativeBase||"",i);return Promise.all(u.map(f=>s.driver.removeItem(f,i)))}}))},async dispose(){await Promise.all(Object.values(r.mounts).map(e=>L(e)))},async watch(e){return await c(),r.watchListeners.push(e),async()=>{r.watchListeners=r.watchListeners.filter(i=>i!==e),r.watchListeners.length===0&&await o()}},async unwatch(){r.watchListeners=[],await o()},mount(e,i){if(e=A(e),e&&r.mounts[e])throw new Error(`already mounted at ${e}`);return e&&(r.mountpoints.push(e),r.mountpoints.sort((s,u)=>u.length-s.length)),r.mounts[e]=i,r.watching&&Promise.resolve(x(i,l,e)).then(s=>{r.unwatch[e]=s}).catch(console.error),g},async unmount(e,i=!0){e=A(e),!(!e||!r.mounts[e])&&(r.watching&&e in r.unwatch&&(r.unwatch[e](),delete r.unwatch[e]),i&&await L(r.mounts[e]),r.mountpoints=r.mountpoints.filter(s=>s!==e),delete r.mounts[e])},getMount(e=""){e=d(e)+":";const i=n(e);return{driver:i.driver,base:i.base}},getMounts(e="",i={}){return e=d(e),a(e,i.parents).map(u=>({driver:u.driver,base:u.mountpoint}))}};return g}function x(t,r,n){return t.watch?t.watch((a,l)=>r(a,n+l)):()=>{}}async function L(t){typeof t.dispose=="function"&&await p(t.dispose)}function ue(t={}){const r=ce(n,t.operators);function n(a,l){return typeof l!="object"||l instanceof RegExp?r.$eq(a,l):Object.keys(l||{}).every(c=>{const o=l[c];if(c.startsWith("$")&&r[c]){const h=r[c];return typeof h=="function"?h(a,o):!1}return n(J(a,c),o)})}return n}function ce(t,r={}){return{$match:(n,a)=>t(n,a),$eq:(n,a)=>a instanceof RegExp?a.test(n):n===a,$ne:(n,a)=>a instanceof RegExp?!a.test(n):n!==a,$not:(n,a)=>!t(n,a),$and:(n,a)=>(P(a,"$and requires an array as condition"),a.every(l=>t(n,l))),$or:(n,a)=>(P(a,"$or requires an array as condition"),a.some(l=>t(n,l))),$in:(n,a)=>E(a).some(l=>Array.isArray(n)?t(n,{$contains:l}):t(n,l)),$contains:(n,a)=>(n=Array.isArray(n)?n:String(n),E(a).every(l=>n.includes(l))),$icontains:(n,a)=>{if(typeof a!="string")throw new TypeError("$icontains requires a string, use $contains instead");return n=String(n).toLocaleLowerCase(),E(a).every(l=>n.includes(l.toLocaleLowerCase()))},$containsAny:(n,a)=>(P(a,"$containsAny requires an array as condition"),n=Array.isArray(n)?n:String(n),a.some(l=>n.includes(l))),$exists:(n,a)=>a?typeof n<"u":typeof n>"u",$type:(n,a)=>typeof n===String(a),$regex:(n,a)=>{if(!(a instanceof RegExp)){const l=String(a).match(/\/(.*)\/([dgimsuy]*)$/);a=l?new RegExp(l[1],l[2]||""):new RegExp(a)}return a.test(String(n||""))},$lt:(n,a)=>nn<=a,$gt:(n,a)=>n>a,$gte:(n,a)=>n>=a,...r||{}}}function le(t){const r=ue(),n=(c,{query:o,before:h,after:g})=>{const e=typeof o=="string"?{_path:o}:o,i=c.findIndex(u=>r(u,e));h=h??1,g=g??1;const s=new Array(h+g).fill(null,0);return i===-1?s:s.map((u,f)=>c[i-h+f+ +(f>=h)]||null)},a=[(c,o)=>{const h=c.result.filter(g=>E(o.where).every(e=>r(g,e)));return{...c,result:h,total:h.length}},(c,o)=>E(o.sort).forEach(h=>b(c.result,h)),function(o,h,g){var e;if(h.surround){let i=n(((e=o.result)==null?void 0:e.length)===1?g:o.result,h.surround);i=$(j(h.without))(i),i=$(D(h.only))(i),o.surround=i}return o}],l=[(c,o)=>{if(o.skip)return{...c,result:c.result.slice(o.skip),skip:o.skip}},(c,o)=>{if(o.limit)return{...c,result:c.result.slice(0,o.limit),limit:o.limit}},function(o,h,g){var e,i,s;if(h.dirConfig){const u=((e=o.result[0])==null?void 0:e._path)||((s=(i=h.where)==null?void 0:i.find(f=>f._path))==null?void 0:s._path);if(typeof u=="string"){const f=g.find(m=>m._path===W(u,"_dir"));f&&(o.dirConfig={_path:f._path,...j(["_"])(f)})}}return o},(c,o)=>({...c,result:$(j(o.without))(c.result)}),(c,o)=>({...c,result:$(D(o.only))(c.result)})];return async c=>{const o=await t(),h=c.params(),g={result:o,limit:0,skip:0,total:o.length},e=a.reduce((s,u)=>u(s,h,o)||s,g);if(h.count)return{result:e.result.length};const i=l.reduce((s,u)=>u(s,h,o)||s,e);return h.first?{...k(["skip","limit","total"])(i),result:i.result[0]}:i}}function N(t){const r=le(t);return async n=>{var c;n.params().first&&n.withDirConfig();const a=n.params(),l=await r(n);return a.surround?l==null?void 0:l.surround:(l!=null&&l.dirConfig&&(l.result={_path:(c=l.dirConfig)==null?void 0:c._path,...l.result,_dir:l.dirConfig}),l==null?void 0:l.result)}}var fe={exports:{}};(function(t,r){(function(n,a,l){t.exports=l(),t.exports.default=l()})("slugify",B,function(){var n=JSON.parse(`{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E'","Ը":"Y'","Թ":"T'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C'","Կ":"K","Հ":"H","Ձ":"D'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P'","Ք":"Q'","Օ":"O''","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"'","’":"'","“":"\\"","”":"\\"","„":"\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}`),a=JSON.parse('{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}');function l(c,o){if(typeof c!="string")throw new Error("slugify: string argument expected");o=typeof o=="string"?{replacement:o}:o||{};var h=a[o.locale]||{},g=o.replacement===void 0?"-":o.replacement,e=o.trim===void 0?!0:o.trim,i=c.normalize().split("").reduce(function(s,u){var f=h[u];return f===void 0&&(f=n[u]),f===void 0&&(f=u),f===g&&(f=" "),s+f.replace(o.remove||/[^\w\s$*_+~.()'"!\-:@]+/g,"")},"");return o.strict&&(i=i.replace(/[^A-Za-z0-9\s]/g,"")),e&&(i=i.trim()),i=i.replace(/\s+/g,g),o.lower&&(i=i.toLowerCase()),i}return l.extend=function(c){Object.assign(n,c)},l})})(fe);const me=t=>t.split(/[\s-]/g).map(Z).join(" ");function he(t,r){const{navigation:n}=M().public.content;if(n===!1)return[];const a=c=>({...pe(["title",...n.fields])(c),...de(c==null?void 0:c.navigation)?c.navigation:{}}),l=t.sort((c,o)=>c._path.localeCompare(o._path)).reduce((c,o)=>{const h=o._path.substring(1).split("/"),g=o._id.split(":").slice(1),e=!!g[g.length-1].match(/([1-9][0-9]*\.)?index.md/g),i=f=>({title:f.title,_path:f._path,_file:f._file,children:[],...a(f),...f._draft?{_draft:!0}:{}}),s=i(o);if(e){const f=r[s._path];if(typeof(f==null?void 0:f.navigation)<"u"&&!(f!=null&&f.navigation))return c;if(o._path!=="/"){const m=i(o);s.children.push(m)}Object.assign(s,a(f))}return h.length===1?(c.push(s),c):(h.slice(0,-1).reduce((f,m,y)=>{const v="/"+h.slice(0,y+1).join("/"),w=r[v];if(typeof(w==null?void 0:w.navigation)<"u"&&!w.navigation)return[];let I=f.find(O=>O._path===v);return I||(I={title:me(m),_path:v,_file:o._file,children:[],...a(w)},f.push(I)),I.children},c).push(s),c)},[]);return Y(l)}const ge=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function Y(t){var n;t.forEach(a=>{a._file=a._file.split(".").slice(0,-1).join(".")});const r=t.sort((a,l)=>ge.compare(a._file,l._file));for(const a of r)(n=a.children)!=null&&n.length?Y(a.children):delete a.children,delete a._file;return t}function pe(t){return r=>(r=r||{},t&&t.length?t.filter(n=>typeof r[n]<"u").reduce((n,a)=>Object.assign(n,{[a]:r[a]}),{}):r)}function de(t){return Object.prototype.toString.call(t)==="[object Object]"}const ye=t=>T(t,M().public.content.api.baseURL),we=ne(oe({driver:F()}),"@content");function ve(t){async function r(){const n=new Set(await t.getKeys("cache:")),a=U().getPreviewToken();if(a){const c=await t.getItem(`${a}$`).then(g=>g||{});if(Array.isArray(c.ignoreSources)){const g=c.ignoreSources.map(e=>`cache:${e.trim()}:`);for(const e of n)g.some(i=>e.startsWith(i))&&n.delete(e)}const o=await t.getKeys(`${a}:`),h=await Promise.all(o.map(g=>t.getItem(g)));for(const g of h)n.delete(`cache:${g._id}`),g.__deleted||n.add(`${a}:${g._id}`)}return await Promise.all(Array.from(n).map(c=>t.getItem(c)))}return{storage:t,fetch:N(r),query:n=>G(N(r),{initialParams:n,legacy:!0})}}let R=null,S=null;async function Ie(){return S?await S:R||(S=Ae(),R=await S),R}async function Ae(){const t=H(),{content:r}=M().public,n=ve(we),a=await n.storage.getItem("integrity");if(r.integrity!==+(a||0)){const{contents:l,navigation:c}=await $fetch(ye(r.integrity?`cache.${r.integrity}.json`:"cache.json"));await Promise.all(l.map(o=>n.storage.setItem(`cache:${o._id}`,o))),await n.storage.setItem("navigation",c),await n.storage.setItem("integrity",r.integrity)}return await t.callHook("content:storage",n.storage),n}async function Ke(t){const r=await Ie();if(!U().getPreviewToken()&&Object.keys(t||{}).length===0)return r.storage.getItem("navigation");const n=await r.query(t).where({_partial:!1,navigation:{$ne:!1}}).find(),l=(await r.query().where({_path:/\/_dir$/i,_partial:!0}).find()).reduce((c,o)=>{var g;((g=o.title)==null?void 0:g.toLowerCase())==="dir"&&(o.title=void 0);const h=o._path.split("/").slice(0,-1).join("/")||"/";return c[h]={...o,...o.body},c},{});return he(n,l)}export{we as contentStorage,ve as createDB,Ke as generateNavigation,Ie as useContentDatabase}; diff --git a/_nuxt/C8Cf_uay.js b/_nuxt/V4NJ029S.js similarity index 79% rename from _nuxt/C8Cf_uay.js rename to _nuxt/V4NJ029S.js index 88b423f4..c94752f9 100644 --- a/_nuxt/C8Cf_uay.js +++ b/_nuxt/V4NJ029S.js @@ -1 +1 @@ -import{c as e,o as t,b as o}from"./D6y6W-Zj.js";const s={class:"flex h-[1024px] justify-center border-2 border-gray-500"},c=o("iframe",{src:"https://cmpadden.github.io/conway/",width:"100%",height:"100%"},null,-1),a=[c],d={__name:"conway",setup(r){return(n,_)=>(t(),e("main",s,a))}};export{d as default}; +import{c as e,o as t,b as o}from"./YC8jgtvV.js";const s={class:"flex h-[1024px] justify-center border-2 border-gray-500"},c=o("iframe",{src:"https://cmpadden.github.io/conway/",width:"100%",height:"100%"},null,-1),a=[c],d={__name:"conway",setup(r){return(n,_)=>(t(),e("main",s,a))}};export{d as default}; diff --git a/_nuxt/C7cmTvz1.js b/_nuxt/V6DC4L2r.js similarity index 79% rename from _nuxt/C7cmTvz1.js rename to _nuxt/V6DC4L2r.js index f9899aee..bd98a373 100644 --- a/_nuxt/C7cmTvz1.js +++ b/_nuxt/V6DC4L2r.js @@ -1 +1 @@ -import{d as t,a7 as a}from"./D6y6W-Zj.js";const o=t({__name:"ProseCode",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null}},setup(n){return(e,r)=>a(e.$slots,"default")}});export{o as _}; +import{d as t,a7 as a}from"./YC8jgtvV.js";const o=t({__name:"ProseCode",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null}},setup(n){return(e,r)=>a(e.$slots,"default")}});export{o as _}; diff --git a/_nuxt/6h42708l.js b/_nuxt/VupGr2ZG.js similarity index 89% rename from _nuxt/6h42708l.js rename to _nuxt/VupGr2ZG.js index ad53819a..f23f6238 100644 --- a/_nuxt/6h42708l.js +++ b/_nuxt/VupGr2ZG.js @@ -1 +1 @@ -import{o as t,c as n,b as e,f as r,g as l,h as u,a as h,i as c,v as w,t as g,F as y,r as x,D as k,e as m}from"./D6y6W-Zj.js";function b(o,i){return t(),n("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true","data-slot":"icon"},[e("path",{"fill-rule":"evenodd",d:"M8.914 6.025a.75.75 0 0 1 1.06 0 3.5 3.5 0 0 1 0 4.95l-2 2a3.5 3.5 0 0 1-5.396-4.402.75.75 0 0 1 1.251.827 2 2 0 0 0 3.085 2.514l2-2a2 2 0 0 0 0-2.828.75.75 0 0 1 0-1.06Z","clip-rule":"evenodd"}),e("path",{"fill-rule":"evenodd",d:"M7.086 9.975a.75.75 0 0 1-1.06 0 3.5 3.5 0 0 1 0-4.95l2-2a3.5 3.5 0 0 1 5.396 4.402.75.75 0 0 1-1.251-.827 2 2 0 0 0-3.085-2.514l-2 2a2 2 0 0 0 0 2.828.75.75 0 0 1 0 1.06Z","clip-rule":"evenodd"})])}const M={class:"flex justify-end"},I={__name:"MoreLink",props:{to:{type:String,required:!0}},setup(o){const i=o;return(a,d)=>{const p=c;return t(),n("div",M,[r(p,{to:i.to,class:"flex items-center text-sm font-bold text-white hover:text-orange-500"},{default:l(()=>[u(" More "),r(h(b),{class:"ml-1 h-5 w-5","aria-hidden":"true"})]),_:1},8,["to"])])}}},D={class:"bg-gradient-to-b from-transparent to-background text-white"},j={class:"container mx-auto space-y-4 py-8 text-white"},L={class:"mb-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"},P={class:"h-full rounded-xl bg-black bg-opacity-70 drop-shadow-lg hover:ring-1 hover:ring-white"},V={class:"min-h-28 px-4 pt-4"},B={class:"pb-2 text-xl font-bold"},C=["innerHTML"],N={key:0},S=["src"],T={key:0},q="Experiments",F={__name:"Playground",props:{showImages:{type:Boolean,default:!1},limit:{type:Number,default:null},linkToPlayground:{type:Boolean,default:!1}},setup(o){const i=o,a=[{title:"Conway",description:"Conway's Game of Life",link:"/playground/conway",img:"/images/previews/conway.png"},{title:"wm.spoon",description:"Hammerpoon Window Manager",link:"https://github.com/cmpadden/wm.spoon",img:"/images/previews/wm.spoon.png"},{title:"Metronome",description:"A simple metronome for tracking tempo.",link:"/playground/metronome",img:"/images/previews/metronome.png"},{title:"Conjugations",description:"Search and explore the conjugations of 1000 French verbs",link:"/playground/french",img:"/images/previews/french-conjugations.png"},{title:"Mountains",description:"Visualize a gradient of colored waves generated with Perlin noise",link:"/playground/palettes/mountains",img:"/images/previews/noise.png"},{title:"Spectrogram",description:"Visualize the audio from your microphone as a waveform, frequency bars, and a spectrogram",link:"/playground/audio",img:"/images/previews/microphone.png"},{title:"Waves",description:"Demonstration of using p5.js within Vue.js to visualize trigonometric functions",link:"/playground/waves",img:"/images/previews/waves.png"},{title:"MIDI Chords",description:"Identify the chords being played by your attached MIDI device",link:"/playground/chords",img:"/images/previews/chord-identifier.png"},{title:"MIDI Events",description:"View the MIDI events triggered by a MIDI-controller through the Web MIDI API",link:"/playground/midi",img:"/images/previews/midi-events.png"},{title:"Matrix Multiplication",description:"Step through the process of matrix multiplication",link:"/playground/matrix",img:"/images/previews/matrix-multiplication.png"},{title:"Sequence Plotter",description:"Plot the fist 10,000 digits of Pi, or any sequence of digits, in 2-dimensional space",link:"/playground/plotter",img:"/images/previews/plotter.png"}],d=w(()=>i.limit===null||i.limit<=0?a:a.slice(0,i.limit));return(p,z)=>{const f=c,_=c,v=I;return t(),n("section",D,[e("div",j,[r(f,{to:"/playground",class:"font-mono text-3xl font-semibold lowercase underline decoration-orange-500 underline-offset-4 hover:text-orange-500"},{default:l(()=>[u(g(q))]),_:1}),e("div",L,[(t(!0),n(y,null,x(h(d),s=>(t(),k(_,{key:s.title,to:s.link},{default:l(()=>[e("div",P,[e("div",V,[e("h3",B,g(s.title),1),e("div",{class:"line-clamp-2 text-base font-light",innerHTML:s.description},null,8,C)]),o.showImages?(t(),n("div",N,[e("img",{class:"h-40 w-full rounded-b-xl object-cover object-top grayscale hover:grayscale-0",src:s.img||"images/placeholder.png"},null,8,S)])):m("",!0)])]),_:2},1032,["to"]))),128))]),o.linkToPlayground?(t(),n("div",T,[r(v,{to:"/playground"})])):m("",!0)])])}}};export{I as _,F as a}; +import{o as t,c as n,b as e,i as r,g as l,h as u,a as h,_ as c,k as w,t as g,F as y,r as x,f as k,e as m}from"./YC8jgtvV.js";function b(o,i){return t(),n("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true","data-slot":"icon"},[e("path",{"fill-rule":"evenodd",d:"M8.914 6.025a.75.75 0 0 1 1.06 0 3.5 3.5 0 0 1 0 4.95l-2 2a3.5 3.5 0 0 1-5.396-4.402.75.75 0 0 1 1.251.827 2 2 0 0 0 3.085 2.514l2-2a2 2 0 0 0 0-2.828.75.75 0 0 1 0-1.06Z","clip-rule":"evenodd"}),e("path",{"fill-rule":"evenodd",d:"M7.086 9.975a.75.75 0 0 1-1.06 0 3.5 3.5 0 0 1 0-4.95l2-2a3.5 3.5 0 0 1 5.396 4.402.75.75 0 0 1-1.251-.827 2 2 0 0 0-3.085-2.514l-2 2a2 2 0 0 0 0 2.828.75.75 0 0 1 0 1.06Z","clip-rule":"evenodd"})])}const M={class:"flex justify-end"},I={__name:"MoreLink",props:{to:{type:String,required:!0}},setup(o){const i=o;return(a,d)=>{const p=c;return t(),n("div",M,[r(p,{to:i.to,class:"flex items-center text-sm font-bold text-white hover:text-orange-500"},{default:l(()=>[u(" More "),r(h(b),{class:"ml-1 h-5 w-5","aria-hidden":"true"})]),_:1},8,["to"])])}}},j={class:"bg-gradient-to-b from-transparent to-background text-white"},D={class:"container mx-auto space-y-4 py-8 text-white"},L={class:"mb-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"},P={class:"h-full rounded-xl bg-black bg-opacity-70 drop-shadow-lg hover:ring-1 hover:ring-white"},V={class:"min-h-28 px-4 pt-4"},B={class:"pb-2 text-xl font-bold"},C=["innerHTML"],N={key:0},S=["src"],T={key:0},q="Experiments",F={__name:"Playground",props:{showImages:{type:Boolean,default:!1},limit:{type:Number,default:null},linkToPlayground:{type:Boolean,default:!1}},setup(o){const i=o,a=[{title:"Conway",description:"Conway's Game of Life",link:"/playground/conway",img:"/images/previews/conway.png"},{title:"wm.spoon",description:"Hammerpoon Window Manager",link:"https://github.com/cmpadden/wm.spoon",img:"/images/previews/wm.spoon.png"},{title:"Metronome",description:"A simple metronome for tracking tempo.",link:"/playground/metronome",img:"/images/previews/metronome.png"},{title:"Conjugations",description:"Search and explore the conjugations of 1000 French verbs",link:"/playground/french",img:"/images/previews/french-conjugations.png"},{title:"Mountains",description:"Visualize a gradient of colored waves generated with Perlin noise",link:"/playground/palettes/mountains",img:"/images/previews/noise.png"},{title:"Spectrogram",description:"Visualize the audio from your microphone as a waveform, frequency bars, and a spectrogram",link:"/playground/audio",img:"/images/previews/microphone.png"},{title:"Waves",description:"Demonstration of using p5.js within Vue.js to visualize trigonometric functions",link:"/playground/waves",img:"/images/previews/waves.png"},{title:"MIDI Chords",description:"Identify the chords being played by your attached MIDI device",link:"/playground/chords",img:"/images/previews/chord-identifier.png"},{title:"MIDI Events",description:"View the MIDI events triggered by a MIDI-controller through the Web MIDI API",link:"/playground/midi",img:"/images/previews/midi-events.png"},{title:"Matrix Multiplication",description:"Step through the process of matrix multiplication",link:"/playground/matrix",img:"/images/previews/matrix-multiplication.png"},{title:"Sequence Plotter",description:"Plot the fist 10,000 digits of Pi, or any sequence of digits, in 2-dimensional space",link:"/playground/plotter",img:"/images/previews/plotter.png"}],d=w(()=>i.limit===null||i.limit<=0?a:a.slice(0,i.limit));return(p,z)=>{const _=c,f=c,v=I;return t(),n("section",j,[e("div",D,[r(_,{to:"/playground",class:"font-mono text-3xl font-semibold lowercase underline decoration-orange-500 underline-offset-4 hover:text-orange-500"},{default:l(()=>[u(g(q))]),_:1}),e("div",L,[(t(!0),n(y,null,x(h(d),s=>(t(),k(f,{key:s.title,to:s.link},{default:l(()=>[e("div",P,[e("div",V,[e("h3",B,g(s.title),1),e("div",{class:"line-clamp-2 text-base font-light",innerHTML:s.description},null,8,C)]),o.showImages?(t(),n("div",N,[e("img",{class:"h-40 w-full rounded-b-xl object-cover object-top grayscale hover:grayscale-0",src:s.img||"images/placeholder.png"},null,8,S)])):m("",!0)])]),_:2},1032,["to"]))),128))]),o.linkToPlayground?(t(),n("div",T,[r(v,{to:"/playground"})])):m("",!0)])])}}};export{I as _,F as a}; diff --git a/_nuxt/D6y6W-Zj.js b/_nuxt/YC8jgtvV.js similarity index 72% rename from _nuxt/D6y6W-Zj.js rename to _nuxt/YC8jgtvV.js index 0091309c..2381adf8 100644 --- a/_nuxt/D6y6W-Zj.js +++ b/_nuxt/YC8jgtvV.js @@ -1,58 +1,58 @@ -const __vite__fileDeps=["./3-SVqsS-.js","./CNTXZiWI.js","./C-v3KzvZ.js","./DXU4rfre.js","./DvDH6DOc.js","./BLy52rwp.js","./T8qFVnUA.js","./ElOT_Ul4.js","./_...J8jiN4NX.css","./CkwidRNk.js","./DQRguPdo.js","./6h42708l.js","./wZXg-9-z.js","./Drhxu60M.js","./DGUXyVWA.js","./BTH0oiOj.js","./B_2hsy3K.js","./CzWl7KmD.js","./qnKzmL5n.js","./DZjQgdbh.js","./DHgolSFm.js","./DQnJMeWU.js","./C7cmTvz1.js","./ProsePre.CchFRBtv.css","./Da1yACaU.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./Gb-Mbhdk.js","./DuCNYxTx.js","./C-v3KzvZ.js","./Dnd51l0P.js","./JthqPOXk.js","./DvDH6DOc.js","./Cj9zn9Hh.js","./DjmxGRUG.js","./NquB2IUV.js","./_...J8jiN4NX.css","./CRLNagtS.js","./Ci9WvbVQ.js","./VupGr2ZG.js","./KYfJ1yMs.js","./CmyKjUr8.js","./mpBF_AdW.js","./EFdih8x4.js","./c-8mvODc.js","./Beu9PnWL.js","./CWeMlRBK.js","./CvqFk8MA.js","./BW3Uyh46.js","./C1gyBLca.js","./V6DC4L2r.js","./ProsePre.CchFRBtv.css","./eJFH2hOw.js"])))=>i.map(i=>d[i]); /** -* @vue/shared v3.4.29 +* @vue/shared v3.4.31 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT -**//*! #__NO_SIDE_EFFECTS__ */function Ga(r,d){const w=new Set(r.split(","));return t=>w.has(t)}const Rt={},uo=[],Vr=()=>{},Dh=()=>!1,ss=r=>r.charCodeAt(0)===111&&r.charCodeAt(1)===110&&(r.charCodeAt(2)>122||r.charCodeAt(2)<97),Va=r=>r.startsWith("onUpdate:"),Xt=Object.assign,Ha=(r,d)=>{const w=r.indexOf(d);w>-1&&r.splice(w,1)},Fh=Object.prototype.hasOwnProperty,vt=(r,d)=>Fh.call(r,d),st=Array.isArray,co=r=>is(r)==="[object Map]",zc=r=>is(r)==="[object Set]",Nh=r=>is(r)==="[object RegExp]",at=r=>typeof r=="function",Gt=r=>typeof r=="string",Jn=r=>typeof r=="symbol",Ct=r=>r!==null&&typeof r=="object",za=r=>(Ct(r)||at(r))&&at(r.then)&&at(r.catch),Wc=Object.prototype.toString,is=r=>Wc.call(r),Uh=r=>is(r).slice(8,-1),qc=r=>is(r)==="[object Object]",Wa=r=>Gt(r)&&r!=="NaN"&&r[0]!=="-"&&""+parseInt(r,10)===r,fo=Ga(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),oi=r=>{const d=Object.create(null);return w=>d[w]||(d[w]=r(w))},Bh=/-(\w)/g,an=oi(r=>r.replace(Bh,(d,w)=>w?w.toUpperCase():"")),Gh=/\B([A-Z])/g,jo=oi(r=>r.replace(Gh,"-$1").toLowerCase()),si=oi(r=>r.charAt(0).toUpperCase()+r.slice(1)),Pi=oi(r=>r?`on${si(r)}`:""),Dn=(r,d)=>!Object.is(r,d),ho=(r,...d)=>{for(let w=0;w{Object.defineProperty(r,d,{configurable:!0,enumerable:!1,writable:t,value:w})},oa=r=>{const d=parseFloat(r);return isNaN(d)?r:d},Yc=r=>{const d=Gt(r)?Number(r):NaN;return isNaN(d)?r:d};let du;const $c=()=>du||(du=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function qa(r){if(st(r)){const d={};for(let w=0;w{if(w){const t=w.split(Hh);t.length>1&&(d[t[0].trim()]=t[1].trim())}}),d}function Xn(r){let d="";if(Gt(r))d=r;else if(st(r))for(let w=0;wGt(r)?r:r==null?"":st(r)||Ct(r)&&(r.toString===Wc||!at(r.toString))?JSON.stringify(r,Zc,2):String(r),Zc=(r,d)=>d&&d.__v_isRef?Zc(r,d.value):co(d)?{[`Map(${d.size})`]:[...d.entries()].reduce((w,[t,x],v)=>(w[Ai(t,v)+" =>"]=x,w),{})}:zc(d)?{[`Set(${d.size})`]:[...d.values()].map(w=>Ai(w))}:Jn(d)?Ai(d):Ct(d)&&!st(d)&&!qc(d)?String(d):d,Ai=(r,d="")=>{var w;return Jn(r)?`Symbol(${(w=r.description)!=null?w:d})`:r};/** -* @vue/reactivity v3.4.29 +**//*! #__NO_SIDE_EFFECTS__ */function Ga(r,d){const w=new Set(r.split(","));return t=>w.has(t)}const Rt={},uo=[],Vr=()=>{},Fh=()=>!1,ss=r=>r.charCodeAt(0)===111&&r.charCodeAt(1)===110&&(r.charCodeAt(2)>122||r.charCodeAt(2)<97),Va=r=>r.startsWith("onUpdate:"),Xt=Object.assign,Ha=(r,d)=>{const w=r.indexOf(d);w>-1&&r.splice(w,1)},Nh=Object.prototype.hasOwnProperty,vt=(r,d)=>Nh.call(r,d),st=Array.isArray,co=r=>is(r)==="[object Map]",Hc=r=>is(r)==="[object Set]",Uh=r=>is(r)==="[object RegExp]",at=r=>typeof r=="function",Gt=r=>typeof r=="string",Fn=r=>typeof r=="symbol",Ct=r=>r!==null&&typeof r=="object",za=r=>(Ct(r)||at(r))&&at(r.then)&&at(r.catch),zc=Object.prototype.toString,is=r=>zc.call(r),Bh=r=>is(r).slice(8,-1),Wc=r=>is(r)==="[object Object]",Wa=r=>Gt(r)&&r!=="NaN"&&r[0]!=="-"&&""+parseInt(r,10)===r,fo=Ga(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),oi=r=>{const d=Object.create(null);return w=>d[w]||(d[w]=r(w))},Gh=/-(\w)/g,an=oi(r=>r.replace(Gh,(d,w)=>w?w.toUpperCase():"")),Vh=/\B([A-Z])/g,jo=oi(r=>r.replace(Vh,"-$1").toLowerCase()),si=oi(r=>r.charAt(0).toUpperCase()+r.slice(1)),Pi=oi(r=>r?`on${si(r)}`:""),Dn=(r,d)=>!Object.is(r,d),ho=(r,...d)=>{for(let w=0;w{Object.defineProperty(r,d,{configurable:!0,enumerable:!1,writable:t,value:w})},oa=r=>{const d=parseFloat(r);return isNaN(d)?r:d},Xc=r=>{const d=Gt(r)?Number(r):NaN;return isNaN(d)?r:d};let cu;const Yc=()=>cu||(cu=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function qa(r){if(st(r)){const d={};for(let w=0;w{if(w){const t=w.split(zh);t.length>1&&(d[t[0].trim()]=t[1].trim())}}),d}function Yn(r){let d="";if(Gt(r))d=r;else if(st(r))for(let w=0;w!!(r&&r.__v_isRef===!0),$h=r=>Gt(r)?r:r==null?"":st(r)||Ct(r)&&(r.toString===zc||!at(r.toString))?Kc(r)?$h(r.value):JSON.stringify(r,Zc,2):String(r),Zc=(r,d)=>Kc(d)?Zc(r,d.value):co(d)?{[`Map(${d.size})`]:[...d.entries()].reduce((w,[t,x],v)=>(w[Ai(t,v)+" =>"]=x,w),{})}:Hc(d)?{[`Set(${d.size})`]:[...d.values()].map(w=>Ai(w))}:Fn(d)?Ai(d):Ct(d)&&!st(d)&&!Wc(d)?String(d):d,Ai=(r,d="")=>{var w;return Fn(r)?`Symbol(${(w=r.description)!=null?w:d})`:r};/** +* @vue/reactivity v3.4.31 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT -**/let Lr;class Qc{constructor(d=!1){this.detached=d,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Lr,!d&&Lr&&(this.index=(Lr.scopes||(Lr.scopes=[])).push(this)-1)}get active(){return this._active}run(d){if(this._active){const w=Lr;try{return Lr=this,d()}finally{Lr=w}}}on(){Lr=this}off(){Lr=this.parent}stop(d){if(this._active){let w,t;for(w=0,t=this.effects.length;w=5)break}}this._dirtyLevel===1&&(this._dirtyLevel=0),Nn()}return this._dirtyLevel>=5}set dirty(d){this._dirtyLevel=d?5:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let d=Rn,w=Yn;try{return Rn=!0,Yn=this,this._runnings++,fu(this),this.fn()}finally{hu(this),this._runnings--,Yn=w,Rn=d}}stop(){this.active&&(fu(this),hu(this),this.onStop&&this.onStop(),this.active=!1)}}function Zh(r){return r.value}function fu(r){r._trackId++,r._depsLength=0}function hu(r){if(r.deps.length>r._depsLength){for(let d=r._depsLength;d0){t._dirtyLevel=2;continue}let x;t._dirtyLevel{const w=new Map;return w.cleanup=r,w.computed=d,w},Vs=new WeakMap,$n=Symbol(""),aa=Symbol("");function br(r,d,w){if(Rn&&Yn){let t=Vs.get(r);t||Vs.set(r,t=new Map);let x=t.get(w);x||t.set(w,x=nd(()=>t.delete(w))),td(Yn,x)}}function mn(r,d,w,t,x,v){const s=Vs.get(r);if(!s)return;let c=[];if(d==="clear")c=[...s.values()];else if(w==="length"&&st(r)){const o=Number(t);s.forEach((u,g)=>{(g==="length"||!Jn(g)&&g>=o)&&c.push(u)})}else switch(w!==void 0&&c.push(s.get(w)),d){case"add":st(r)?Wa(w)&&c.push(s.get("length")):(c.push(s.get($n)),co(r)&&c.push(s.get(aa)));break;case"delete":st(r)||(c.push(s.get($n)),co(r)&&c.push(s.get(aa)));break;case"set":co(r)&&c.push(s.get($n));break}Ya();for(const o of c)o&&rd(o,5);$a()}function Qh(r,d){const w=Vs.get(r);return w&&w.get(d)}const Jh=Ga("__proto__,__v_isRef,__isVue"),od=new Set(Object.getOwnPropertyNames(Symbol).filter(r=>r!=="arguments"&&r!=="caller").map(r=>Symbol[r]).filter(Jn)),pu=ep();function ep(){const r={};return["includes","indexOf","lastIndexOf"].forEach(d=>{r[d]=function(...w){const t=bt(this);for(let v=0,s=this.length;v{r[d]=function(...w){Fn(),Ya();const t=bt(this)[d].apply(this,w);return $a(),Nn(),t}}),r}function tp(r){Jn(r)||(r=String(r));const d=bt(this);return br(d,"has",r),d.hasOwnProperty(r)}class sd{constructor(d=!1,w=!1){this._isReadonly=d,this._isShallow=w}get(d,w,t){const x=this._isReadonly,v=this._isShallow;if(w==="__v_isReactive")return!x;if(w==="__v_isReadonly")return x;if(w==="__v_isShallow")return v;if(w==="__v_raw")return t===(x?v?pp:ud:v?ld:ad).get(d)||Object.getPrototypeOf(d)===Object.getPrototypeOf(t)?d:void 0;const s=st(d);if(!x){if(s&&vt(pu,w))return Reflect.get(pu,w,t);if(w==="hasOwnProperty")return tp}const c=Reflect.get(d,w,t);return(Jn(w)?od.has(w):Jh(w))||(x||br(d,"get",w),v)?c:hr(c)?s&&Wa(w)?c:c.value:Ct(c)?x?cd(c):Un(c):c}}class id extends sd{constructor(d=!1){super(!1,d)}set(d,w,t,x){let v=d[w];if(!this._isShallow){const o=go(v);if(!Hs(t)&&!go(t)&&(v=bt(v),t=bt(t)),!st(d)&&hr(v)&&!hr(t))return o?!1:(v.value=t,!0)}const s=st(d)&&Wa(w)?Number(w)r,ii=r=>Reflect.getPrototypeOf(r);function ws(r,d,w=!1,t=!1){r=r.__v_raw;const x=bt(r),v=bt(d);w||(Dn(d,v)&&br(x,"get",d),br(x,"get",v));const{has:s}=ii(x),c=t?Ka:w?Ja:$o;if(s.call(x,d))return c(r.get(d));if(s.call(x,v))return c(r.get(v));r!==x&&r.get(d)}function xs(r,d=!1){const w=this.__v_raw,t=bt(w),x=bt(r);return d||(Dn(r,x)&&br(t,"has",r),br(t,"has",x)),r===x?w.has(r):w.has(r)||w.has(x)}function js(r,d=!1){return r=r.__v_raw,!d&&br(bt(r),"iterate",$n),Reflect.get(r,"size",r)}function mu(r){r=bt(r);const d=bt(this);return ii(d).has.call(d,r)||(d.add(r),mn(d,"add",r,r)),this}function yu(r,d){d=bt(d);const w=bt(this),{has:t,get:x}=ii(w);let v=t.call(w,r);v||(r=bt(r),v=t.call(w,r));const s=x.call(w,r);return w.set(r,d),v?Dn(d,s)&&mn(w,"set",r,d):mn(w,"add",r,d),this}function gu(r){const d=bt(this),{has:w,get:t}=ii(d);let x=w.call(d,r);x||(r=bt(r),x=w.call(d,r)),t&&t.call(d,r);const v=d.delete(r);return x&&mn(d,"delete",r,void 0),v}function vu(){const r=bt(this),d=r.size!==0,w=r.clear();return d&&mn(r,"clear",void 0,void 0),w}function Ss(r,d){return function(t,x){const v=this,s=v.__v_raw,c=bt(s),o=d?Ka:r?Ja:$o;return!r&&br(c,"iterate",$n),s.forEach((u,g)=>t.call(x,o(u),o(g),v))}}function Es(r,d,w){return function(...t){const x=this.__v_raw,v=bt(x),s=co(v),c=r==="entries"||r===Symbol.iterator&&s,o=r==="keys"&&s,u=x[r](...t),g=w?Ka:d?Ja:$o;return!d&&br(v,"iterate",o?aa:$n),{next(){const{value:p,done:n}=u.next();return n?{value:p,done:n}:{value:c?[g(p[0]),g(p[1])]:g(p),done:n}},[Symbol.iterator](){return this}}}}function xn(r){return function(...d){return r==="delete"?!1:r==="clear"?void 0:this}}function ip(){const r={get(v){return ws(this,v)},get size(){return js(this)},has:xs,add:mu,set:yu,delete:gu,clear:vu,forEach:Ss(!1,!1)},d={get(v){return ws(this,v,!1,!0)},get size(){return js(this)},has:xs,add:mu,set:yu,delete:gu,clear:vu,forEach:Ss(!1,!0)},w={get(v){return ws(this,v,!0)},get size(){return js(this,!0)},has(v){return xs.call(this,v,!0)},add:xn("add"),set:xn("set"),delete:xn("delete"),clear:xn("clear"),forEach:Ss(!0,!1)},t={get(v){return ws(this,v,!0,!0)},get size(){return js(this,!0)},has(v){return xs.call(this,v,!0)},add:xn("add"),set:xn("set"),delete:xn("delete"),clear:xn("clear"),forEach:Ss(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(v=>{r[v]=Es(v,!1,!1),w[v]=Es(v,!0,!1),d[v]=Es(v,!1,!0),t[v]=Es(v,!0,!0)}),[r,w,d,t]}const[ap,lp,up,cp]=ip();function Za(r,d){const w=d?r?cp:up:r?lp:ap;return(t,x,v)=>x==="__v_isReactive"?!r:x==="__v_isReadonly"?r:x==="__v_raw"?t:Reflect.get(vt(w,x)&&x in t?w:t,x,v)}const dp={get:Za(!1,!1)},fp={get:Za(!1,!0)},hp={get:Za(!0,!1)};const ad=new WeakMap,ld=new WeakMap,ud=new WeakMap,pp=new WeakMap;function mp(r){switch(r){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function yp(r){return r.__v_skip||!Object.isExtensible(r)?0:mp(Uh(r))}function Un(r){return go(r)?r:Qa(r,!1,np,dp,ad)}function as(r){return Qa(r,!1,sp,fp,ld)}function cd(r){return Qa(r,!0,op,hp,ud)}function Qa(r,d,w,t,x){if(!Ct(r)||r.__v_raw&&!(d&&r.__v_isReactive))return r;const v=x.get(r);if(v)return v;const s=yp(r);if(s===0)return r;const c=new Proxy(r,s===2?t:w);return x.set(r,c),c}function Bo(r){return go(r)?Bo(r.__v_raw):!!(r&&r.__v_isReactive)}function go(r){return!!(r&&r.__v_isReadonly)}function Hs(r){return!!(r&&r.__v_isShallow)}function dd(r){return r?!!r.__v_raw:!1}function bt(r){const d=r&&r.__v_raw;return d?bt(d):r}function gp(r){return Object.isExtensible(r)&&Xc(r,"__v_skip",!0),r}const $o=r=>Ct(r)?Un(r):r,Ja=r=>Ct(r)?cd(r):r;class fd{constructor(d,w,t,x){this.getter=d,this._setter=w,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new Xa(()=>d(this._value),()=>Go(this,this.effect._dirtyLevel===3?3:4)),this.effect.computed=this,this.effect.active=this._cacheable=!x,this.__v_isReadonly=t}get value(){const d=bt(this);return(!d._cacheable||d.effect.dirty)&&Dn(d._value,d._value=d.effect.run())&&Go(d,5),el(d),d.effect._dirtyLevel>=2&&Go(d,3),d._value}set value(d){this._setter(d)}get _dirty(){return this.effect.dirty}set _dirty(d){this.effect.dirty=d}}function vp(r,d,w=!1){let t,x;const v=at(r);return v?(t=r,x=Vr):(t=r.get,x=r.set),new fd(t,x,v||!x,w)}function el(r){var d;Rn&&Yn&&(r=bt(r),td(Yn,(d=r.dep)!=null?d:r.dep=nd(()=>r.dep=void 0,r instanceof fd?r:void 0)))}function Go(r,d=5,w,t){r=bt(r);const x=r.dep;x&&rd(x,d)}function hr(r){return!!(r&&r.__v_isRef===!0)}function mt(r){return hd(r,!1)}function Ko(r){return hd(r,!0)}function hd(r,d){return hr(r)?r:new bp(r,d)}class bp{constructor(d,w){this.__v_isShallow=w,this.dep=void 0,this.__v_isRef=!0,this._rawValue=w?d:bt(d),this._value=w?d:$o(d)}get value(){return el(this),this._value}set value(d){const w=this.__v_isShallow||Hs(d)||go(d);d=w?d:bt(d),Dn(d,this._rawValue)&&(this._rawValue,this._rawValue=d,this._value=w?d:$o(d),Go(this,5))}}function Bt(r){return hr(r)?r.value:r}function v_(r){return at(r)?r():Bt(r)}const _p={get:(r,d,w)=>Bt(Reflect.get(r,d,w)),set:(r,d,w,t)=>{const x=r[d];return hr(x)&&!hr(w)?(x.value=w,!0):Reflect.set(r,d,w,t)}};function pd(r){return Bo(r)?r:new Proxy(r,_p)}class wp{constructor(d){this.dep=void 0,this.__v_isRef=!0;const{get:w,set:t}=d(()=>el(this),()=>Go(this));this._get=w,this._set=t}get value(){return this._get()}set value(d){this._set(d)}}function b_(r){return new wp(r)}function __(r){const d=st(r)?new Array(r.length):{};for(const w in r)d[w]=md(r,w);return d}class xp{constructor(d,w,t){this._object=d,this._key=w,this._defaultValue=t,this.__v_isRef=!0}get value(){const d=this._object[this._key];return d===void 0?this._defaultValue:d}set value(d){this._object[this._key]=d}get dep(){return Qh(bt(this._object),this._key)}}class jp{constructor(d){this._getter=d,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Sp(r,d,w){return hr(r)?r:at(r)?new jp(r):Ct(r)&&arguments.length>1?md(r,d,w):mt(r)}function md(r,d,w){const t=r[d];return hr(t)?t:new xp(r,d,w)}/** -* @vue/runtime-core v3.4.29 +**/let Lr;class Qc{constructor(d=!1){this.detached=d,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Lr,!d&&Lr&&(this.index=(Lr.scopes||(Lr.scopes=[])).push(this)-1)}get active(){return this._active}run(d){if(this._active){const w=Lr;try{return Lr=this,d()}finally{Lr=w}}}on(){Lr=this}off(){Lr=this.parent}stop(d){if(this._active){let w,t;for(w=0,t=this.effects.length;w=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),Un()}return this._dirtyLevel>=4}set dirty(d){this._dirtyLevel=d?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let d=Rn,w=$n;try{return Rn=!0,$n=this,this._runnings++,du(this),this.fn()}finally{fu(this),this._runnings--,$n=w,Rn=d}}stop(){this.active&&(du(this),fu(this),this.onStop&&this.onStop(),this.active=!1)}}function Jh(r){return r.value}function du(r){r._trackId++,r._depsLength=0}function fu(r){if(r.deps.length>r._depsLength){for(let d=r._depsLength;d{const w=new Map;return w.cleanup=r,w.computed=d,w},Vs=new WeakMap,Kn=Symbol(""),aa=Symbol("");function br(r,d,w){if(Rn&&$n){let t=Vs.get(r);t||Vs.set(r,t=new Map);let x=t.get(w);x||t.set(w,x=nd(()=>t.delete(w))),td($n,x)}}function mn(r,d,w,t,x,v){const s=Vs.get(r);if(!s)return;let c=[];if(d==="clear")c=[...s.values()];else if(w==="length"&&st(r)){const o=Number(t);s.forEach((u,g)=>{(g==="length"||!Fn(g)&&g>=o)&&c.push(u)})}else switch(w!==void 0&&c.push(s.get(w)),d){case"add":st(r)?Wa(w)&&c.push(s.get("length")):(c.push(s.get(Kn)),co(r)&&c.push(s.get(aa)));break;case"delete":st(r)||(c.push(s.get(Kn)),co(r)&&c.push(s.get(aa)));break;case"set":co(r)&&c.push(s.get(Kn));break}Ya();for(const o of c)o&&rd(o,4);$a()}function ep(r,d){const w=Vs.get(r);return w&&w.get(d)}const tp=Ga("__proto__,__v_isRef,__isVue"),od=new Set(Object.getOwnPropertyNames(Symbol).filter(r=>r!=="arguments"&&r!=="caller").map(r=>Symbol[r]).filter(Fn)),hu=rp();function rp(){const r={};return["includes","indexOf","lastIndexOf"].forEach(d=>{r[d]=function(...w){const t=bt(this);for(let v=0,s=this.length;v{r[d]=function(...w){Nn(),Ya();const t=bt(this)[d].apply(this,w);return $a(),Un(),t}}),r}function np(r){Fn(r)||(r=String(r));const d=bt(this);return br(d,"has",r),d.hasOwnProperty(r)}class sd{constructor(d=!1,w=!1){this._isReadonly=d,this._isShallow=w}get(d,w,t){const x=this._isReadonly,v=this._isShallow;if(w==="__v_isReactive")return!x;if(w==="__v_isReadonly")return x;if(w==="__v_isShallow")return v;if(w==="__v_raw")return t===(x?v?yp:ud:v?ld:ad).get(d)||Object.getPrototypeOf(d)===Object.getPrototypeOf(t)?d:void 0;const s=st(d);if(!x){if(s&&vt(hu,w))return Reflect.get(hu,w,t);if(w==="hasOwnProperty")return np}const c=Reflect.get(d,w,t);return(Fn(w)?od.has(w):tp(w))||(x||br(d,"get",w),v)?c:hr(c)?s&&Wa(w)?c:c.value:Ct(c)?x?cd(c):Bn(c):c}}class id extends sd{constructor(d=!1){super(!1,d)}set(d,w,t,x){let v=d[w];if(!this._isShallow){const o=go(v);if(!Hs(t)&&!go(t)&&(v=bt(v),t=bt(t)),!st(d)&&hr(v)&&!hr(t))return o?!1:(v.value=t,!0)}const s=st(d)&&Wa(w)?Number(w)r,ii=r=>Reflect.getPrototypeOf(r);function ws(r,d,w=!1,t=!1){r=r.__v_raw;const x=bt(r),v=bt(d);w||(Dn(d,v)&&br(x,"get",d),br(x,"get",v));const{has:s}=ii(x),c=t?Ka:w?Ja:$o;if(s.call(x,d))return c(r.get(d));if(s.call(x,v))return c(r.get(v));r!==x&&r.get(d)}function xs(r,d=!1){const w=this.__v_raw,t=bt(w),x=bt(r);return d||(Dn(r,x)&&br(t,"has",r),br(t,"has",x)),r===x?w.has(r):w.has(r)||w.has(x)}function js(r,d=!1){return r=r.__v_raw,!d&&br(bt(r),"iterate",Kn),Reflect.get(r,"size",r)}function pu(r){r=bt(r);const d=bt(this);return ii(d).has.call(d,r)||(d.add(r),mn(d,"add",r,r)),this}function mu(r,d){d=bt(d);const w=bt(this),{has:t,get:x}=ii(w);let v=t.call(w,r);v||(r=bt(r),v=t.call(w,r));const s=x.call(w,r);return w.set(r,d),v?Dn(d,s)&&mn(w,"set",r,d):mn(w,"add",r,d),this}function yu(r){const d=bt(this),{has:w,get:t}=ii(d);let x=w.call(d,r);x||(r=bt(r),x=w.call(d,r)),t&&t.call(d,r);const v=d.delete(r);return x&&mn(d,"delete",r,void 0),v}function gu(){const r=bt(this),d=r.size!==0,w=r.clear();return d&&mn(r,"clear",void 0,void 0),w}function Ss(r,d){return function(t,x){const v=this,s=v.__v_raw,c=bt(s),o=d?Ka:r?Ja:$o;return!r&&br(c,"iterate",Kn),s.forEach((u,g)=>t.call(x,o(u),o(g),v))}}function Es(r,d,w){return function(...t){const x=this.__v_raw,v=bt(x),s=co(v),c=r==="entries"||r===Symbol.iterator&&s,o=r==="keys"&&s,u=x[r](...t),g=w?Ka:d?Ja:$o;return!d&&br(v,"iterate",o?aa:Kn),{next(){const{value:p,done:n}=u.next();return n?{value:p,done:n}:{value:c?[g(p[0]),g(p[1])]:g(p),done:n}},[Symbol.iterator](){return this}}}}function xn(r){return function(...d){return r==="delete"?!1:r==="clear"?void 0:this}}function lp(){const r={get(v){return ws(this,v)},get size(){return js(this)},has:xs,add:pu,set:mu,delete:yu,clear:gu,forEach:Ss(!1,!1)},d={get(v){return ws(this,v,!1,!0)},get size(){return js(this)},has:xs,add:pu,set:mu,delete:yu,clear:gu,forEach:Ss(!1,!0)},w={get(v){return ws(this,v,!0)},get size(){return js(this,!0)},has(v){return xs.call(this,v,!0)},add:xn("add"),set:xn("set"),delete:xn("delete"),clear:xn("clear"),forEach:Ss(!0,!1)},t={get(v){return ws(this,v,!0,!0)},get size(){return js(this,!0)},has(v){return xs.call(this,v,!0)},add:xn("add"),set:xn("set"),delete:xn("delete"),clear:xn("clear"),forEach:Ss(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(v=>{r[v]=Es(v,!1,!1),w[v]=Es(v,!0,!1),d[v]=Es(v,!1,!0),t[v]=Es(v,!0,!0)}),[r,w,d,t]}const[up,cp,dp,fp]=lp();function Za(r,d){const w=d?r?fp:dp:r?cp:up;return(t,x,v)=>x==="__v_isReactive"?!r:x==="__v_isReadonly"?r:x==="__v_raw"?t:Reflect.get(vt(w,x)&&x in t?w:t,x,v)}const hp={get:Za(!1,!1)},pp={get:Za(!1,!0)},mp={get:Za(!0,!1)};const ad=new WeakMap,ld=new WeakMap,ud=new WeakMap,yp=new WeakMap;function gp(r){switch(r){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function vp(r){return r.__v_skip||!Object.isExtensible(r)?0:gp(Bh(r))}function Bn(r){return go(r)?r:Qa(r,!1,sp,hp,ad)}function as(r){return Qa(r,!1,ap,pp,ld)}function cd(r){return Qa(r,!0,ip,mp,ud)}function Qa(r,d,w,t,x){if(!Ct(r)||r.__v_raw&&!(d&&r.__v_isReactive))return r;const v=x.get(r);if(v)return v;const s=vp(r);if(s===0)return r;const c=new Proxy(r,s===2?t:w);return x.set(r,c),c}function Bo(r){return go(r)?Bo(r.__v_raw):!!(r&&r.__v_isReactive)}function go(r){return!!(r&&r.__v_isReadonly)}function Hs(r){return!!(r&&r.__v_isShallow)}function dd(r){return r?!!r.__v_raw:!1}function bt(r){const d=r&&r.__v_raw;return d?bt(d):r}function bp(r){return Object.isExtensible(r)&&qc(r,"__v_skip",!0),r}const $o=r=>Ct(r)?Bn(r):r,Ja=r=>Ct(r)?cd(r):r;class fd{constructor(d,w,t,x){this.getter=d,this._setter=w,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new Xa(()=>d(this._value),()=>Go(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!x,this.__v_isReadonly=t}get value(){const d=bt(this);return(!d._cacheable||d.effect.dirty)&&Dn(d._value,d._value=d.effect.run())&&Go(d,4),el(d),d.effect._dirtyLevel>=2&&Go(d,2),d._value}set value(d){this._setter(d)}get _dirty(){return this.effect.dirty}set _dirty(d){this.effect.dirty=d}}function _p(r,d,w=!1){let t,x;const v=at(r);return v?(t=r,x=Vr):(t=r.get,x=r.set),new fd(t,x,v||!x,w)}function el(r){var d;Rn&&$n&&(r=bt(r),td($n,(d=r.dep)!=null?d:r.dep=nd(()=>r.dep=void 0,r instanceof fd?r:void 0)))}function Go(r,d=4,w,t){r=bt(r);const x=r.dep;x&&rd(x,d)}function hr(r){return!!(r&&r.__v_isRef===!0)}function mt(r){return hd(r,!1)}function Ko(r){return hd(r,!0)}function hd(r,d){return hr(r)?r:new wp(r,d)}class wp{constructor(d,w){this.__v_isShallow=w,this.dep=void 0,this.__v_isRef=!0,this._rawValue=w?d:bt(d),this._value=w?d:$o(d)}get value(){return el(this),this._value}set value(d){const w=this.__v_isShallow||Hs(d)||go(d);d=w?d:bt(d),Dn(d,this._rawValue)&&(this._rawValue,this._rawValue=d,this._value=w?d:$o(d),Go(this,4))}}function Bt(r){return hr(r)?r.value:r}function b_(r){return at(r)?r():Bt(r)}const xp={get:(r,d,w)=>Bt(Reflect.get(r,d,w)),set:(r,d,w,t)=>{const x=r[d];return hr(x)&&!hr(w)?(x.value=w,!0):Reflect.set(r,d,w,t)}};function pd(r){return Bo(r)?r:new Proxy(r,xp)}class jp{constructor(d){this.dep=void 0,this.__v_isRef=!0;const{get:w,set:t}=d(()=>el(this),()=>Go(this));this._get=w,this._set=t}get value(){return this._get()}set value(d){this._set(d)}}function __(r){return new jp(r)}function w_(r){const d=st(r)?new Array(r.length):{};for(const w in r)d[w]=md(r,w);return d}class Sp{constructor(d,w,t){this._object=d,this._key=w,this._defaultValue=t,this.__v_isRef=!0}get value(){const d=this._object[this._key];return d===void 0?this._defaultValue:d}set value(d){this._object[this._key]=d}get dep(){return ep(bt(this._object),this._key)}}class Ep{constructor(d){this._getter=d,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Tp(r,d,w){return hr(r)?r:at(r)?new Ep(r):Ct(r)&&arguments.length>1?md(r,d,w):mt(r)}function md(r,d,w){const t=r[d];return hr(t)?t:new Sp(r,d,w)}/** +* @vue/runtime-core v3.4.31 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT -**/function Ln(r,d,w,t){try{return t?r(...t):r()}catch(x){So(x,d,w)}}function zr(r,d,w,t){if(at(r)){const x=Ln(r,d,w,t);return x&&za(x)&&x.catch(v=>{So(v,d,w)}),x}if(st(r)){const x=[];for(let v=0;v>>1,x=fr[t],v=Qo(x);vsn&&fr.splice(d,1)}function ua(r){st(r)?po.push(...r):(!Tn||!Tn.includes(r,r.allowRecurse?Wn+1:Wn))&&po.push(r),gd()}function bu(r,d,w=Zo?sn+1:0){for(;wQo(w)-Qo(t));if(po.length=0,Tn){Tn.push(...d);return}for(Tn=d,Wn=0;Wnr.id==null?1/0:r.id,Mp=(r,d)=>{const w=Qo(r)-Qo(d);if(w===0){if(r.pre&&!d.pre)return-1;if(d.pre&&!r.pre)return 1}return w};function vd(r){la=!1,Zo=!0,fr.sort(Mp);try{for(sn=0;snGt(i)?i.trim():i)),p&&(x=w.map(oa))}let c,o=t[c=Pi(d)]||t[c=Pi(an(d))];!o&&v&&(o=t[c=Pi(jo(d))]),o&&zr(o,r,6,x);const u=t[c+"Once"];if(u){if(!r.emitted)r.emitted={};else if(r.emitted[c])return;r.emitted[c]=!0,zr(u,r,6,x)}}function bd(r,d,w=!1){const t=d.emitsCache,x=t.get(r);if(x!==void 0)return x;const v=r.emits;let s={},c=!1;if(!at(r)){const o=u=>{const g=bd(u,d,!0);g&&(c=!0,Xt(s,g))};!w&&d.mixins.length&&d.mixins.forEach(o),r.extends&&o(r.extends),r.mixins&&r.mixins.forEach(o)}return!v&&!c?(Ct(r)&&t.set(r,null),null):(st(v)?v.forEach(o=>s[o]=null):Xt(s,v),Ct(r)&&t.set(r,s),s)}function li(r,d){return!r||!ss(d)?!1:(d=d.slice(2).replace(/Once$/,""),vt(r,d[0].toLowerCase()+d.slice(1))||vt(r,jo(d))||vt(r,d))}let Kt=null,_d=null;function Ws(r){const d=Kt;return Kt=r,_d=r&&r.type.__scopeId||null,d}function Ur(r,d=Kt,w){if(!d||r._n)return r;const t=(...x)=>{t._d&&Ru(-1);const v=Ws(d);let s;try{s=r(...x)}finally{Ws(v),t._d&&Ru(1)}return s};return t._n=!0,t._c=!0,t._d=!0,t}function Ri(r){const{type:d,vnode:w,proxy:t,withProxy:x,propsOptions:[v],slots:s,attrs:c,emit:o,render:u,renderCache:g,props:p,data:n,setupState:i,ctx:a,inheritAttrs:h}=r,m=Ws(r);let l,f;try{if(w.shapeFlag&4){const b=x||t,j=b;l=Br(u.call(j,b,g,p,i,n,a)),f=c}else{const b=d;l=Br(b.length>1?b(p,{attrs:c,slots:s,emit:o}):b(p,null)),f=d.props?c:Pp(c)}}catch(b){zo.length=0,So(b,r,1),l=pt(ar)}let y=l;if(f&&h!==!1){const b=Object.keys(f),{shapeFlag:j}=y;b.length&&j&7&&(v&&b.some(Va)&&(f=Ap(f,v)),y=un(y,f,!1,!0))}return w.dirs&&(y=un(y,null,!1,!0),y.dirs=y.dirs?y.dirs.concat(w.dirs):w.dirs),w.transition&&(y.transition=w.transition),l=y,Ws(m),l}function Op(r,d=!0){let w;for(let t=0;t{let d;for(const w in r)(w==="class"||w==="style"||ss(w))&&((d||(d={}))[w]=r[w]);return d},Ap=(r,d)=>{const w={};for(const t in r)(!Va(t)||!(t.slice(9)in d))&&(w[t]=r[t]);return w};function Rp(r,d,w){const{props:t,children:x,component:v}=r,{props:s,children:c,patchFlag:o}=d,u=v.emitsOptions;if(d.dirs||d.transition)return!0;if(w&&o>=0){if(o&1024)return!0;if(o&16)return t?_u(t,s,u):!!s;if(o&8){const g=d.dynamicProps;for(let p=0;pr.__isSuspense;let da=0;const Dp={name:"Suspense",__isSuspense:!0,process(r,d,w,t,x,v,s,c,o,u){if(r==null)Fp(d,w,t,x,v,s,c,o,u);else{if(v&&v.deps>0&&!r.suspense.isInFallback){d.suspense=r.suspense,d.suspense.vnode=d,d.el=r.el;return}Np(r,d,w,t,x,s,c,o,u)}},hydrate:Up,create:ol,normalize:Bp},nl=Dp;function Jo(r,d){const w=r.props&&r.props[d];at(w)&&w()}function Fp(r,d,w,t,x,v,s,c,o){const{p:u,o:{createElement:g}}=o,p=g("div"),n=r.suspense=ol(r,x,t,d,p,w,v,s,c,o);u(null,n.pendingBranch=r.ssContent,p,null,t,n,v,s),n.deps>0?(Jo(r,"onPending"),Jo(r,"onFallback"),u(null,r.ssFallback,d,w,t,null,v,s),mo(n,r.ssFallback)):n.resolve(!1,!0)}function Np(r,d,w,t,x,v,s,c,{p:o,um:u,o:{createElement:g}}){const p=d.suspense=r.suspense;p.vnode=d,d.el=r.el;const n=d.ssContent,i=d.ssFallback,{activeBranch:a,pendingBranch:h,isInFallback:m,isHydrating:l}=p;if(h)p.pendingBranch=n,Zr(n,h)?(o(h,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0?p.resolve():m&&(l||(o(a,i,w,t,x,null,v,s,c),mo(p,i)))):(p.pendingId=da++,l?(p.isHydrating=!1,p.activeBranch=h):u(h,x,p),p.deps=0,p.effects.length=0,p.hiddenContainer=g("div"),m?(o(null,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0?p.resolve():(o(a,i,w,t,x,null,v,s,c),mo(p,i))):a&&Zr(n,a)?(o(a,n,w,t,x,p,v,s,c),p.resolve(!0)):(o(null,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0&&p.resolve()));else if(a&&Zr(n,a))o(a,n,w,t,x,p,v,s,c),mo(p,n);else if(Jo(d,"onPending"),p.pendingBranch=n,n.shapeFlag&512?p.pendingId=n.component.suspenseId:p.pendingId=da++,o(null,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0)p.resolve();else{const{timeout:f,pendingId:y}=p;f>0?setTimeout(()=>{p.pendingId===y&&p.fallback(i)},f):f===0&&p.fallback(i)}}function ol(r,d,w,t,x,v,s,c,o,u,g=!1){const{p,m:n,um:i,n:a,o:{parentNode:h,remove:m}}=u;let l;const f=Gp(r);f&&d&&d.pendingBranch&&(l=d.pendingId,d.deps++);const y=r.props?Yc(r.props.timeout):void 0,b=v,j={vnode:r,parent:d,parentComponent:w,namespace:s,container:t,hiddenContainer:x,deps:0,pendingId:da++,timeout:typeof y=="number"?y:-1,activeBranch:null,pendingBranch:null,isInFallback:!g,isHydrating:g,isUnmounted:!1,effects:[],resolve(k=!1,E=!1){const{vnode:M,activeBranch:P,pendingBranch:L,pendingId:C,effects:I,parentComponent:A,container:N}=j;let F=!1;j.isHydrating?j.isHydrating=!1:k||(F=P&&L.transition&&L.transition.mode==="out-in",F&&(P.transition.afterLeave=()=>{C===j.pendingId&&(n(L,N,v===b?a(P):v,0),ua(I))}),P&&(h(P.el)!==j.hiddenContainer&&(v=a(P)),i(P,A,j,!0)),F||n(L,N,v,0)),mo(j,L),j.pendingBranch=null,j.isInFallback=!1;let B=j.parent,q=!1;for(;B;){if(B.pendingBranch){B.effects.push(...I),q=!0;break}B=B.parent}!q&&!F&&ua(I),j.effects=[],f&&d&&d.pendingBranch&&l===d.pendingId&&(d.deps--,d.deps===0&&!E&&d.resolve()),Jo(M,"onResolve")},fallback(k){if(!j.pendingBranch)return;const{vnode:E,activeBranch:M,parentComponent:P,container:L,namespace:C}=j;Jo(E,"onFallback");const I=a(M),A=()=>{j.isInFallback&&(p(null,k,L,I,P,null,C,c,o),mo(j,k))},N=k.transition&&k.transition.mode==="out-in";N&&(M.transition.afterLeave=A),j.isInFallback=!0,i(M,P,null,!0),N||A()},move(k,E,M){j.activeBranch&&n(j.activeBranch,k,E,M),j.container=k},next(){return j.activeBranch&&a(j.activeBranch)},registerDep(k,E,M){const P=!!j.pendingBranch;P&&j.deps++;const L=k.vnode.el;k.asyncDep.catch(C=>{So(C,k,0)}).then(C=>{if(k.isUnmounted||j.isUnmounted||j.pendingId!==k.suspenseId)return;k.asyncResolved=!0;const{vnode:I}=k;ba(k,C,!1),L&&(I.el=L);const A=!L&&k.subTree.el;E(k,I,h(L||k.subTree.el),L?null:a(k.subTree),j,s,M),A&&m(A),rl(k,I.el),P&&--j.deps===0&&j.resolve()})},unmount(k,E){j.isUnmounted=!0,j.activeBranch&&i(j.activeBranch,w,k,E),j.pendingBranch&&i(j.pendingBranch,w,k,E)}};return j}function Up(r,d,w,t,x,v,s,c,o){const u=d.suspense=ol(d,t,w,r.parentNode,document.createElement("div"),null,x,v,s,c,!0),g=o(r,u.pendingBranch=d.ssContent,w,u,v,s);return u.deps===0&&u.resolve(!1,!0),g}function Bp(r){const{shapeFlag:d,children:w}=r,t=d&32;r.ssContent=xu(t?w.default:w),r.ssFallback=t?xu(w.fallback):pt(ar)}function xu(r){let d;if(at(r)){const w=bo&&r._c;w&&(r._d=!1,Gr()),r=r(),w&&(r._d=!0,d=Hr,Zd())}return st(r)&&(r=Op(r)),r=Br(r),d&&!r.dynamicChildren&&(r.dynamicChildren=d.filter(w=>w!==r)),r}function Sd(r,d){d&&d.pendingBranch?st(r)?d.effects.push(...r):d.effects.push(r):ua(r)}function mo(r,d){r.activeBranch=d;const{vnode:w,parentComponent:t}=r;let x=d.el;for(;!x&&d.component;)d=d.component.subTree,x=d.el;w.el=x,t&&t.subTree===w&&(t.vnode.el=x,rl(t,x))}function Gp(r){const d=r.props&&r.props.suspensible;return d!=null&&d!==!1}function ui(r,d,w=$t,t=!1){if(w){const x=w[r]||(w[r]=[]),v=d.__weh||(d.__weh=(...s)=>{Fn();const c=Zn(w),o=zr(d,w,r,s);return c(),Nn(),o});return t?x.unshift(v):x.push(v),v}}const yn=r=>(d,w=$t)=>{(!ds||r==="sp")&&ui(r,(...t)=>d(...t),w)},Vp=yn("bm"),Qr=yn("m"),Hp=yn("bu"),Ed=yn("u"),ls=yn("bum"),us=yn("um"),zp=yn("sp"),Wp=yn("rtg"),qp=yn("rtc");function Td(r,d=$t){ui("ec",r,d)}function w_(r,d){if(Kt===null)return r;const w=di(Kt),t=r.dirs||(r.dirs=[]);for(let x=0;xd(s,c,void 0,v));else{const s=Object.keys(r);x=new Array(s.length);for(let c=0,o=s.length;c!!r.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function ft(r){at(r)&&(r={loader:r});const{loader:d,loadingComponent:w,errorComponent:t,delay:x=200,timeout:v,suspensible:s=!0,onError:c}=r;let o=null,u,g=0;const p=()=>(g++,o=null,n()),n=()=>{let i;return o||(i=o=d().catch(a=>{if(a=a instanceof Error?a:new Error(String(a)),c)return new Promise((h,m)=>{c(a,()=>h(p()),()=>m(a),g+1)});throw a}).then(a=>i!==o&&o?o:(a&&(a.__esModule||a[Symbol.toStringTag]==="Module")&&(a=a.default),u=a,a)))};return pr({name:"AsyncComponentWrapper",__asyncLoader:n,get __asyncResolved(){return u},setup(){const i=$t;if(u)return()=>Li(u,i);const a=f=>{o=null,So(f,i,13,!t)};if(s&&i.suspense||ds)return n().then(f=>()=>Li(f,i)).catch(f=>(a(f),()=>t?pt(t,{error:f}):null));const h=mt(!1),m=mt(),l=mt(!!x);return x&&setTimeout(()=>{l.value=!1},x),v!=null&&setTimeout(()=>{if(!h.value&&!m.value){const f=new Error(`Async component timed out after ${v}ms.`);a(f),m.value=f}},v),n().then(()=>{h.value=!0,i.parent&&cs(i.parent.vnode)&&(i.parent.effect.dirty=!0,ai(i.parent.update))}).catch(f=>{a(f),m.value=f}),()=>{if(h.value&&u)return Li(u,i);if(m.value&&t)return pt(t,{error:m.value});if(w&&!l.value)return pt(w)}}})}function Li(r,d){const{ref:w,props:t,children:x,ce:v}=d.vnode,s=pt(r,t,x);return s.ref=w,s.ce=v,delete d.vnode.ce,s}function j_(r,d,w={},t,x){if(Kt.isCE||Kt.parent&&Kn(Kt.parent)&&Kt.parent.isCE)return pt("slot",w,t);let v=r[d];v&&v._c&&(v._d=!1),Gr();const s=v&&kd(v(w)),c=qn(gr,{key:w.key||s&&s.key||`_${d}`},s||[],s&&r._===1?64:-2);return c.scopeId&&(c.slotScopeIds=[c.scopeId+"-s"]),v&&v._c&&(v._d=!0),c}function kd(r){return r.some(d=>_o(d)?!(d.type===ar||d.type===gr&&!kd(d.children)):!0)?r:null}const fa=r=>r?tf(r)?di(r):fa(r.parent):null,Vo=Xt(Object.create(null),{$:r=>r,$el:r=>r.vnode.el,$data:r=>r.data,$props:r=>r.props,$attrs:r=>r.attrs,$slots:r=>r.slots,$refs:r=>r.refs,$parent:r=>fa(r.parent),$root:r=>fa(r.root),$emit:r=>r.emit,$options:r=>sl(r),$forceUpdate:r=>r.f||(r.f=()=>{r.effect.dirty=!0,ai(r.update)}),$nextTick:r=>r.n||(r.n=Fr.bind(r.proxy)),$watch:r=>mm.bind(r)}),Ii=(r,d)=>r!==Rt&&!r.__isScriptSetup&&vt(r,d),Xp={get({_:r},d){if(d==="__v_skip")return!0;const{ctx:w,setupState:t,data:x,props:v,accessCache:s,type:c,appContext:o}=r;let u;if(d[0]!=="$"){const i=s[d];if(i!==void 0)switch(i){case 1:return t[d];case 2:return x[d];case 4:return w[d];case 3:return v[d]}else{if(Ii(t,d))return s[d]=1,t[d];if(x!==Rt&&vt(x,d))return s[d]=2,x[d];if((u=r.propsOptions[0])&&vt(u,d))return s[d]=3,v[d];if(w!==Rt&&vt(w,d))return s[d]=4,w[d];ha&&(s[d]=0)}}const g=Vo[d];let p,n;if(g)return d==="$attrs"&&br(r.attrs,"get",""),g(r);if((p=c.__cssModules)&&(p=p[d]))return p;if(w!==Rt&&vt(w,d))return s[d]=4,w[d];if(n=o.config.globalProperties,vt(n,d))return n[d]},set({_:r},d,w){const{data:t,setupState:x,ctx:v}=r;return Ii(x,d)?(x[d]=w,!0):t!==Rt&&vt(t,d)?(t[d]=w,!0):vt(r.props,d)||d[0]==="$"&&d.slice(1)in r?!1:(v[d]=w,!0)},has({_:{data:r,setupState:d,accessCache:w,ctx:t,appContext:x,propsOptions:v}},s){let c;return!!w[s]||r!==Rt&&vt(r,s)||Ii(d,s)||(c=v[0])&&vt(c,s)||vt(t,s)||vt(Vo,s)||vt(x.config.globalProperties,s)},defineProperty(r,d,w){return w.get!=null?r._.accessCache[d]=0:vt(w,"value")&&this.set(r,d,w.value,null),Reflect.defineProperty(r,d,w)}};function S_(){return Yp().slots}function Yp(){const r=Eo();return r.setupContext||(r.setupContext=nf(r))}function ju(r){return st(r)?r.reduce((d,w)=>(d[w]=null,d),{}):r}function E_(r){const d=Eo();let w=r();return va(),za(w)&&(w=w.catch(t=>{throw Zn(d),t})),[w,()=>Zn(d)]}let ha=!0;function $p(r){const d=sl(r),w=r.proxy,t=r.ctx;ha=!1,d.beforeCreate&&Su(d.beforeCreate,r,"bc");const{data:x,computed:v,methods:s,watch:c,provide:o,inject:u,created:g,beforeMount:p,mounted:n,beforeUpdate:i,updated:a,activated:h,deactivated:m,beforeDestroy:l,beforeUnmount:f,destroyed:y,unmounted:b,render:j,renderTracked:k,renderTriggered:E,errorCaptured:M,serverPrefetch:P,expose:L,inheritAttrs:C,components:I,directives:A,filters:N}=d;if(u&&Kp(u,t,null),s)for(const q in s){const V=s[q];at(V)&&(t[q]=V.bind(w))}if(x){const q=x.call(w,w);Ct(q)&&(r.data=Un(q))}if(ha=!0,v)for(const q in v){const V=v[q],H=at(V)?V.bind(w,w):at(V.get)?V.get.bind(w,w):Vr,Z=!at(V)&&at(V.set)?V.set.bind(w):Vr,ee=jt({get:H,set:Z});Object.defineProperty(t,q,{enumerable:!0,configurable:!0,get:()=>ee.value,set:ue=>ee.value=ue})}if(c)for(const q in c)Md(c[q],t,w,q);if(o){const q=at(o)?o.call(w):o;Reflect.ownKeys(q).forEach(V=>{Wr(V,q[V])})}g&&Su(g,r,"c");function B(q,V){st(V)?V.forEach(H=>q(H.bind(w))):V&&q(V.bind(w))}if(B(Vp,p),B(Qr,n),B(Hp,i),B(Ed,a),B(zd,h),B(Wd,m),B(Td,M),B(qp,k),B(Wp,E),B(ls,f),B(us,b),B(zp,P),st(L))if(L.length){const q=r.exposed||(r.exposed={});L.forEach(V=>{Object.defineProperty(q,V,{get:()=>w[V],set:H=>w[V]=H})})}else r.exposed||(r.exposed={});j&&r.render===Vr&&(r.render=j),C!=null&&(r.inheritAttrs=C),I&&(r.components=I),A&&(r.directives=A)}function Kp(r,d,w=Vr){st(r)&&(r=pa(r));for(const t in r){const x=r[t];let v;Ct(x)?"default"in x?v=Ht(x.from||t,x.default,!0):v=Ht(x.from||t):v=Ht(x),hr(v)?Object.defineProperty(d,t,{enumerable:!0,configurable:!0,get:()=>v.value,set:s=>v.value=s}):d[t]=v}}function Su(r,d,w){zr(st(r)?r.map(t=>t.bind(d.proxy)):r.bind(d.proxy),d,w)}function Md(r,d,w,t){const x=t.includes(".")?Hd(w,t):()=>w[t];if(Gt(r)){const v=d[r];at(v)&&In(x,v)}else if(at(r))In(x,r.bind(w));else if(Ct(r))if(st(r))r.forEach(v=>Md(v,d,w,t));else{const v=at(r.handler)?r.handler.bind(w):d[r.handler];at(v)&&In(x,v,r)}}function sl(r){const d=r.type,{mixins:w,extends:t}=d,{mixins:x,optionsCache:v,config:{optionMergeStrategies:s}}=r.appContext,c=v.get(d);let o;return c?o=c:!x.length&&!w&&!t?o=d:(o={},x.length&&x.forEach(u=>qs(o,u,s,!0)),qs(o,d,s)),Ct(d)&&v.set(d,o),o}function qs(r,d,w,t=!1){const{mixins:x,extends:v}=d;v&&qs(r,v,w,!0),x&&x.forEach(s=>qs(r,s,w,!0));for(const s in d)if(!(t&&s==="expose")){const c=Zp[s]||w&&w[s];r[s]=c?c(r[s],d[s]):d[s]}return r}const Zp={data:Eu,props:Tu,emits:Tu,methods:No,computed:No,beforeCreate:yr,created:yr,beforeMount:yr,mounted:yr,beforeUpdate:yr,updated:yr,beforeDestroy:yr,beforeUnmount:yr,destroyed:yr,unmounted:yr,activated:yr,deactivated:yr,errorCaptured:yr,serverPrefetch:yr,components:No,directives:No,watch:Jp,provide:Eu,inject:Qp};function Eu(r,d){return d?r?function(){return Xt(at(r)?r.call(this,this):r,at(d)?d.call(this,this):d)}:d:r}function Qp(r,d){return No(pa(r),pa(d))}function pa(r){if(st(r)){const d={};for(let w=0;w1)return w&&at(d)?d.call(t&&t.proxy):d}}function Od(){return!!($t||Kt||yo)}const Pd={},Ad=()=>Object.create(Pd),Rd=r=>Object.getPrototypeOf(r)===Pd;function rm(r,d,w,t=!1){const x={},v=Ad();r.propsDefaults=Object.create(null),Ld(r,d,x,v);for(const s in r.propsOptions[0])s in x||(x[s]=void 0);w?r.props=t?x:as(x):r.type.props?r.props=x:r.props=v,r.attrs=v}function nm(r,d,w,t){const{props:x,attrs:v,vnode:{patchFlag:s}}=r,c=bt(x),[o]=r.propsOptions;let u=!1;if((t||s>0)&&!(s&16)){if(s&8){const g=r.vnode.dynamicProps;for(let p=0;p{o=!0;const[n,i]=Id(p,d,!0);Xt(s,n),i&&c.push(...i)};!w&&d.mixins.length&&d.mixins.forEach(g),r.extends&&g(r.extends),r.mixins&&r.mixins.forEach(g)}if(!v&&!o)return Ct(r)&&t.set(r,uo),uo;if(st(v))for(let g=0;g-1,i[1]=h<0||a-1||vt(i,"default"))&&c.push(p)}}}const u=[s,c];return Ct(r)&&t.set(r,u),u}function ku(r){return r[0]!=="$"&&!fo(r)}function Mu(r){return r===null?"null":typeof r=="function"?r.name||"":typeof r=="object"&&r.constructor&&r.constructor.name||""}function Cu(r,d){return Mu(r)===Mu(d)}function Ou(r,d){return st(d)?d.findIndex(w=>Cu(w,r)):at(d)&&Cu(d,r)?0:-1}const Dd=r=>r[0]==="_"||r==="$stable",il=r=>st(r)?r.map(Br):[Br(r)],om=(r,d,w)=>{if(d._n)return d;const t=Ur((...x)=>il(d(...x)),w);return t._c=!1,t},Fd=(r,d,w)=>{const t=r._ctx;for(const x in r){if(Dd(x))continue;const v=r[x];if(at(v))d[x]=om(x,v,t);else if(v!=null){const s=il(v);d[x]=()=>s}}},Nd=(r,d)=>{const w=il(d);r.slots.default=()=>w},sm=(r,d)=>{const w=r.slots=Ad();if(r.vnode.shapeFlag&32){const t=d._;t?(Xt(w,d),Xc(w,"_",t,!0)):Fd(d,w)}else d&&Nd(r,d)},im=(r,d,w)=>{const{vnode:t,slots:x}=r;let v=!0,s=Rt;if(t.shapeFlag&32){const c=d._;c?w&&c===1?v=!1:(Xt(x,d),!w&&c===1&&delete x._):(v=!d.$stable,Fd(d,x)),s=d}else d&&(Nd(r,d),s={default:1});if(v)for(const c in x)!Dd(c)&&s[c]==null&&delete x[c]};function Xs(r,d,w,t,x=!1){if(st(r)){r.forEach((n,i)=>Xs(n,d&&(st(d)?d[i]:d),w,t,x));return}if(Kn(t)&&!x)return;const v=t.shapeFlag&4?di(t.component):t.el,s=x?null:v,{i:c,r:o}=r,u=d&&d.r,g=c.refs===Rt?c.refs={}:c.refs,p=c.setupState;if(u!=null&&u!==o&&(Gt(u)?(g[u]=null,vt(p,u)&&(p[u]=null)):hr(u)&&(u.value=null)),at(o))Ln(o,c,12,[s,g]);else{const n=Gt(o),i=hr(o);if(n||i){const a=()=>{if(r.f){const h=n?vt(p,o)?p[o]:g[o]:o.value;x?st(h)&&Ha(h,v):st(h)?h.includes(v)||h.push(v):n?(g[o]=[v],vt(p,o)&&(p[o]=g[o])):(o.value=[v],r.k&&(g[r.k]=o.value))}else n?(g[o]=s,vt(p,o)&&(p[o]=s)):i&&(o.value=s,r.k&&(g[r.k]=s))};s?(a.id=-1,tr(a,w)):a()}}}let Pu=!1;const oo=()=>{Pu||(console.error("Hydration completed but contains mismatches."),Pu=!0)},am=r=>r.namespaceURI.includes("svg")&&r.tagName!=="foreignObject",lm=r=>r.namespaceURI.includes("MathML"),Ts=r=>{if(am(r))return"svg";if(lm(r))return"mathml"},ks=r=>r.nodeType===8;function um(r){const{mt:d,p:w,o:{patchProp:t,createText:x,nextSibling:v,parentNode:s,remove:c,insert:o,createComment:u}}=r,g=(y,b)=>{if(!b.hasChildNodes()){w(null,y,b),zs(),b._vnode=y;return}p(b.firstChild,y,null,null,null),zs(),b._vnode=y},p=(y,b,j,k,E,M=!1)=>{M=M||!!b.dynamicChildren;const P=ks(y)&&y.data==="[",L=()=>h(y,b,j,k,E,P),{type:C,ref:I,shapeFlag:A,patchFlag:N}=b;let F=y.nodeType;b.el=y,N===-2&&(M=!1,b.dynamicChildren=null);let B=null;switch(C){case vo:F!==3?b.children===""?(o(b.el=x(""),s(y),y),B=y):B=L():(y.data!==b.children&&(oo(),y.data=b.children),B=v(y));break;case ar:f(y)?(B=v(y),l(b.el=y.content.firstChild,y,j)):F!==8||P?B=L():B=v(y);break;case Ho:if(P&&(y=v(y),F=y.nodeType),F===1||F===3){B=y;const q=!b.children.length;for(let V=0;V{M=M||!!b.dynamicChildren;const{type:P,props:L,patchFlag:C,shapeFlag:I,dirs:A,transition:N}=b,F=P==="input"||P==="option";if(F||C!==-1){A&&on(b,null,j,"created");let B=!1;if(f(y)){B=Bd(k,N)&&j&&j.vnode.props&&j.vnode.props.appear;const V=y.content.firstChild;B&&N.beforeEnter(V),l(V,y,j),b.el=y=V}if(I&16&&!(L&&(L.innerHTML||L.textContent))){let V=i(y.firstChild,b,y,j,k,E,M);for(;V;){oo();const H=V;V=V.nextSibling,c(H)}}else I&8&&y.textContent!==b.children&&(oo(),y.textContent=b.children);if(L)if(F||!M||C&48)for(const V in L)(F&&(V.endsWith("value")||V==="indeterminate")||ss(V)&&!fo(V)||V[0]===".")&&t(y,V,null,L[V],void 0,void 0,j);else L.onClick&&t(y,"onClick",null,L.onClick,void 0,void 0,j);let q;(q=L&&L.onVnodeBeforeMount)&&vr(q,j,b),A&&on(b,null,j,"beforeMount"),((q=L&&L.onVnodeMounted)||A||B)&&Sd(()=>{q&&vr(q,j,b),B&&N.enter(y),A&&on(b,null,j,"mounted")},k)}return y.nextSibling},i=(y,b,j,k,E,M,P)=>{P=P||!!b.dynamicChildren;const L=b.children,C=L.length;for(let I=0;I{const{slotScopeIds:P}=b;P&&(E=E?E.concat(P):P);const L=s(y),C=i(v(y),b,L,j,k,E,M);return C&&ks(C)&&C.data==="]"?v(b.anchor=C):(oo(),o(b.anchor=u("]"),L,C),C)},h=(y,b,j,k,E,M)=>{if(oo(),b.el=null,M){const C=m(y);for(;;){const I=v(y);if(I&&I!==C)c(I);else break}}const P=v(y),L=s(y);return c(y),w(null,b,L,P,j,k,Ts(L),E),P},m=(y,b="[",j="]")=>{let k=0;for(;y;)if(y=v(y),y&&ks(y)&&(y.data===b&&k++,y.data===j)){if(k===0)return v(y);k--}return y},l=(y,b,j)=>{const k=b.parentNode;k&&k.replaceChild(y,b);let E=j;for(;E;)E.vnode.el===b&&(E.vnode.el=E.subTree.el=y),E=E.parent},f=y=>y.nodeType===1&&y.tagName.toLowerCase()==="template";return[g,p]}const tr=Sd;function cm(r){return Ud(r)}function dm(r){return Ud(r,um)}function Ud(r,d){const w=$c();w.__VUE__=!0;const{insert:t,remove:x,patchProp:v,createElement:s,createText:c,createComment:o,setText:u,setElementText:g,parentNode:p,nextSibling:n,setScopeId:i=Vr,insertStaticContent:a}=r,h=(K,z,te,le=null,me=null,de=null,ye=void 0,ge=null,ke=!!z.dynamicChildren)=>{if(K===z)return;K&&!Zr(K,z)&&(le=$(K),ue(K,me,de,!0),K=null),z.patchFlag===-2&&(ke=!1,z.dynamicChildren=null);const{type:ve,ref:Ie,shapeFlag:De}=z;switch(ve){case vo:m(K,z,te,le);break;case ar:l(K,z,te,le);break;case Ho:K==null&&f(z,te,le,ye);break;case gr:I(K,z,te,le,me,de,ye,ge,ke);break;default:De&1?j(K,z,te,le,me,de,ye,ge,ke):De&6?A(K,z,te,le,me,de,ye,ge,ke):(De&64||De&128)&&ve.process(K,z,te,le,me,de,ye,ge,ke,ce)}Ie!=null&&me&&Xs(Ie,K&&K.ref,de,z||K,!z)},m=(K,z,te,le)=>{if(K==null)t(z.el=c(z.children),te,le);else{const me=z.el=K.el;z.children!==K.children&&u(me,z.children)}},l=(K,z,te,le)=>{K==null?t(z.el=o(z.children||""),te,le):z.el=K.el},f=(K,z,te,le)=>{[K.el,K.anchor]=a(K.children,z,te,le,K.el,K.anchor)},y=({el:K,anchor:z},te,le)=>{let me;for(;K&&K!==z;)me=n(K),t(K,te,le),K=me;t(z,te,le)},b=({el:K,anchor:z})=>{let te;for(;K&&K!==z;)te=n(K),x(K),K=te;x(z)},j=(K,z,te,le,me,de,ye,ge,ke)=>{z.type==="svg"?ye="svg":z.type==="math"&&(ye="mathml"),K==null?k(z,te,le,me,de,ye,ge,ke):P(K,z,me,de,ye,ge,ke)},k=(K,z,te,le,me,de,ye,ge)=>{let ke,ve;const{props:Ie,shapeFlag:De,transition:Le,dirs:Ne}=K;if(ke=K.el=s(K.type,de,Ie&&Ie.is,Ie),De&8?g(ke,K.children):De&16&&M(K.children,ke,null,le,me,Di(K,de),ye,ge),Ne&&on(K,null,le,"created"),E(ke,K,K.scopeId,ye,le),Ie){for(const xe in Ie)xe!=="value"&&!fo(xe)&&v(ke,xe,null,Ie[xe],de,K.children,le,me,W);"value"in Ie&&v(ke,"value",null,Ie.value,de),(ve=Ie.onVnodeBeforeMount)&&vr(ve,le,K)}Ne&&on(K,null,le,"beforeMount");const Be=Bd(me,Le);Be&&Le.beforeEnter(ke),t(ke,z,te),((ve=Ie&&Ie.onVnodeMounted)||Be||Ne)&&tr(()=>{ve&&vr(ve,le,K),Be&&Le.enter(ke),Ne&&on(K,null,le,"mounted")},me)},E=(K,z,te,le,me)=>{if(te&&i(K,te),le)for(let de=0;de{for(let ve=ke;ve{const ge=z.el=K.el;let{patchFlag:ke,dynamicChildren:ve,dirs:Ie}=z;ke|=K.patchFlag&16;const De=K.props||Rt,Le=z.props||Rt;let Ne;if(te&&Bn(te,!1),(Ne=Le.onVnodeBeforeUpdate)&&vr(Ne,te,z,K),Ie&&on(z,K,te,"beforeUpdate"),te&&Bn(te,!0),ve?L(K.dynamicChildren,ve,ge,te,le,Di(z,me),de):ye||V(K,z,ge,null,te,le,Di(z,me),de,!1),ke>0){if(ke&16)C(ge,z,De,Le,te,le,me);else if(ke&2&&De.class!==Le.class&&v(ge,"class",null,Le.class,me),ke&4&&v(ge,"style",De.style,Le.style,me),ke&8){const Be=z.dynamicProps;for(let xe=0;xe{Ne&&vr(Ne,te,z,K),Ie&&on(z,K,te,"updated")},le)},L=(K,z,te,le,me,de,ye)=>{for(let ge=0;ge{if(te!==le){if(te!==Rt)for(const ge in te)!fo(ge)&&!(ge in le)&&v(K,ge,te[ge],null,ye,z.children,me,de,W);for(const ge in le){if(fo(ge))continue;const ke=le[ge],ve=te[ge];ke!==ve&&ge!=="value"&&v(K,ge,ve,ke,ye,z.children,me,de,W)}"value"in le&&v(K,"value",te.value,le.value,ye)}},I=(K,z,te,le,me,de,ye,ge,ke)=>{const ve=z.el=K?K.el:c(""),Ie=z.anchor=K?K.anchor:c("");let{patchFlag:De,dynamicChildren:Le,slotScopeIds:Ne}=z;Ne&&(ge=ge?ge.concat(Ne):Ne),K==null?(t(ve,te,le),t(Ie,te,le),M(z.children||[],te,Ie,me,de,ye,ge,ke)):De>0&&De&64&&Le&&K.dynamicChildren?(L(K.dynamicChildren,Le,te,me,de,ye,ge),(z.key!=null||me&&z===me.subTree)&&Gd(K,z,!0)):V(K,z,te,Ie,me,de,ye,ge,ke)},A=(K,z,te,le,me,de,ye,ge,ke)=>{z.slotScopeIds=ge,K==null?z.shapeFlag&512?me.ctx.activate(z,te,le,ye,ke):N(z,te,le,me,de,ye,ke):F(K,z,ke)},N=(K,z,te,le,me,de,ye)=>{const ge=K.component=km(K,le,me);if(cs(K)&&(ge.ctx.renderer=ce),Mm(ge),ge.asyncDep){if(me&&me.registerDep(ge,B,ye),!K.el){const ke=ge.subTree=pt(ar);l(null,ke,z,te)}}else B(ge,K,z,te,me,de,ye)},F=(K,z,te)=>{const le=z.component=K.component;if(Rp(K,z,te))if(le.asyncDep&&!le.asyncResolved){q(le,z,te);return}else le.next=z,kp(le.update),le.effect.dirty=!0,le.update();else z.el=K.el,le.vnode=z},B=(K,z,te,le,me,de,ye)=>{const ge=()=>{if(K.isMounted){let{next:Ie,bu:De,u:Le,parent:Ne,vnode:Be}=K;{const se=Vd(K);if(se){Ie&&(Ie.el=Be.el,q(K,Ie,ye)),se.asyncDep.then(()=>{K.isUnmounted||ge()});return}}let xe=Ie,Re;Bn(K,!1),Ie?(Ie.el=Be.el,q(K,Ie,ye)):Ie=Be,De&&ho(De),(Re=Ie.props&&Ie.props.onVnodeBeforeUpdate)&&vr(Re,Ne,Ie,Be),Bn(K,!0);const Ee=Ri(K),re=K.subTree;K.subTree=Ee,h(re,Ee,p(re.el),$(re),K,me,de),Ie.el=Ee.el,xe===null&&rl(K,Ee.el),Le&&tr(Le,me),(Re=Ie.props&&Ie.props.onVnodeUpdated)&&tr(()=>vr(Re,Ne,Ie,Be),me)}else{let Ie;const{el:De,props:Le}=z,{bm:Ne,m:Be,parent:xe}=K,Re=Kn(z);if(Bn(K,!1),Ne&&ho(Ne),!Re&&(Ie=Le&&Le.onVnodeBeforeMount)&&vr(Ie,xe,z),Bn(K,!0),De&&pe){const Ee=()=>{K.subTree=Ri(K),pe(De,K.subTree,K,me,null)};Re?z.type.__asyncLoader().then(()=>!K.isUnmounted&&Ee()):Ee()}else{const Ee=K.subTree=Ri(K);h(null,Ee,te,le,K,me,de),z.el=Ee.el}if(Be&&tr(Be,me),!Re&&(Ie=Le&&Le.onVnodeMounted)){const Ee=z;tr(()=>vr(Ie,xe,Ee),me)}(z.shapeFlag&256||xe&&Kn(xe.vnode)&&xe.vnode.shapeFlag&256)&&K.a&&tr(K.a,me),K.isMounted=!0,z=te=le=null}},ke=K.effect=new Xa(ge,Vr,()=>ai(ve),K.scope),ve=K.update=()=>{ke.dirty&&ke.run()};ve.id=K.uid,Bn(K,!0),ve()},q=(K,z,te)=>{z.component=K;const le=K.vnode.props;K.vnode=z,K.next=null,nm(K,z.props,le,te),im(K,z.children,te),Fn(),bu(K),Nn()},V=(K,z,te,le,me,de,ye,ge,ke=!1)=>{const ve=K&&K.children,Ie=K?K.shapeFlag:0,De=z.children,{patchFlag:Le,shapeFlag:Ne}=z;if(Le>0){if(Le&128){Z(ve,De,te,le,me,de,ye,ge,ke);return}else if(Le&256){H(ve,De,te,le,me,de,ye,ge,ke);return}}Ne&8?(Ie&16&&W(ve,me,de),De!==ve&&g(te,De)):Ie&16?Ne&16?Z(ve,De,te,le,me,de,ye,ge,ke):W(ve,me,de,!0):(Ie&8&&g(te,""),Ne&16&&M(De,te,le,me,de,ye,ge,ke))},H=(K,z,te,le,me,de,ye,ge,ke)=>{K=K||uo,z=z||uo;const ve=K.length,Ie=z.length,De=Math.min(ve,Ie);let Le;for(Le=0;LeIe?W(K,me,de,!0,!1,De):M(z,te,le,me,de,ye,ge,ke,De)},Z=(K,z,te,le,me,de,ye,ge,ke)=>{let ve=0;const Ie=z.length;let De=K.length-1,Le=Ie-1;for(;ve<=De&&ve<=Le;){const Ne=K[ve],Be=z[ve]=ke?Mn(z[ve]):Br(z[ve]);if(Zr(Ne,Be))h(Ne,Be,te,null,me,de,ye,ge,ke);else break;ve++}for(;ve<=De&&ve<=Le;){const Ne=K[De],Be=z[Le]=ke?Mn(z[Le]):Br(z[Le]);if(Zr(Ne,Be))h(Ne,Be,te,null,me,de,ye,ge,ke);else break;De--,Le--}if(ve>De){if(ve<=Le){const Ne=Le+1,Be=NeLe)for(;ve<=De;)ue(K[ve],me,de,!0),ve++;else{const Ne=ve,Be=ve,xe=new Map;for(ve=Be;ve<=Le;ve++){const Se=z[ve]=ke?Mn(z[ve]):Br(z[ve]);Se.key!=null&&xe.set(Se.key,ve)}let Re,Ee=0;const re=Le-Be+1;let se=!1,Q=0;const ae=new Array(re);for(ve=0;ve=re){ue(Se,me,de,!0);continue}let Pe;if(Se.key!=null)Pe=xe.get(Se.key);else for(Re=Be;Re<=Le;Re++)if(ae[Re-Be]===0&&Zr(Se,z[Re])){Pe=Re;break}Pe===void 0?ue(Se,me,de,!0):(ae[Pe-Be]=ve+1,Pe>=Q?Q=Pe:se=!0,h(Se,z[Pe],te,null,me,de,ye,ge,ke),Ee++)}const we=se?fm(ae):uo;for(Re=we.length-1,ve=re-1;ve>=0;ve--){const Se=Be+ve,Pe=z[Se],He=Se+1{const{el:de,type:ye,transition:ge,children:ke,shapeFlag:ve}=K;if(ve&6){ee(K.component.subTree,z,te,le);return}if(ve&128){K.suspense.move(z,te,le);return}if(ve&64){ye.move(K,z,te,ce);return}if(ye===gr){t(de,z,te);for(let De=0;Dege.enter(de),me);else{const{leave:De,delayLeave:Le,afterLeave:Ne}=ge,Be=()=>t(de,z,te),xe=()=>{De(de,()=>{Be(),Ne&&Ne()})};Le?Le(de,Be,xe):xe()}else t(de,z,te)},ue=(K,z,te,le=!1,me=!1)=>{const{type:de,props:ye,ref:ge,children:ke,dynamicChildren:ve,shapeFlag:Ie,patchFlag:De,dirs:Le,memoIndex:Ne}=K;if(ge!=null&&Xs(ge,null,te,K,!0),Ne!=null&&(z.renderCache[Ne]=void 0),Ie&256){z.ctx.deactivate(K);return}const Be=Ie&1&&Le,xe=!Kn(K);let Re;if(xe&&(Re=ye&&ye.onVnodeBeforeUnmount)&&vr(Re,z,K),Ie&6)G(K.component,te,le);else{if(Ie&128){K.suspense.unmount(te,le);return}Be&&on(K,null,z,"beforeUnmount"),Ie&64?K.type.remove(K,z,te,me,ce,le):ve&&(de!==gr||De>0&&De&64)?W(ve,z,te,!1,!0):(de===gr&&De&384||!me&&Ie&16)&&W(ke,z,te),le&&T(K)}(xe&&(Re=ye&&ye.onVnodeUnmounted)||Be)&&tr(()=>{Re&&vr(Re,z,K),Be&&on(K,null,z,"unmounted")},te)},T=K=>{const{type:z,el:te,anchor:le,transition:me}=K;if(z===gr){D(te,le);return}if(z===Ho){b(K);return}const de=()=>{x(te),me&&!me.persisted&&me.afterLeave&&me.afterLeave()};if(K.shapeFlag&1&&me&&!me.persisted){const{leave:ye,delayLeave:ge}=me,ke=()=>ye(te,de);ge?ge(K.el,de,ke):ke()}else de()},D=(K,z)=>{let te;for(;K!==z;)te=n(K),x(K),K=te;x(z)},G=(K,z,te)=>{const{bum:le,scope:me,update:de,subTree:ye,um:ge,m:ke,a:ve}=K;Ys(ke),Ys(ve),le&&ho(le),me.stop(),de&&(de.active=!1,ue(ye,K,z,te)),ge&&tr(ge,z),tr(()=>{K.isUnmounted=!0},z),z&&z.pendingBranch&&!z.isUnmounted&&K.asyncDep&&!K.asyncResolved&&K.suspenseId===z.pendingId&&(z.deps--,z.deps===0&&z.resolve())},W=(K,z,te,le=!1,me=!1,de=0)=>{for(let ye=de;yeK.shapeFlag&6?$(K.component.subTree):K.shapeFlag&128?K.suspense.next():n(K.anchor||K.el);let J=!1;const ne=(K,z,te)=>{K==null?z._vnode&&ue(z._vnode,null,null,!0):h(z._vnode||null,K,z,null,null,null,te),J||(J=!0,bu(),zs(),J=!1),z._vnode=K},ce={p:h,um:ue,m:ee,r:T,mt:N,mc:M,pc:V,pbc:L,n:$,o:r};let ie,pe;return d&&([ie,pe]=d(ce)),{render:ne,hydrate:ie,createApp:tm(ne,ie)}}function Di({type:r,props:d},w){return w==="svg"&&r==="foreignObject"||w==="mathml"&&r==="annotation-xml"&&d&&d.encoding&&d.encoding.includes("html")?void 0:w}function Bn({effect:r,update:d},w){r.allowRecurse=d.allowRecurse=w}function Bd(r,d){return(!r||r&&!r.pendingBranch)&&d&&!d.persisted}function Gd(r,d,w=!1){const t=r.children,x=d.children;if(st(t)&&st(x))for(let v=0;v>1,r[w[c]]0&&(d[t]=w[v-1]),w[v]=t)}}for(v=w.length,s=w[v-1];v-- >0;)w[v]=s,s=d[s];return w}function Vd(r){const d=r.subTree.component;if(d)return d.asyncDep&&!d.asyncResolved?d:Vd(d)}function Ys(r){if(r)for(let d=0;dHt(hm);function ln(r,d){return al(r,null,d)}const Ms={};function In(r,d,w){return al(r,d,w)}function al(r,d,{immediate:w,deep:t,flush:x,once:v,onTrack:s,onTrigger:c}=Rt){if(d&&v){const k=d;d=(...E)=>{k(...E),j()}}const o=$t,u=k=>t===!0?k:On(k,t===!1?1:void 0);let g,p=!1,n=!1;if(hr(r)?(g=()=>r.value,p=Hs(r)):Bo(r)?(g=()=>u(r),p=!0):st(r)?(n=!0,p=r.some(k=>Bo(k)||Hs(k)),g=()=>r.map(k=>{if(hr(k))return k.value;if(Bo(k))return u(k);if(at(k))return Ln(k,o,2)})):at(r)?d?g=()=>Ln(r,o,2):g=()=>(i&&i(),zr(r,o,3,[a])):g=Vr,d&&t){const k=g;g=()=>On(k())}let i,a=k=>{i=y.onStop=()=>{Ln(k,o,4),i=y.onStop=void 0}},h;if(ds)if(a=Vr,d?w&&zr(d,o,3,[g(),n?[]:void 0,a]):g(),x==="sync"){const k=pm();h=k.__watcherHandles||(k.__watcherHandles=[])}else return Vr;let m=n?new Array(r.length).fill(Ms):Ms;const l=()=>{if(!(!y.active||!y.dirty))if(d){const k=y.run();(t||p||(n?k.some((E,M)=>Dn(E,m[M])):Dn(k,m)))&&(i&&i(),zr(d,o,3,[k,m===Ms?void 0:n&&m[0]===Ms?[]:m,a]),m=k)}else y.run()};l.allowRecurse=!!d;let f;x==="sync"?f=l:x==="post"?f=()=>tr(l,o&&o.suspense):(l.pre=!0,o&&(l.id=o.uid),f=()=>ai(l));const y=new Xa(g,Vr,f),b=Kh(),j=()=>{y.stop(),b&&Ha(b.effects,y)};return d?w?l():m=y.run():x==="post"?tr(y.run.bind(y),o&&o.suspense):y.run(),h&&h.push(j),j}function mm(r,d,w){const t=this.proxy,x=Gt(r)?r.includes(".")?Hd(t,r):()=>t[r]:r.bind(t,t);let v;at(d)?v=d:(v=d.handler,w=d);const s=Zn(this),c=al(x,v.bind(t),w);return s(),c}function Hd(r,d){const w=d.split(".");return()=>{let t=r;for(let x=0;x{On(t,d,w)});else if(qc(r)){for(const t in r)On(r[t],d,w);for(const t of Object.getOwnPropertySymbols(r))Object.prototype.propertyIsEnumerable.call(r,t)&&On(r[t],d,w)}return r}const cs=r=>r.type.__isKeepAlive,ym={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(r,{slots:d}){const w=Eo(),t=w.ctx;if(!t.renderer)return()=>{const f=d.default&&d.default();return f&&f.length===1?f[0]:f};const x=new Map,v=new Set;let s=null;const c=w.suspense,{renderer:{p:o,m:u,um:g,o:{createElement:p}}}=t,n=p("div");t.activate=(f,y,b,j,k)=>{const E=f.component;u(f,y,b,0,c),o(E.vnode,f,y,b,E,c,j,f.slotScopeIds,k),tr(()=>{E.isDeactivated=!1,E.a&&ho(E.a);const M=f.props&&f.props.onVnodeMounted;M&&vr(M,E.parent,f)},c)},t.deactivate=f=>{const y=f.component;Ys(y.m),Ys(y.a),u(f,n,null,1,c),tr(()=>{y.da&&ho(y.da);const b=f.props&&f.props.onVnodeUnmounted;b&&vr(b,y.parent,f),y.isDeactivated=!0},c)};function i(f){Fi(f),g(f,w,c,!0)}function a(f){x.forEach((y,b)=>{const j=_a(y.type);j&&(!f||!f(j))&&h(b)})}function h(f){const y=x.get(f);!s||!Zr(y,s)?i(y):s&&Fi(s),x.delete(f),v.delete(f)}In(()=>[r.include,r.exclude],([f,y])=>{f&&a(b=>Uo(f,b)),y&&a(b=>!Uo(y,b))},{flush:"post",deep:!0});let m=null;const l=()=>{m!=null&&(ca(w.subTree.type)?tr(()=>{x.set(m,Cs(w.subTree))},w.subTree.suspense):x.set(m,Cs(w.subTree)))};return Qr(l),Ed(l),ls(()=>{x.forEach(f=>{const{subTree:y,suspense:b}=w,j=Cs(y);if(f.type===j.type&&f.key===j.key){Fi(j);const k=j.component.da;k&&tr(k,b);return}i(f)})}),()=>{if(m=null,!d.default)return null;const f=d.default(),y=f[0];if(f.length>1)return s=null,f;if(!_o(y)||!(y.shapeFlag&4)&&!(y.shapeFlag&128))return s=null,y;let b=Cs(y);const j=b.type,k=_a(Kn(b)?b.type.__asyncResolved||{}:j),{include:E,exclude:M,max:P}=r;if(E&&(!k||!Uo(E,k))||M&&k&&Uo(M,k))return s=b,y;const L=b.key==null?j:b.key,C=x.get(L);return b.el&&(b=un(b),y.shapeFlag&128&&(y.ssContent=b)),m=L,C?(b.el=C.el,b.component=C.component,b.transition&&es(b,b.transition),b.shapeFlag|=512,v.delete(L),v.add(L)):(v.add(L),P&&v.size>parseInt(P,10)&&h(v.values().next().value)),b.shapeFlag|=256,s=b,ca(y.type)?y:b}}},gm=ym;function Uo(r,d){return st(r)?r.some(w=>Uo(w,d)):Gt(r)?r.split(",").includes(d):Nh(r)?r.test(d):!1}function zd(r,d){qd(r,"a",d)}function Wd(r,d){qd(r,"da",d)}function qd(r,d,w=$t){const t=r.__wdc||(r.__wdc=()=>{let x=w;for(;x;){if(x.isDeactivated)return;x=x.parent}return r()});if(ui(d,t,w),w){let x=w.parent;for(;x&&x.parent;)cs(x.parent.vnode)&&vm(t,d,w,x),x=x.parent}}function vm(r,d,w,t){const x=ui(d,r,t,!0);us(()=>{Ha(t[d],x)},w)}function Fi(r){r.shapeFlag&=-257,r.shapeFlag&=-513}function Cs(r){return r.shapeFlag&128?r.ssContent:r}const kn=Symbol("_leaveCb"),Os=Symbol("_enterCb");function bm(){const r={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Qr(()=>{r.isMounted=!0}),ls(()=>{r.isUnmounting=!0}),r}const Nr=[Function,Array],Xd={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Nr,onEnter:Nr,onAfterEnter:Nr,onEnterCancelled:Nr,onBeforeLeave:Nr,onLeave:Nr,onAfterLeave:Nr,onLeaveCancelled:Nr,onBeforeAppear:Nr,onAppear:Nr,onAfterAppear:Nr,onAppearCancelled:Nr},Yd=r=>{const d=r.subTree;return d.component?Yd(d.component):d},_m={name:"BaseTransition",props:Xd,setup(r,{slots:d}){const w=Eo(),t=bm();return()=>{const x=d.default&&Kd(d.default(),!0);if(!x||!x.length)return;let v=x[0];if(x.length>1){for(const n of x)if(n.type!==ar){v=n;break}}const s=bt(r),{mode:c}=s;if(t.isLeaving)return Ni(v);const o=Au(v);if(!o)return Ni(v);let u=ya(o,s,t,w,n=>u=n);es(o,u);const g=w.subTree,p=g&&Au(g);if(p&&p.type!==ar&&!Zr(o,p)&&Yd(w).type!==ar){const n=ya(p,s,t,w);if(es(p,n),c==="out-in"&&o.type!==ar)return t.isLeaving=!0,n.afterLeave=()=>{t.isLeaving=!1,w.update.active!==!1&&(w.effect.dirty=!0,w.update())},Ni(v);c==="in-out"&&o.type!==ar&&(n.delayLeave=(i,a,h)=>{const m=$d(t,p);m[String(p.key)]=p,i[kn]=()=>{a(),i[kn]=void 0,delete u.delayedLeave},u.delayedLeave=h})}return v}}},wm=_m;function $d(r,d){const{leavingVNodes:w}=r;let t=w.get(d.type);return t||(t=Object.create(null),w.set(d.type,t)),t}function ya(r,d,w,t,x){const{appear:v,mode:s,persisted:c=!1,onBeforeEnter:o,onEnter:u,onAfterEnter:g,onEnterCancelled:p,onBeforeLeave:n,onLeave:i,onAfterLeave:a,onLeaveCancelled:h,onBeforeAppear:m,onAppear:l,onAfterAppear:f,onAppearCancelled:y}=d,b=String(r.key),j=$d(w,r),k=(P,L)=>{P&&zr(P,t,9,L)},E=(P,L)=>{const C=L[1];k(P,L),st(P)?P.every(I=>I.length<=1)&&C():P.length<=1&&C()},M={mode:s,persisted:c,beforeEnter(P){let L=o;if(!w.isMounted)if(v)L=m||o;else return;P[kn]&&P[kn](!0);const C=j[b];C&&Zr(r,C)&&C.el[kn]&&C.el[kn](),k(L,[P])},enter(P){let L=u,C=g,I=p;if(!w.isMounted)if(v)L=l||u,C=f||g,I=y||p;else return;let A=!1;const N=P[Os]=F=>{A||(A=!0,F?k(I,[P]):k(C,[P]),M.delayedLeave&&M.delayedLeave(),P[Os]=void 0)};L?E(L,[P,N]):N()},leave(P,L){const C=String(r.key);if(P[Os]&&P[Os](!0),w.isUnmounting)return L();k(n,[P]);let I=!1;const A=P[kn]=N=>{I||(I=!0,L(),N?k(h,[P]):k(a,[P]),P[kn]=void 0,j[C]===r&&delete j[C])};j[C]=r,i?E(i,[P,A]):A()},clone(P){const L=ya(P,d,w,t,x);return x&&x(L),L}};return M}function Ni(r){if(cs(r))return r=un(r),r.children=null,r}function Au(r){if(!cs(r))return r;const{shapeFlag:d,children:w}=r;if(w){if(d&16)return w[0];if(d&32&&at(w.default))return w.default()}}function es(r,d){r.shapeFlag&6&&r.component?es(r.component.subTree,d):r.shapeFlag&128?(r.ssContent.transition=d.clone(r.ssContent),r.ssFallback.transition=d.clone(r.ssFallback)):r.transition=d}function Kd(r,d=!1,w){let t=[],x=0;for(let v=0;v1)for(let v=0;vr.__isTeleport,gr=Symbol.for("v-fgt"),vo=Symbol.for("v-txt"),ar=Symbol.for("v-cmt"),Ho=Symbol.for("v-stc"),zo=[];let Hr=null;function Gr(r=!1){zo.push(Hr=r?null:[])}function Zd(){zo.pop(),Hr=zo[zo.length-1]||null}let bo=1;function Ru(r){bo+=r}function Qd(r){return r.dynamicChildren=bo>0?Hr||uo:null,Zd(),bo>0&&Hr&&Hr.push(r),r}function ci(r,d,w,t,x,v){return Qd(Lt(r,d,w,t,x,v,!0))}function qn(r,d,w,t,x){return Qd(pt(r,d,w,t,x,!0))}function _o(r){return r?r.__v_isVNode===!0:!1}function Zr(r,d){return r.type===d.type&&r.key===d.key}const Jd=({key:r})=>r??null,Fs=({ref:r,ref_key:d,ref_for:w})=>(typeof r=="number"&&(r=""+r),r!=null?Gt(r)||hr(r)||at(r)?{i:Kt,r,k:d,f:!!w}:r:null);function Lt(r,d=null,w=null,t=0,x=null,v=r===gr?0:1,s=!1,c=!1){const o={__v_isVNode:!0,__v_skip:!0,type:r,props:d,key:d&&Jd(d),ref:d&&Fs(d),scopeId:_d,slotScopeIds:null,children:w,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:v,patchFlag:t,dynamicProps:x,dynamicChildren:null,appContext:null,ctx:Kt};return c?(ll(o,w),v&128&&r.normalize(o)):w&&(o.shapeFlag|=Gt(w)?8:16),bo>0&&!s&&Hr&&(o.patchFlag>0||v&6)&&o.patchFlag!==32&&Hr.push(o),o}const pt=jm;function jm(r,d=null,w=null,t=0,x=null,v=!1){if((!r||r===xd)&&(r=ar),_o(r)){const c=un(r,d,!0);return w&&ll(c,w),bo>0&&!v&&Hr&&(c.shapeFlag&6?Hr[Hr.indexOf(r)]=c:Hr.push(c)),c.patchFlag=-2,c}if(Pm(r)&&(r=r.__vccOpts),d){d=Sm(d);let{class:c,style:o}=d;c&&!Gt(c)&&(d.class=Xn(c)),Ct(o)&&(dd(o)&&!st(o)&&(o=Xt({},o)),d.style=qa(o))}const s=Gt(r)?1:ca(r)?128:xm(r)?64:Ct(r)?4:at(r)?2:0;return Lt(r,d,w,t,x,s,v,!0)}function Sm(r){return r?dd(r)||Rd(r)?Xt({},r):r:null}function un(r,d,w=!1,t=!1){const{props:x,ref:v,patchFlag:s,children:c,transition:o}=r,u=d?ef(x||{},d):x,g={__v_isVNode:!0,__v_skip:!0,type:r.type,props:u,key:u&&Jd(u),ref:d&&d.ref?w&&v?st(v)?v.concat(Fs(d)):[v,Fs(d)]:Fs(d):v,scopeId:r.scopeId,slotScopeIds:r.slotScopeIds,children:c,target:r.target,targetAnchor:r.targetAnchor,staticCount:r.staticCount,shapeFlag:r.shapeFlag,patchFlag:d&&r.type!==gr?s===-1?16:s|16:s,dynamicProps:r.dynamicProps,dynamicChildren:r.dynamicChildren,appContext:r.appContext,dirs:r.dirs,transition:o,component:r.component,suspense:r.suspense,ssContent:r.ssContent&&un(r.ssContent),ssFallback:r.ssFallback&&un(r.ssFallback),el:r.el,anchor:r.anchor,ctx:r.ctx,ce:r.ce};return o&&t&&es(g,o.clone(g)),g}function ao(r=" ",d=0){return pt(vo,null,r,d)}function T_(r,d){const w=pt(Ho,null,r);return w.staticCount=d,w}function k_(r="",d=!1){return d?(Gr(),qn(ar,null,r)):pt(ar,null,r)}function Br(r){return r==null||typeof r=="boolean"?pt(ar):st(r)?pt(gr,null,r.slice()):typeof r=="object"?Mn(r):pt(vo,null,String(r))}function Mn(r){return r.el===null&&r.patchFlag!==-1||r.memo?r:un(r)}function ll(r,d){let w=0;const{shapeFlag:t}=r;if(d==null)d=null;else if(st(d))w=16;else if(typeof d=="object")if(t&65){const x=d.default;x&&(x._c&&(x._d=!1),ll(r,x()),x._c&&(x._d=!0));return}else{w=32;const x=d._;!x&&!Rd(d)?d._ctx=Kt:x===3&&Kt&&(Kt.slots._===1?d._=1:(d._=2,r.patchFlag|=1024))}else at(d)?(d={default:d,_ctx:Kt},w=32):(d=String(d),t&64?(w=16,d=[ao(d)]):w=8);r.children=d,r.shapeFlag|=w}function ef(...r){const d={};for(let w=0;w$t||Kt;let $s,ga;{const r=$c(),d=(w,t)=>{let x;return(x=r[w])||(x=r[w]=[]),x.push(t),v=>{x.length>1?x.forEach(s=>s(v)):x[0](v)}};$s=d("__VUE_INSTANCE_SETTERS__",w=>$t=w),ga=d("__VUE_SSR_SETTERS__",w=>ds=w)}const Zn=r=>{const d=$t;return $s(r),r.scope.on(),()=>{r.scope.off(),$s(d)}},va=()=>{$t&&$t.scope.off(),$s(null)};function tf(r){return r.vnode.shapeFlag&4}let ds=!1;function Mm(r,d=!1){d&&ga(d);const{props:w,children:t}=r.vnode,x=tf(r);rm(r,w,x,d),sm(r,t);const v=x?Cm(r,d):void 0;return d&&ga(!1),v}function Cm(r,d){const w=r.type;r.accessCache=Object.create(null),r.proxy=new Proxy(r.ctx,Xp);const{setup:t}=w;if(t){const x=r.setupContext=t.length>1?nf(r):null,v=Zn(r);Fn();const s=Ln(t,r,0,[r.props,x]);if(Nn(),v(),za(s)){if(s.then(va,va),d)return s.then(c=>{ba(r,c,d)}).catch(c=>{So(c,r,0)});r.asyncDep=s}else ba(r,s,d)}else rf(r,d)}function ba(r,d,w){at(d)?r.type.__ssrInlineRender?r.ssrRender=d:r.render=d:Ct(d)&&(r.setupState=pd(d)),rf(r,w)}let Lu;function rf(r,d,w){const t=r.type;if(!r.render){if(!d&&Lu&&!t.render){const x=t.template||sl(r).template;if(x){const{isCustomElement:v,compilerOptions:s}=r.appContext.config,{delimiters:c,compilerOptions:o}=t,u=Xt(Xt({isCustomElement:v,delimiters:c},s),o);t.render=Lu(x,u)}}r.render=t.render||Vr}{const x=Zn(r);Fn();try{$p(r)}finally{Nn(),x()}}}const Om={get(r,d){return br(r,"get",""),r[d]}};function nf(r){const d=w=>{r.exposed=w||{}};return{attrs:new Proxy(r.attrs,Om),slots:r.slots,emit:r.emit,expose:d}}function di(r){return r.exposed?r.exposeProxy||(r.exposeProxy=new Proxy(pd(gp(r.exposed)),{get(d,w){if(w in d)return d[w];if(w in Vo)return Vo[w](r)},has(d,w){return w in d||w in Vo}})):r.proxy}function _a(r,d=!0){return at(r)?r.displayName||r.name:r.name||d&&r.__name}function Pm(r){return at(r)&&"__vccOpts"in r}const jt=(r,d)=>vp(r,d,ds);function rr(r,d,w){const t=arguments.length;return t===2?Ct(d)&&!st(d)?_o(d)?pt(r,null,[d]):pt(r,d):pt(r,null,d):(t>3?w=Array.prototype.slice.call(arguments,2):t===3&&_o(w)&&(w=[w]),pt(r,d,w))}const of="3.4.29";/** -* @vue/runtime-dom v3.4.29 +**/function Ln(r,d,w,t){try{return t?r(...t):r()}catch(x){So(x,d,w)}}function zr(r,d,w,t){if(at(r)){const x=Ln(r,d,w,t);return x&&za(x)&&x.catch(v=>{So(v,d,w)}),x}if(st(r)){const x=[];for(let v=0;v>>1,x=fr[t],v=Qo(x);vsn&&fr.splice(d,1)}function ua(r){st(r)?po.push(...r):(!Tn||!Tn.includes(r,r.allowRecurse?qn+1:qn))&&po.push(r),gd()}function vu(r,d,w=Zo?sn+1:0){for(;wQo(w)-Qo(t));if(po.length=0,Tn){Tn.push(...d);return}for(Tn=d,qn=0;qnr.id==null?1/0:r.id,Op=(r,d)=>{const w=Qo(r)-Qo(d);if(w===0){if(r.pre&&!d.pre)return-1;if(d.pre&&!r.pre)return 1}return w};function vd(r){la=!1,Zo=!0,fr.sort(Op);try{for(sn=0;snGt(i)?i.trim():i)),p&&(x=w.map(oa))}let c,o=t[c=Pi(d)]||t[c=Pi(an(d))];!o&&v&&(o=t[c=Pi(jo(d))]),o&&zr(o,r,6,x);const u=t[c+"Once"];if(u){if(!r.emitted)r.emitted={};else if(r.emitted[c])return;r.emitted[c]=!0,zr(u,r,6,x)}}function bd(r,d,w=!1){const t=d.emitsCache,x=t.get(r);if(x!==void 0)return x;const v=r.emits;let s={},c=!1;if(!at(r)){const o=u=>{const g=bd(u,d,!0);g&&(c=!0,Xt(s,g))};!w&&d.mixins.length&&d.mixins.forEach(o),r.extends&&o(r.extends),r.mixins&&r.mixins.forEach(o)}return!v&&!c?(Ct(r)&&t.set(r,null),null):(st(v)?v.forEach(o=>s[o]=null):Xt(s,v),Ct(r)&&t.set(r,s),s)}function li(r,d){return!r||!ss(d)?!1:(d=d.slice(2).replace(/Once$/,""),vt(r,d[0].toLowerCase()+d.slice(1))||vt(r,jo(d))||vt(r,d))}let Kt=null,_d=null;function Ws(r){const d=Kt;return Kt=r,_d=r&&r.type.__scopeId||null,d}function Ur(r,d=Kt,w){if(!d||r._n)return r;const t=(...x)=>{t._d&&Au(-1);const v=Ws(d);let s;try{s=r(...x)}finally{Ws(v),t._d&&Au(1)}return s};return t._n=!0,t._c=!0,t._d=!0,t}function Ri(r){const{type:d,vnode:w,proxy:t,withProxy:x,propsOptions:[v],slots:s,attrs:c,emit:o,render:u,renderCache:g,props:p,data:n,setupState:i,ctx:a,inheritAttrs:h}=r,y=Ws(r);let l,f;try{if(w.shapeFlag&4){const b=x||t,j=b;l=Br(u.call(j,b,g,p,i,n,a)),f=c}else{const b=d;l=Br(b.length>1?b(p,{attrs:c,slots:s,emit:o}):b(p,null)),f=d.props?c:Rp(c)}}catch(b){zo.length=0,So(b,r,1),l=pt(ar)}let m=l;if(f&&h!==!1){const b=Object.keys(f),{shapeFlag:j}=m;b.length&&j&7&&(v&&b.some(Va)&&(f=Lp(f,v)),m=un(m,f,!1,!0))}return w.dirs&&(m=un(m,null,!1,!0),m.dirs=m.dirs?m.dirs.concat(w.dirs):w.dirs),w.transition&&(m.transition=w.transition),l=m,Ws(y),l}function Ap(r,d=!0){let w;for(let t=0;t{let d;for(const w in r)(w==="class"||w==="style"||ss(w))&&((d||(d={}))[w]=r[w]);return d},Lp=(r,d)=>{const w={};for(const t in r)(!Va(t)||!(t.slice(9)in d))&&(w[t]=r[t]);return w};function Ip(r,d,w){const{props:t,children:x,component:v}=r,{props:s,children:c,patchFlag:o}=d,u=v.emitsOptions;if(d.dirs||d.transition)return!0;if(w&&o>=0){if(o&1024)return!0;if(o&16)return t?bu(t,s,u):!!s;if(o&8){const g=d.dynamicProps;for(let p=0;pr.__isSuspense;let da=0;const Np={name:"Suspense",__isSuspense:!0,process(r,d,w,t,x,v,s,c,o,u){if(r==null)Up(d,w,t,x,v,s,c,o,u);else{if(v&&v.deps>0&&!r.suspense.isInFallback){d.suspense=r.suspense,d.suspense.vnode=d,d.el=r.el;return}Bp(r,d,w,t,x,s,c,o,u)}},hydrate:Gp,normalize:Vp},nl=Np;function Jo(r,d){const w=r.props&&r.props[d];at(w)&&w()}function Up(r,d,w,t,x,v,s,c,o){const{p:u,o:{createElement:g}}=o,p=g("div"),n=r.suspense=Sd(r,x,t,d,p,w,v,s,c,o);u(null,n.pendingBranch=r.ssContent,p,null,t,n,v,s),n.deps>0?(Jo(r,"onPending"),Jo(r,"onFallback"),u(null,r.ssFallback,d,w,t,null,v,s),mo(n,r.ssFallback)):n.resolve(!1,!0)}function Bp(r,d,w,t,x,v,s,c,{p:o,um:u,o:{createElement:g}}){const p=d.suspense=r.suspense;p.vnode=d,d.el=r.el;const n=d.ssContent,i=d.ssFallback,{activeBranch:a,pendingBranch:h,isInFallback:y,isHydrating:l}=p;if(h)p.pendingBranch=n,Zr(n,h)?(o(h,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0?p.resolve():y&&(l||(o(a,i,w,t,x,null,v,s,c),mo(p,i)))):(p.pendingId=da++,l?(p.isHydrating=!1,p.activeBranch=h):u(h,x,p),p.deps=0,p.effects.length=0,p.hiddenContainer=g("div"),y?(o(null,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0?p.resolve():(o(a,i,w,t,x,null,v,s,c),mo(p,i))):a&&Zr(n,a)?(o(a,n,w,t,x,p,v,s,c),p.resolve(!0)):(o(null,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0&&p.resolve()));else if(a&&Zr(n,a))o(a,n,w,t,x,p,v,s,c),mo(p,n);else if(Jo(d,"onPending"),p.pendingBranch=n,n.shapeFlag&512?p.pendingId=n.component.suspenseId:p.pendingId=da++,o(null,n,p.hiddenContainer,null,x,p,v,s,c),p.deps<=0)p.resolve();else{const{timeout:f,pendingId:m}=p;f>0?setTimeout(()=>{p.pendingId===m&&p.fallback(i)},f):f===0&&p.fallback(i)}}function Sd(r,d,w,t,x,v,s,c,o,u,g=!1){const{p,m:n,um:i,n:a,o:{parentNode:h,remove:y}}=u;let l;const f=Hp(r);f&&d&&d.pendingBranch&&(l=d.pendingId,d.deps++);const m=r.props?Xc(r.props.timeout):void 0,b=v,j={vnode:r,parent:d,parentComponent:w,namespace:s,container:t,hiddenContainer:x,deps:0,pendingId:da++,timeout:typeof m=="number"?m:-1,activeBranch:null,pendingBranch:null,isInFallback:!g,isHydrating:g,isUnmounted:!1,effects:[],resolve(k=!1,E=!1){const{vnode:M,activeBranch:P,pendingBranch:L,pendingId:C,effects:I,parentComponent:A,container:N}=j;let F=!1;j.isHydrating?j.isHydrating=!1:k||(F=P&&L.transition&&L.transition.mode==="out-in",F&&(P.transition.afterLeave=()=>{C===j.pendingId&&(n(L,N,v===b?a(P):v,0),ua(I))}),P&&(h(P.el)!==j.hiddenContainer&&(v=a(P)),i(P,A,j,!0)),F||n(L,N,v,0)),mo(j,L),j.pendingBranch=null,j.isInFallback=!1;let B=j.parent,q=!1;for(;B;){if(B.pendingBranch){B.effects.push(...I),q=!0;break}B=B.parent}!q&&!F&&ua(I),j.effects=[],f&&d&&d.pendingBranch&&l===d.pendingId&&(d.deps--,d.deps===0&&!E&&d.resolve()),Jo(M,"onResolve")},fallback(k){if(!j.pendingBranch)return;const{vnode:E,activeBranch:M,parentComponent:P,container:L,namespace:C}=j;Jo(E,"onFallback");const I=a(M),A=()=>{j.isInFallback&&(p(null,k,L,I,P,null,C,c,o),mo(j,k))},N=k.transition&&k.transition.mode==="out-in";N&&(M.transition.afterLeave=A),j.isInFallback=!0,i(M,P,null,!0),N||A()},move(k,E,M){j.activeBranch&&n(j.activeBranch,k,E,M),j.container=k},next(){return j.activeBranch&&a(j.activeBranch)},registerDep(k,E,M){const P=!!j.pendingBranch;P&&j.deps++;const L=k.vnode.el;k.asyncDep.catch(C=>{So(C,k,0)}).then(C=>{if(k.isUnmounted||j.isUnmounted||j.pendingId!==k.suspenseId)return;k.asyncResolved=!0;const{vnode:I}=k;ba(k,C,!1),L&&(I.el=L);const A=!L&&k.subTree.el;E(k,I,h(L||k.subTree.el),L?null:a(k.subTree),j,s,M),A&&y(A),rl(k,I.el),P&&--j.deps===0&&j.resolve()})},unmount(k,E){j.isUnmounted=!0,j.activeBranch&&i(j.activeBranch,w,k,E),j.pendingBranch&&i(j.pendingBranch,w,k,E)}};return j}function Gp(r,d,w,t,x,v,s,c,o){const u=d.suspense=Sd(d,t,w,r.parentNode,document.createElement("div"),null,x,v,s,c,!0),g=o(r,u.pendingBranch=d.ssContent,w,u,v,s);return u.deps===0&&u.resolve(!1,!0),g}function Vp(r){const{shapeFlag:d,children:w}=r,t=d&32;r.ssContent=wu(t?w.default:w),r.ssFallback=t?wu(w.fallback):pt(ar)}function wu(r){let d;if(at(r)){const w=bo&&r._c;w&&(r._d=!1,Gr()),r=r(),w&&(r._d=!0,d=Hr,Qd())}return st(r)&&(r=Ap(r)),r=Br(r),d&&!r.dynamicChildren&&(r.dynamicChildren=d.filter(w=>w!==r)),r}function Ed(r,d){d&&d.pendingBranch?st(r)?d.effects.push(...r):d.effects.push(r):ua(r)}function mo(r,d){r.activeBranch=d;const{vnode:w,parentComponent:t}=r;let x=d.el;for(;!x&&d.component;)d=d.component.subTree,x=d.el;w.el=x,t&&t.subTree===w&&(t.vnode.el=x,rl(t,x))}function Hp(r){const d=r.props&&r.props.suspensible;return d!=null&&d!==!1}function ui(r,d,w=$t,t=!1){if(w){const x=w[r]||(w[r]=[]),v=d.__weh||(d.__weh=(...s)=>{Nn();const c=Qn(w),o=zr(d,w,r,s);return c(),Un(),o});return t?x.unshift(v):x.push(v),v}}const yn=r=>(d,w=$t)=>{(!ds||r==="sp")&&ui(r,(...t)=>d(...t),w)},zp=yn("bm"),Qr=yn("m"),Wp=yn("bu"),Td=yn("u"),ls=yn("bum"),us=yn("um"),qp=yn("sp"),Xp=yn("rtg"),Yp=yn("rtc");function kd(r,d=$t){ui("ec",r,d)}function x_(r,d){if(Kt===null)return r;const w=di(Kt),t=r.dirs||(r.dirs=[]);for(let x=0;xd(s,c,void 0,v));else{const s=Object.keys(r);x=new Array(s.length);for(let c=0,o=s.length;c!!r.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function ft(r){at(r)&&(r={loader:r});const{loader:d,loadingComponent:w,errorComponent:t,delay:x=200,timeout:v,suspensible:s=!0,onError:c}=r;let o=null,u,g=0;const p=()=>(g++,o=null,n()),n=()=>{let i;return o||(i=o=d().catch(a=>{if(a=a instanceof Error?a:new Error(String(a)),c)return new Promise((h,y)=>{c(a,()=>h(p()),()=>y(a),g+1)});throw a}).then(a=>i!==o&&o?o:(a&&(a.__esModule||a[Symbol.toStringTag]==="Module")&&(a=a.default),u=a,a)))};return pr({name:"AsyncComponentWrapper",__asyncLoader:n,get __asyncResolved(){return u},setup(){const i=$t;if(u)return()=>Li(u,i);const a=f=>{o=null,So(f,i,13,!t)};if(s&&i.suspense||ds)return n().then(f=>()=>Li(f,i)).catch(f=>(a(f),()=>t?pt(t,{error:f}):null));const h=mt(!1),y=mt(),l=mt(!!x);return x&&setTimeout(()=>{l.value=!1},x),v!=null&&setTimeout(()=>{if(!h.value&&!y.value){const f=new Error(`Async component timed out after ${v}ms.`);a(f),y.value=f}},v),n().then(()=>{h.value=!0,i.parent&&cs(i.parent.vnode)&&(i.parent.effect.dirty=!0,ai(i.parent.update))}).catch(f=>{a(f),y.value=f}),()=>{if(h.value&&u)return Li(u,i);if(y.value&&t)return pt(t,{error:y.value});if(w&&!l.value)return pt(w)}}})}function Li(r,d){const{ref:w,props:t,children:x,ce:v}=d.vnode,s=pt(r,t,x);return s.ref=w,s.ce=v,delete d.vnode.ce,s}function S_(r,d,w={},t,x){if(Kt.isCE||Kt.parent&&Zn(Kt.parent)&&Kt.parent.isCE)return pt("slot",w,t);let v=r[d];v&&v._c&&(v._d=!1),Gr();const s=v&&Md(v(w)),c=Xn(gr,{key:w.key||s&&s.key||`_${d}`},s||[],s&&r._===1?64:-2);return c.scopeId&&(c.slotScopeIds=[c.scopeId+"-s"]),v&&v._c&&(v._d=!0),c}function Md(r){return r.some(d=>_o(d)?!(d.type===ar||d.type===gr&&!Md(d.children)):!0)?r:null}const fa=r=>r?rf(r)?di(r):fa(r.parent):null,Vo=Xt(Object.create(null),{$:r=>r,$el:r=>r.vnode.el,$data:r=>r.data,$props:r=>r.props,$attrs:r=>r.attrs,$slots:r=>r.slots,$refs:r=>r.refs,$parent:r=>fa(r.parent),$root:r=>fa(r.root),$emit:r=>r.emit,$options:r=>ol(r),$forceUpdate:r=>r.f||(r.f=()=>{r.effect.dirty=!0,ai(r.update)}),$nextTick:r=>r.n||(r.n=Fr.bind(r.proxy)),$watch:r=>gm.bind(r)}),Ii=(r,d)=>r!==Rt&&!r.__isScriptSetup&&vt(r,d),$p={get({_:r},d){if(d==="__v_skip")return!0;const{ctx:w,setupState:t,data:x,props:v,accessCache:s,type:c,appContext:o}=r;let u;if(d[0]!=="$"){const i=s[d];if(i!==void 0)switch(i){case 1:return t[d];case 2:return x[d];case 4:return w[d];case 3:return v[d]}else{if(Ii(t,d))return s[d]=1,t[d];if(x!==Rt&&vt(x,d))return s[d]=2,x[d];if((u=r.propsOptions[0])&&vt(u,d))return s[d]=3,v[d];if(w!==Rt&&vt(w,d))return s[d]=4,w[d];ha&&(s[d]=0)}}const g=Vo[d];let p,n;if(g)return d==="$attrs"&&br(r.attrs,"get",""),g(r);if((p=c.__cssModules)&&(p=p[d]))return p;if(w!==Rt&&vt(w,d))return s[d]=4,w[d];if(n=o.config.globalProperties,vt(n,d))return n[d]},set({_:r},d,w){const{data:t,setupState:x,ctx:v}=r;return Ii(x,d)?(x[d]=w,!0):t!==Rt&&vt(t,d)?(t[d]=w,!0):vt(r.props,d)||d[0]==="$"&&d.slice(1)in r?!1:(v[d]=w,!0)},has({_:{data:r,setupState:d,accessCache:w,ctx:t,appContext:x,propsOptions:v}},s){let c;return!!w[s]||r!==Rt&&vt(r,s)||Ii(d,s)||(c=v[0])&&vt(c,s)||vt(t,s)||vt(Vo,s)||vt(x.config.globalProperties,s)},defineProperty(r,d,w){return w.get!=null?r._.accessCache[d]=0:vt(w,"value")&&this.set(r,d,w.value,null),Reflect.defineProperty(r,d,w)}};function E_(){return Kp().slots}function Kp(){const r=Eo();return r.setupContext||(r.setupContext=of(r))}function xu(r){return st(r)?r.reduce((d,w)=>(d[w]=null,d),{}):r}function T_(r){const d=Eo();let w=r();return va(),za(w)&&(w=w.catch(t=>{throw Qn(d),t})),[w,()=>Qn(d)]}let ha=!0;function Zp(r){const d=ol(r),w=r.proxy,t=r.ctx;ha=!1,d.beforeCreate&&ju(d.beforeCreate,r,"bc");const{data:x,computed:v,methods:s,watch:c,provide:o,inject:u,created:g,beforeMount:p,mounted:n,beforeUpdate:i,updated:a,activated:h,deactivated:y,beforeDestroy:l,beforeUnmount:f,destroyed:m,unmounted:b,render:j,renderTracked:k,renderTriggered:E,errorCaptured:M,serverPrefetch:P,expose:L,inheritAttrs:C,components:I,directives:A,filters:N}=d;if(u&&Qp(u,t,null),s)for(const q in s){const V=s[q];at(V)&&(t[q]=V.bind(w))}if(x){const q=x.call(w,w);Ct(q)&&(r.data=Bn(q))}if(ha=!0,v)for(const q in v){const V=v[q],H=at(V)?V.bind(w,w):at(V.get)?V.get.bind(w,w):Vr,Z=!at(V)&&at(V.set)?V.set.bind(w):Vr,ee=jt({get:H,set:Z});Object.defineProperty(t,q,{enumerable:!0,configurable:!0,get:()=>ee.value,set:ue=>ee.value=ue})}if(c)for(const q in c)Cd(c[q],t,w,q);if(o){const q=at(o)?o.call(w):o;Reflect.ownKeys(q).forEach(V=>{Wr(V,q[V])})}g&&ju(g,r,"c");function B(q,V){st(V)?V.forEach(H=>q(H.bind(w))):V&&q(V.bind(w))}if(B(zp,p),B(Qr,n),B(Wp,i),B(Td,a),B(Wd,h),B(qd,y),B(kd,M),B(Yp,k),B(Xp,E),B(ls,f),B(us,b),B(qp,P),st(L))if(L.length){const q=r.exposed||(r.exposed={});L.forEach(V=>{Object.defineProperty(q,V,{get:()=>w[V],set:H=>w[V]=H})})}else r.exposed||(r.exposed={});j&&r.render===Vr&&(r.render=j),C!=null&&(r.inheritAttrs=C),I&&(r.components=I),A&&(r.directives=A)}function Qp(r,d,w=Vr){st(r)&&(r=pa(r));for(const t in r){const x=r[t];let v;Ct(x)?"default"in x?v=Ht(x.from||t,x.default,!0):v=Ht(x.from||t):v=Ht(x),hr(v)?Object.defineProperty(d,t,{enumerable:!0,configurable:!0,get:()=>v.value,set:s=>v.value=s}):d[t]=v}}function ju(r,d,w){zr(st(r)?r.map(t=>t.bind(d.proxy)):r.bind(d.proxy),d,w)}function Cd(r,d,w,t){const x=t.includes(".")?zd(w,t):()=>w[t];if(Gt(r)){const v=d[r];at(v)&&In(x,v)}else if(at(r))In(x,r.bind(w));else if(Ct(r))if(st(r))r.forEach(v=>Cd(v,d,w,t));else{const v=at(r.handler)?r.handler.bind(w):d[r.handler];at(v)&&In(x,v,r)}}function ol(r){const d=r.type,{mixins:w,extends:t}=d,{mixins:x,optionsCache:v,config:{optionMergeStrategies:s}}=r.appContext,c=v.get(d);let o;return c?o=c:!x.length&&!w&&!t?o=d:(o={},x.length&&x.forEach(u=>qs(o,u,s,!0)),qs(o,d,s)),Ct(d)&&v.set(d,o),o}function qs(r,d,w,t=!1){const{mixins:x,extends:v}=d;v&&qs(r,v,w,!0),x&&x.forEach(s=>qs(r,s,w,!0));for(const s in d)if(!(t&&s==="expose")){const c=Jp[s]||w&&w[s];r[s]=c?c(r[s],d[s]):d[s]}return r}const Jp={data:Su,props:Eu,emits:Eu,methods:No,computed:No,beforeCreate:yr,created:yr,beforeMount:yr,mounted:yr,beforeUpdate:yr,updated:yr,beforeDestroy:yr,beforeUnmount:yr,destroyed:yr,unmounted:yr,activated:yr,deactivated:yr,errorCaptured:yr,serverPrefetch:yr,components:No,directives:No,watch:tm,provide:Su,inject:em};function Su(r,d){return d?r?function(){return Xt(at(r)?r.call(this,this):r,at(d)?d.call(this,this):d)}:d:r}function em(r,d){return No(pa(r),pa(d))}function pa(r){if(st(r)){const d={};for(let w=0;w1)return w&&at(d)?d.call(t&&t.proxy):d}}function Pd(){return!!($t||Kt||yo)}const Ad={},Rd=()=>Object.create(Ad),Ld=r=>Object.getPrototypeOf(r)===Ad;function om(r,d,w,t=!1){const x={},v=Rd();r.propsDefaults=Object.create(null),Id(r,d,x,v);for(const s in r.propsOptions[0])s in x||(x[s]=void 0);w?r.props=t?x:as(x):r.type.props?r.props=x:r.props=v,r.attrs=v}function sm(r,d,w,t){const{props:x,attrs:v,vnode:{patchFlag:s}}=r,c=bt(x),[o]=r.propsOptions;let u=!1;if((t||s>0)&&!(s&16)){if(s&8){const g=r.vnode.dynamicProps;for(let p=0;p{o=!0;const[n,i]=Dd(p,d,!0);Xt(s,n),i&&c.push(...i)};!w&&d.mixins.length&&d.mixins.forEach(g),r.extends&&g(r.extends),r.mixins&&r.mixins.forEach(g)}if(!v&&!o)return Ct(r)&&t.set(r,uo),uo;if(st(v))for(let g=0;g-1,i[1]=h<0||a-1||vt(i,"default"))&&c.push(p)}}}const u=[s,c];return Ct(r)&&t.set(r,u),u}function Tu(r){return r[0]!=="$"&&!fo(r)}function ku(r){return r===null?"null":typeof r=="function"?r.name||"":typeof r=="object"&&r.constructor&&r.constructor.name||""}function Mu(r,d){return ku(r)===ku(d)}function Cu(r,d){return st(d)?d.findIndex(w=>Mu(w,r)):at(d)&&Mu(d,r)?0:-1}const Fd=r=>r[0]==="_"||r==="$stable",sl=r=>st(r)?r.map(Br):[Br(r)],im=(r,d,w)=>{if(d._n)return d;const t=Ur((...x)=>sl(d(...x)),w);return t._c=!1,t},Nd=(r,d,w)=>{const t=r._ctx;for(const x in r){if(Fd(x))continue;const v=r[x];if(at(v))d[x]=im(x,v,t);else if(v!=null){const s=sl(v);d[x]=()=>s}}},Ud=(r,d)=>{const w=sl(d);r.slots.default=()=>w},am=(r,d)=>{const w=r.slots=Rd();if(r.vnode.shapeFlag&32){const t=d._;t?(Xt(w,d),qc(w,"_",t,!0)):Nd(d,w)}else d&&Ud(r,d)},lm=(r,d,w)=>{const{vnode:t,slots:x}=r;let v=!0,s=Rt;if(t.shapeFlag&32){const c=d._;c?w&&c===1?v=!1:(Xt(x,d),!w&&c===1&&delete x._):(v=!d.$stable,Nd(d,x)),s=d}else d&&(Ud(r,d),s={default:1});if(v)for(const c in x)!Fd(c)&&s[c]==null&&delete x[c]};function Xs(r,d,w,t,x=!1){if(st(r)){r.forEach((n,i)=>Xs(n,d&&(st(d)?d[i]:d),w,t,x));return}if(Zn(t)&&!x)return;const v=t.shapeFlag&4?di(t.component):t.el,s=x?null:v,{i:c,r:o}=r,u=d&&d.r,g=c.refs===Rt?c.refs={}:c.refs,p=c.setupState;if(u!=null&&u!==o&&(Gt(u)?(g[u]=null,vt(p,u)&&(p[u]=null)):hr(u)&&(u.value=null)),at(o))Ln(o,c,12,[s,g]);else{const n=Gt(o),i=hr(o);if(n||i){const a=()=>{if(r.f){const h=n?vt(p,o)?p[o]:g[o]:o.value;x?st(h)&&Ha(h,v):st(h)?h.includes(v)||h.push(v):n?(g[o]=[v],vt(p,o)&&(p[o]=g[o])):(o.value=[v],r.k&&(g[r.k]=o.value))}else n?(g[o]=s,vt(p,o)&&(p[o]=s)):i&&(o.value=s,r.k&&(g[r.k]=s))};s?(a.id=-1,tr(a,w)):a()}}}let Ou=!1;const oo=()=>{Ou||(console.error("Hydration completed but contains mismatches."),Ou=!0)},um=r=>r.namespaceURI.includes("svg")&&r.tagName!=="foreignObject",cm=r=>r.namespaceURI.includes("MathML"),Ts=r=>{if(um(r))return"svg";if(cm(r))return"mathml"},ks=r=>r.nodeType===8;function dm(r){const{mt:d,p:w,o:{patchProp:t,createText:x,nextSibling:v,parentNode:s,remove:c,insert:o,createComment:u}}=r,g=(m,b)=>{if(!b.hasChildNodes()){w(null,m,b),zs(),b._vnode=m;return}p(b.firstChild,m,null,null,null),zs(),b._vnode=m},p=(m,b,j,k,E,M=!1)=>{M=M||!!b.dynamicChildren;const P=ks(m)&&m.data==="[",L=()=>h(m,b,j,k,E,P),{type:C,ref:I,shapeFlag:A,patchFlag:N}=b;let F=m.nodeType;b.el=m,N===-2&&(M=!1,b.dynamicChildren=null);let B=null;switch(C){case vo:F!==3?b.children===""?(o(b.el=x(""),s(m),m),B=m):B=L():(m.data!==b.children&&(oo(),m.data=b.children),B=v(m));break;case ar:f(m)?(B=v(m),l(b.el=m.content.firstChild,m,j)):F!==8||P?B=L():B=v(m);break;case Ho:if(P&&(m=v(m),F=m.nodeType),F===1||F===3){B=m;const q=!b.children.length;for(let V=0;V{M=M||!!b.dynamicChildren;const{type:P,props:L,patchFlag:C,shapeFlag:I,dirs:A,transition:N}=b,F=P==="input"||P==="option";if(F||C!==-1){A&&on(b,null,j,"created");let B=!1;if(f(m)){B=Gd(k,N)&&j&&j.vnode.props&&j.vnode.props.appear;const V=m.content.firstChild;B&&N.beforeEnter(V),l(V,m,j),b.el=m=V}if(I&16&&!(L&&(L.innerHTML||L.textContent))){let V=i(m.firstChild,b,m,j,k,E,M);for(;V;){oo();const H=V;V=V.nextSibling,c(H)}}else I&8&&m.textContent!==b.children&&(oo(),m.textContent=b.children);if(L)if(F||!M||C&48)for(const V in L)(F&&(V.endsWith("value")||V==="indeterminate")||ss(V)&&!fo(V)||V[0]===".")&&t(m,V,null,L[V],void 0,void 0,j);else L.onClick&&t(m,"onClick",null,L.onClick,void 0,void 0,j);let q;(q=L&&L.onVnodeBeforeMount)&&vr(q,j,b),A&&on(b,null,j,"beforeMount"),((q=L&&L.onVnodeMounted)||A||B)&&Ed(()=>{q&&vr(q,j,b),B&&N.enter(m),A&&on(b,null,j,"mounted")},k)}return m.nextSibling},i=(m,b,j,k,E,M,P)=>{P=P||!!b.dynamicChildren;const L=b.children,C=L.length;for(let I=0;I{const{slotScopeIds:P}=b;P&&(E=E?E.concat(P):P);const L=s(m),C=i(v(m),b,L,j,k,E,M);return C&&ks(C)&&C.data==="]"?v(b.anchor=C):(oo(),o(b.anchor=u("]"),L,C),C)},h=(m,b,j,k,E,M)=>{if(oo(),b.el=null,M){const C=y(m);for(;;){const I=v(m);if(I&&I!==C)c(I);else break}}const P=v(m),L=s(m);return c(m),w(null,b,L,P,j,k,Ts(L),E),P},y=(m,b="[",j="]")=>{let k=0;for(;m;)if(m=v(m),m&&ks(m)&&(m.data===b&&k++,m.data===j)){if(k===0)return v(m);k--}return m},l=(m,b,j)=>{const k=b.parentNode;k&&k.replaceChild(m,b);let E=j;for(;E;)E.vnode.el===b&&(E.vnode.el=E.subTree.el=m),E=E.parent},f=m=>m.nodeType===1&&m.tagName.toLowerCase()==="template";return[g,p]}const tr=Ed;function fm(r){return Bd(r)}function hm(r){return Bd(r,dm)}function Bd(r,d){const w=Yc();w.__VUE__=!0;const{insert:t,remove:x,patchProp:v,createElement:s,createText:c,createComment:o,setText:u,setElementText:g,parentNode:p,nextSibling:n,setScopeId:i=Vr,insertStaticContent:a}=r,h=(K,z,te,le=null,me=null,de=null,ye=void 0,ge=null,ke=!!z.dynamicChildren)=>{if(K===z)return;K&&!Zr(K,z)&&(le=$(K),ue(K,me,de,!0),K=null),z.patchFlag===-2&&(ke=!1,z.dynamicChildren=null);const{type:ve,ref:Ie,shapeFlag:De}=z;switch(ve){case vo:y(K,z,te,le);break;case ar:l(K,z,te,le);break;case Ho:K==null&&f(z,te,le,ye);break;case gr:I(K,z,te,le,me,de,ye,ge,ke);break;default:De&1?j(K,z,te,le,me,de,ye,ge,ke):De&6?A(K,z,te,le,me,de,ye,ge,ke):(De&64||De&128)&&ve.process(K,z,te,le,me,de,ye,ge,ke,ce)}Ie!=null&&me&&Xs(Ie,K&&K.ref,de,z||K,!z)},y=(K,z,te,le)=>{if(K==null)t(z.el=c(z.children),te,le);else{const me=z.el=K.el;z.children!==K.children&&u(me,z.children)}},l=(K,z,te,le)=>{K==null?t(z.el=o(z.children||""),te,le):z.el=K.el},f=(K,z,te,le)=>{[K.el,K.anchor]=a(K.children,z,te,le,K.el,K.anchor)},m=({el:K,anchor:z},te,le)=>{let me;for(;K&&K!==z;)me=n(K),t(K,te,le),K=me;t(z,te,le)},b=({el:K,anchor:z})=>{let te;for(;K&&K!==z;)te=n(K),x(K),K=te;x(z)},j=(K,z,te,le,me,de,ye,ge,ke)=>{z.type==="svg"?ye="svg":z.type==="math"&&(ye="mathml"),K==null?k(z,te,le,me,de,ye,ge,ke):P(K,z,me,de,ye,ge,ke)},k=(K,z,te,le,me,de,ye,ge)=>{let ke,ve;const{props:Ie,shapeFlag:De,transition:Le,dirs:Ne}=K;if(ke=K.el=s(K.type,de,Ie&&Ie.is,Ie),De&8?g(ke,K.children):De&16&&M(K.children,ke,null,le,me,Di(K,de),ye,ge),Ne&&on(K,null,le,"created"),E(ke,K,K.scopeId,ye,le),Ie){for(const xe in Ie)xe!=="value"&&!fo(xe)&&v(ke,xe,null,Ie[xe],de,K.children,le,me,W);"value"in Ie&&v(ke,"value",null,Ie.value,de),(ve=Ie.onVnodeBeforeMount)&&vr(ve,le,K)}Ne&&on(K,null,le,"beforeMount");const Be=Gd(me,Le);Be&&Le.beforeEnter(ke),t(ke,z,te),((ve=Ie&&Ie.onVnodeMounted)||Be||Ne)&&tr(()=>{ve&&vr(ve,le,K),Be&&Le.enter(ke),Ne&&on(K,null,le,"mounted")},me)},E=(K,z,te,le,me)=>{if(te&&i(K,te),le)for(let de=0;de{for(let ve=ke;ve{const ge=z.el=K.el;let{patchFlag:ke,dynamicChildren:ve,dirs:Ie}=z;ke|=K.patchFlag&16;const De=K.props||Rt,Le=z.props||Rt;let Ne;if(te&&Gn(te,!1),(Ne=Le.onVnodeBeforeUpdate)&&vr(Ne,te,z,K),Ie&&on(z,K,te,"beforeUpdate"),te&&Gn(te,!0),ve?L(K.dynamicChildren,ve,ge,te,le,Di(z,me),de):ye||V(K,z,ge,null,te,le,Di(z,me),de,!1),ke>0){if(ke&16)C(ge,z,De,Le,te,le,me);else if(ke&2&&De.class!==Le.class&&v(ge,"class",null,Le.class,me),ke&4&&v(ge,"style",De.style,Le.style,me),ke&8){const Be=z.dynamicProps;for(let xe=0;xe{Ne&&vr(Ne,te,z,K),Ie&&on(z,K,te,"updated")},le)},L=(K,z,te,le,me,de,ye)=>{for(let ge=0;ge{if(te!==le){if(te!==Rt)for(const ge in te)!fo(ge)&&!(ge in le)&&v(K,ge,te[ge],null,ye,z.children,me,de,W);for(const ge in le){if(fo(ge))continue;const ke=le[ge],ve=te[ge];ke!==ve&&ge!=="value"&&v(K,ge,ve,ke,ye,z.children,me,de,W)}"value"in le&&v(K,"value",te.value,le.value,ye)}},I=(K,z,te,le,me,de,ye,ge,ke)=>{const ve=z.el=K?K.el:c(""),Ie=z.anchor=K?K.anchor:c("");let{patchFlag:De,dynamicChildren:Le,slotScopeIds:Ne}=z;Ne&&(ge=ge?ge.concat(Ne):Ne),K==null?(t(ve,te,le),t(Ie,te,le),M(z.children||[],te,Ie,me,de,ye,ge,ke)):De>0&&De&64&&Le&&K.dynamicChildren?(L(K.dynamicChildren,Le,te,me,de,ye,ge),(z.key!=null||me&&z===me.subTree)&&Vd(K,z,!0)):V(K,z,te,Ie,me,de,ye,ge,ke)},A=(K,z,te,le,me,de,ye,ge,ke)=>{z.slotScopeIds=ge,K==null?z.shapeFlag&512?me.ctx.activate(z,te,le,ye,ke):N(z,te,le,me,de,ye,ke):F(K,z,ke)},N=(K,z,te,le,me,de,ye)=>{const ge=K.component=Cm(K,le,me);if(cs(K)&&(ge.ctx.renderer=ce),Om(ge),ge.asyncDep){if(me&&me.registerDep(ge,B,ye),!K.el){const ke=ge.subTree=pt(ar);l(null,ke,z,te)}}else B(ge,K,z,te,me,de,ye)},F=(K,z,te)=>{const le=z.component=K.component;if(Ip(K,z,te))if(le.asyncDep&&!le.asyncResolved){q(le,z,te);return}else le.next=z,Cp(le.update),le.effect.dirty=!0,le.update();else z.el=K.el,le.vnode=z},B=(K,z,te,le,me,de,ye)=>{const ge=()=>{if(K.isMounted){let{next:Ie,bu:De,u:Le,parent:Ne,vnode:Be}=K;{const se=Hd(K);if(se){Ie&&(Ie.el=Be.el,q(K,Ie,ye)),se.asyncDep.then(()=>{K.isUnmounted||ge()});return}}let xe=Ie,Re;Gn(K,!1),Ie?(Ie.el=Be.el,q(K,Ie,ye)):Ie=Be,De&&ho(De),(Re=Ie.props&&Ie.props.onVnodeBeforeUpdate)&&vr(Re,Ne,Ie,Be),Gn(K,!0);const Ee=Ri(K),re=K.subTree;K.subTree=Ee,h(re,Ee,p(re.el),$(re),K,me,de),Ie.el=Ee.el,xe===null&&rl(K,Ee.el),Le&&tr(Le,me),(Re=Ie.props&&Ie.props.onVnodeUpdated)&&tr(()=>vr(Re,Ne,Ie,Be),me)}else{let Ie;const{el:De,props:Le}=z,{bm:Ne,m:Be,parent:xe}=K,Re=Zn(z);if(Gn(K,!1),Ne&&ho(Ne),!Re&&(Ie=Le&&Le.onVnodeBeforeMount)&&vr(Ie,xe,z),Gn(K,!0),De&&pe){const Ee=()=>{K.subTree=Ri(K),pe(De,K.subTree,K,me,null)};Re?z.type.__asyncLoader().then(()=>!K.isUnmounted&&Ee()):Ee()}else{const Ee=K.subTree=Ri(K);h(null,Ee,te,le,K,me,de),z.el=Ee.el}if(Be&&tr(Be,me),!Re&&(Ie=Le&&Le.onVnodeMounted)){const Ee=z;tr(()=>vr(Ie,xe,Ee),me)}(z.shapeFlag&256||xe&&Zn(xe.vnode)&&xe.vnode.shapeFlag&256)&&K.a&&tr(K.a,me),K.isMounted=!0,z=te=le=null}},ke=K.effect=new Xa(ge,Vr,()=>ai(ve),K.scope),ve=K.update=()=>{ke.dirty&&ke.run()};ve.id=K.uid,Gn(K,!0),ve()},q=(K,z,te)=>{z.component=K;const le=K.vnode.props;K.vnode=z,K.next=null,sm(K,z.props,le,te),lm(K,z.children,te),Nn(),vu(K),Un()},V=(K,z,te,le,me,de,ye,ge,ke=!1)=>{const ve=K&&K.children,Ie=K?K.shapeFlag:0,De=z.children,{patchFlag:Le,shapeFlag:Ne}=z;if(Le>0){if(Le&128){Z(ve,De,te,le,me,de,ye,ge,ke);return}else if(Le&256){H(ve,De,te,le,me,de,ye,ge,ke);return}}Ne&8?(Ie&16&&W(ve,me,de),De!==ve&&g(te,De)):Ie&16?Ne&16?Z(ve,De,te,le,me,de,ye,ge,ke):W(ve,me,de,!0):(Ie&8&&g(te,""),Ne&16&&M(De,te,le,me,de,ye,ge,ke))},H=(K,z,te,le,me,de,ye,ge,ke)=>{K=K||uo,z=z||uo;const ve=K.length,Ie=z.length,De=Math.min(ve,Ie);let Le;for(Le=0;LeIe?W(K,me,de,!0,!1,De):M(z,te,le,me,de,ye,ge,ke,De)},Z=(K,z,te,le,me,de,ye,ge,ke)=>{let ve=0;const Ie=z.length;let De=K.length-1,Le=Ie-1;for(;ve<=De&&ve<=Le;){const Ne=K[ve],Be=z[ve]=ke?Mn(z[ve]):Br(z[ve]);if(Zr(Ne,Be))h(Ne,Be,te,null,me,de,ye,ge,ke);else break;ve++}for(;ve<=De&&ve<=Le;){const Ne=K[De],Be=z[Le]=ke?Mn(z[Le]):Br(z[Le]);if(Zr(Ne,Be))h(Ne,Be,te,null,me,de,ye,ge,ke);else break;De--,Le--}if(ve>De){if(ve<=Le){const Ne=Le+1,Be=NeLe)for(;ve<=De;)ue(K[ve],me,de,!0),ve++;else{const Ne=ve,Be=ve,xe=new Map;for(ve=Be;ve<=Le;ve++){const Se=z[ve]=ke?Mn(z[ve]):Br(z[ve]);Se.key!=null&&xe.set(Se.key,ve)}let Re,Ee=0;const re=Le-Be+1;let se=!1,Q=0;const ae=new Array(re);for(ve=0;ve=re){ue(Se,me,de,!0);continue}let Pe;if(Se.key!=null)Pe=xe.get(Se.key);else for(Re=Be;Re<=Le;Re++)if(ae[Re-Be]===0&&Zr(Se,z[Re])){Pe=Re;break}Pe===void 0?ue(Se,me,de,!0):(ae[Pe-Be]=ve+1,Pe>=Q?Q=Pe:se=!0,h(Se,z[Pe],te,null,me,de,ye,ge,ke),Ee++)}const we=se?pm(ae):uo;for(Re=we.length-1,ve=re-1;ve>=0;ve--){const Se=Be+ve,Pe=z[Se],He=Se+1{const{el:de,type:ye,transition:ge,children:ke,shapeFlag:ve}=K;if(ve&6){ee(K.component.subTree,z,te,le);return}if(ve&128){K.suspense.move(z,te,le);return}if(ve&64){ye.move(K,z,te,ce);return}if(ye===gr){t(de,z,te);for(let De=0;Dege.enter(de),me);else{const{leave:De,delayLeave:Le,afterLeave:Ne}=ge,Be=()=>t(de,z,te),xe=()=>{De(de,()=>{Be(),Ne&&Ne()})};Le?Le(de,Be,xe):xe()}else t(de,z,te)},ue=(K,z,te,le=!1,me=!1)=>{const{type:de,props:ye,ref:ge,children:ke,dynamicChildren:ve,shapeFlag:Ie,patchFlag:De,dirs:Le,memoIndex:Ne}=K;if(De===-2&&(me=!1),ge!=null&&Xs(ge,null,te,K,!0),Ne!=null&&(z.renderCache[Ne]=void 0),Ie&256){z.ctx.deactivate(K);return}const Be=Ie&1&&Le,xe=!Zn(K);let Re;if(xe&&(Re=ye&&ye.onVnodeBeforeUnmount)&&vr(Re,z,K),Ie&6)G(K.component,te,le);else{if(Ie&128){K.suspense.unmount(te,le);return}Be&&on(K,null,z,"beforeUnmount"),Ie&64?K.type.remove(K,z,te,ce,le):ve&&(de!==gr||De>0&&De&64)?W(ve,z,te,!1,!0):(de===gr&&De&384||!me&&Ie&16)&&W(ke,z,te),le&&T(K)}(xe&&(Re=ye&&ye.onVnodeUnmounted)||Be)&&tr(()=>{Re&&vr(Re,z,K),Be&&on(K,null,z,"unmounted")},te)},T=K=>{const{type:z,el:te,anchor:le,transition:me}=K;if(z===gr){D(te,le);return}if(z===Ho){b(K);return}const de=()=>{x(te),me&&!me.persisted&&me.afterLeave&&me.afterLeave()};if(K.shapeFlag&1&&me&&!me.persisted){const{leave:ye,delayLeave:ge}=me,ke=()=>ye(te,de);ge?ge(K.el,de,ke):ke()}else de()},D=(K,z)=>{let te;for(;K!==z;)te=n(K),x(K),K=te;x(z)},G=(K,z,te)=>{const{bum:le,scope:me,update:de,subTree:ye,um:ge,m:ke,a:ve}=K;Ys(ke),Ys(ve),le&&ho(le),me.stop(),de&&(de.active=!1,ue(ye,K,z,te)),ge&&tr(ge,z),tr(()=>{K.isUnmounted=!0},z),z&&z.pendingBranch&&!z.isUnmounted&&K.asyncDep&&!K.asyncResolved&&K.suspenseId===z.pendingId&&(z.deps--,z.deps===0&&z.resolve())},W=(K,z,te,le=!1,me=!1,de=0)=>{for(let ye=de;yeK.shapeFlag&6?$(K.component.subTree):K.shapeFlag&128?K.suspense.next():n(K.anchor||K.el);let J=!1;const ne=(K,z,te)=>{K==null?z._vnode&&ue(z._vnode,null,null,!0):h(z._vnode||null,K,z,null,null,null,te),J||(J=!0,vu(),zs(),J=!1),z._vnode=K},ce={p:h,um:ue,m:ee,r:T,mt:N,mc:M,pc:V,pbc:L,n:$,o:r};let ie,pe;return d&&([ie,pe]=d(ce)),{render:ne,hydrate:ie,createApp:nm(ne,ie)}}function Di({type:r,props:d},w){return w==="svg"&&r==="foreignObject"||w==="mathml"&&r==="annotation-xml"&&d&&d.encoding&&d.encoding.includes("html")?void 0:w}function Gn({effect:r,update:d},w){r.allowRecurse=d.allowRecurse=w}function Gd(r,d){return(!r||r&&!r.pendingBranch)&&d&&!d.persisted}function Vd(r,d,w=!1){const t=r.children,x=d.children;if(st(t)&&st(x))for(let v=0;v>1,r[w[c]]0&&(d[t]=w[v-1]),w[v]=t)}}for(v=w.length,s=w[v-1];v-- >0;)w[v]=s,s=d[s];return w}function Hd(r){const d=r.subTree.component;if(d)return d.asyncDep&&!d.asyncResolved?d:Hd(d)}function Ys(r){if(r)for(let d=0;dHt(mm);function ln(r,d){return il(r,null,d)}const Ms={};function In(r,d,w){return il(r,d,w)}function il(r,d,{immediate:w,deep:t,flush:x,once:v,onTrack:s,onTrigger:c}=Rt){if(d&&v){const k=d;d=(...E)=>{k(...E),j()}}const o=$t,u=k=>t===!0?k:On(k,t===!1?1:void 0);let g,p=!1,n=!1;if(hr(r)?(g=()=>r.value,p=Hs(r)):Bo(r)?(g=()=>u(r),p=!0):st(r)?(n=!0,p=r.some(k=>Bo(k)||Hs(k)),g=()=>r.map(k=>{if(hr(k))return k.value;if(Bo(k))return u(k);if(at(k))return Ln(k,o,2)})):at(r)?d?g=()=>Ln(r,o,2):g=()=>(i&&i(),zr(r,o,3,[a])):g=Vr,d&&t){const k=g;g=()=>On(k())}let i,a=k=>{i=m.onStop=()=>{Ln(k,o,4),i=m.onStop=void 0}},h;if(ds)if(a=Vr,d?w&&zr(d,o,3,[g(),n?[]:void 0,a]):g(),x==="sync"){const k=ym();h=k.__watcherHandles||(k.__watcherHandles=[])}else return Vr;let y=n?new Array(r.length).fill(Ms):Ms;const l=()=>{if(!(!m.active||!m.dirty))if(d){const k=m.run();(t||p||(n?k.some((E,M)=>Dn(E,y[M])):Dn(k,y)))&&(i&&i(),zr(d,o,3,[k,y===Ms?void 0:n&&y[0]===Ms?[]:y,a]),y=k)}else m.run()};l.allowRecurse=!!d;let f;x==="sync"?f=l:x==="post"?f=()=>tr(l,o&&o.suspense):(l.pre=!0,o&&(l.id=o.uid),f=()=>ai(l));const m=new Xa(g,Vr,f),b=Qh(),j=()=>{m.stop(),b&&Ha(b.effects,m)};return d?w?l():y=m.run():x==="post"?tr(m.run.bind(m),o&&o.suspense):m.run(),h&&h.push(j),j}function gm(r,d,w){const t=this.proxy,x=Gt(r)?r.includes(".")?zd(t,r):()=>t[r]:r.bind(t,t);let v;at(d)?v=d:(v=d.handler,w=d);const s=Qn(this),c=il(x,v.bind(t),w);return s(),c}function zd(r,d){const w=d.split(".");return()=>{let t=r;for(let x=0;x{On(t,d,w)});else if(Wc(r)){for(const t in r)On(r[t],d,w);for(const t of Object.getOwnPropertySymbols(r))Object.prototype.propertyIsEnumerable.call(r,t)&&On(r[t],d,w)}return r}const cs=r=>r.type.__isKeepAlive,vm={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(r,{slots:d}){const w=Eo(),t=w.ctx;if(!t.renderer)return()=>{const f=d.default&&d.default();return f&&f.length===1?f[0]:f};const x=new Map,v=new Set;let s=null;const c=w.suspense,{renderer:{p:o,m:u,um:g,o:{createElement:p}}}=t,n=p("div");t.activate=(f,m,b,j,k)=>{const E=f.component;u(f,m,b,0,c),o(E.vnode,f,m,b,E,c,j,f.slotScopeIds,k),tr(()=>{E.isDeactivated=!1,E.a&&ho(E.a);const M=f.props&&f.props.onVnodeMounted;M&&vr(M,E.parent,f)},c)},t.deactivate=f=>{const m=f.component;Ys(m.m),Ys(m.a),u(f,n,null,1,c),tr(()=>{m.da&&ho(m.da);const b=f.props&&f.props.onVnodeUnmounted;b&&vr(b,m.parent,f),m.isDeactivated=!0},c)};function i(f){Fi(f),g(f,w,c,!0)}function a(f){x.forEach((m,b)=>{const j=_a(m.type);j&&(!f||!f(j))&&h(b)})}function h(f){const m=x.get(f);!s||!Zr(m,s)?i(m):s&&Fi(s),x.delete(f),v.delete(f)}In(()=>[r.include,r.exclude],([f,m])=>{f&&a(b=>Uo(f,b)),m&&a(b=>!Uo(m,b))},{flush:"post",deep:!0});let y=null;const l=()=>{y!=null&&(ca(w.subTree.type)?tr(()=>{x.set(y,Cs(w.subTree))},w.subTree.suspense):x.set(y,Cs(w.subTree)))};return Qr(l),Td(l),ls(()=>{x.forEach(f=>{const{subTree:m,suspense:b}=w,j=Cs(m);if(f.type===j.type&&f.key===j.key){Fi(j);const k=j.component.da;k&&tr(k,b);return}i(f)})}),()=>{if(y=null,!d.default)return null;const f=d.default(),m=f[0];if(f.length>1)return s=null,f;if(!_o(m)||!(m.shapeFlag&4)&&!(m.shapeFlag&128))return s=null,m;let b=Cs(m);const j=b.type,k=_a(Zn(b)?b.type.__asyncResolved||{}:j),{include:E,exclude:M,max:P}=r;if(E&&(!k||!Uo(E,k))||M&&k&&Uo(M,k))return s=b,m;const L=b.key==null?j:b.key,C=x.get(L);return b.el&&(b=un(b),m.shapeFlag&128&&(m.ssContent=b)),y=L,C?(b.el=C.el,b.component=C.component,b.transition&&es(b,b.transition),b.shapeFlag|=512,v.delete(L),v.add(L)):(v.add(L),P&&v.size>parseInt(P,10)&&h(v.values().next().value)),b.shapeFlag|=256,s=b,ca(m.type)?m:b}}},bm=vm;function Uo(r,d){return st(r)?r.some(w=>Uo(w,d)):Gt(r)?r.split(",").includes(d):Uh(r)?r.test(d):!1}function Wd(r,d){Xd(r,"a",d)}function qd(r,d){Xd(r,"da",d)}function Xd(r,d,w=$t){const t=r.__wdc||(r.__wdc=()=>{let x=w;for(;x;){if(x.isDeactivated)return;x=x.parent}return r()});if(ui(d,t,w),w){let x=w.parent;for(;x&&x.parent;)cs(x.parent.vnode)&&_m(t,d,w,x),x=x.parent}}function _m(r,d,w,t){const x=ui(d,r,t,!0);us(()=>{Ha(t[d],x)},w)}function Fi(r){r.shapeFlag&=-257,r.shapeFlag&=-513}function Cs(r){return r.shapeFlag&128?r.ssContent:r}const kn=Symbol("_leaveCb"),Os=Symbol("_enterCb");function wm(){const r={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Qr(()=>{r.isMounted=!0}),ls(()=>{r.isUnmounting=!0}),r}const Nr=[Function,Array],Yd={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Nr,onEnter:Nr,onAfterEnter:Nr,onEnterCancelled:Nr,onBeforeLeave:Nr,onLeave:Nr,onAfterLeave:Nr,onLeaveCancelled:Nr,onBeforeAppear:Nr,onAppear:Nr,onAfterAppear:Nr,onAppearCancelled:Nr},$d=r=>{const d=r.subTree;return d.component?$d(d.component):d},xm={name:"BaseTransition",props:Yd,setup(r,{slots:d}){const w=Eo(),t=wm();return()=>{const x=d.default&&Zd(d.default(),!0);if(!x||!x.length)return;let v=x[0];if(x.length>1){for(const n of x)if(n.type!==ar){v=n;break}}const s=bt(r),{mode:c}=s;if(t.isLeaving)return Ni(v);const o=Pu(v);if(!o)return Ni(v);let u=ya(o,s,t,w,n=>u=n);es(o,u);const g=w.subTree,p=g&&Pu(g);if(p&&p.type!==ar&&!Zr(o,p)&&$d(w).type!==ar){const n=ya(p,s,t,w);if(es(p,n),c==="out-in"&&o.type!==ar)return t.isLeaving=!0,n.afterLeave=()=>{t.isLeaving=!1,w.update.active!==!1&&(w.effect.dirty=!0,w.update())},Ni(v);c==="in-out"&&o.type!==ar&&(n.delayLeave=(i,a,h)=>{const y=Kd(t,p);y[String(p.key)]=p,i[kn]=()=>{a(),i[kn]=void 0,delete u.delayedLeave},u.delayedLeave=h})}return v}}},jm=xm;function Kd(r,d){const{leavingVNodes:w}=r;let t=w.get(d.type);return t||(t=Object.create(null),w.set(d.type,t)),t}function ya(r,d,w,t,x){const{appear:v,mode:s,persisted:c=!1,onBeforeEnter:o,onEnter:u,onAfterEnter:g,onEnterCancelled:p,onBeforeLeave:n,onLeave:i,onAfterLeave:a,onLeaveCancelled:h,onBeforeAppear:y,onAppear:l,onAfterAppear:f,onAppearCancelled:m}=d,b=String(r.key),j=Kd(w,r),k=(P,L)=>{P&&zr(P,t,9,L)},E=(P,L)=>{const C=L[1];k(P,L),st(P)?P.every(I=>I.length<=1)&&C():P.length<=1&&C()},M={mode:s,persisted:c,beforeEnter(P){let L=o;if(!w.isMounted)if(v)L=y||o;else return;P[kn]&&P[kn](!0);const C=j[b];C&&Zr(r,C)&&C.el[kn]&&C.el[kn](),k(L,[P])},enter(P){let L=u,C=g,I=p;if(!w.isMounted)if(v)L=l||u,C=f||g,I=m||p;else return;let A=!1;const N=P[Os]=F=>{A||(A=!0,F?k(I,[P]):k(C,[P]),M.delayedLeave&&M.delayedLeave(),P[Os]=void 0)};L?E(L,[P,N]):N()},leave(P,L){const C=String(r.key);if(P[Os]&&P[Os](!0),w.isUnmounting)return L();k(n,[P]);let I=!1;const A=P[kn]=N=>{I||(I=!0,L(),N?k(h,[P]):k(a,[P]),P[kn]=void 0,j[C]===r&&delete j[C])};j[C]=r,i?E(i,[P,A]):A()},clone(P){const L=ya(P,d,w,t,x);return x&&x(L),L}};return M}function Ni(r){if(cs(r))return r=un(r),r.children=null,r}function Pu(r){if(!cs(r))return r;const{shapeFlag:d,children:w}=r;if(w){if(d&16)return w[0];if(d&32&&at(w.default))return w.default()}}function es(r,d){r.shapeFlag&6&&r.component?es(r.component.subTree,d):r.shapeFlag&128?(r.ssContent.transition=d.clone(r.ssContent),r.ssFallback.transition=d.clone(r.ssFallback)):r.transition=d}function Zd(r,d=!1,w){let t=[],x=0;for(let v=0;v1)for(let v=0;vr.__isTeleport,gr=Symbol.for("v-fgt"),vo=Symbol.for("v-txt"),ar=Symbol.for("v-cmt"),Ho=Symbol.for("v-stc"),zo=[];let Hr=null;function Gr(r=!1){zo.push(Hr=r?null:[])}function Qd(){zo.pop(),Hr=zo[zo.length-1]||null}let bo=1;function Au(r){bo+=r}function Jd(r){return r.dynamicChildren=bo>0?Hr||uo:null,Qd(),bo>0&&Hr&&Hr.push(r),r}function ci(r,d,w,t,x,v){return Jd(Lt(r,d,w,t,x,v,!0))}function Xn(r,d,w,t,x){return Jd(pt(r,d,w,t,x,!0))}function _o(r){return r?r.__v_isVNode===!0:!1}function Zr(r,d){return r.type===d.type&&r.key===d.key}const ef=({key:r})=>r??null,Fs=({ref:r,ref_key:d,ref_for:w})=>(typeof r=="number"&&(r=""+r),r!=null?Gt(r)||hr(r)||at(r)?{i:Kt,r,k:d,f:!!w}:r:null);function Lt(r,d=null,w=null,t=0,x=null,v=r===gr?0:1,s=!1,c=!1){const o={__v_isVNode:!0,__v_skip:!0,type:r,props:d,key:d&&ef(d),ref:d&&Fs(d),scopeId:_d,slotScopeIds:null,children:w,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:v,patchFlag:t,dynamicProps:x,dynamicChildren:null,appContext:null,ctx:Kt};return c?(al(o,w),v&128&&r.normalize(o)):w&&(o.shapeFlag|=Gt(w)?8:16),bo>0&&!s&&Hr&&(o.patchFlag>0||v&6)&&o.patchFlag!==32&&Hr.push(o),o}const pt=Em;function Em(r,d=null,w=null,t=0,x=null,v=!1){if((!r||r===xd)&&(r=ar),_o(r)){const c=un(r,d,!0);return w&&al(c,w),bo>0&&!v&&Hr&&(c.shapeFlag&6?Hr[Hr.indexOf(r)]=c:Hr.push(c)),c.patchFlag=-2,c}if(Rm(r)&&(r=r.__vccOpts),d){d=Tm(d);let{class:c,style:o}=d;c&&!Gt(c)&&(d.class=Yn(c)),Ct(o)&&(dd(o)&&!st(o)&&(o=Xt({},o)),d.style=qa(o))}const s=Gt(r)?1:ca(r)?128:Sm(r)?64:Ct(r)?4:at(r)?2:0;return Lt(r,d,w,t,x,s,v,!0)}function Tm(r){return r?dd(r)||Ld(r)?Xt({},r):r:null}function un(r,d,w=!1,t=!1){const{props:x,ref:v,patchFlag:s,children:c,transition:o}=r,u=d?tf(x||{},d):x,g={__v_isVNode:!0,__v_skip:!0,type:r.type,props:u,key:u&&ef(u),ref:d&&d.ref?w&&v?st(v)?v.concat(Fs(d)):[v,Fs(d)]:Fs(d):v,scopeId:r.scopeId,slotScopeIds:r.slotScopeIds,children:c,target:r.target,targetAnchor:r.targetAnchor,staticCount:r.staticCount,shapeFlag:r.shapeFlag,patchFlag:d&&r.type!==gr?s===-1?16:s|16:s,dynamicProps:r.dynamicProps,dynamicChildren:r.dynamicChildren,appContext:r.appContext,dirs:r.dirs,transition:o,component:r.component,suspense:r.suspense,ssContent:r.ssContent&&un(r.ssContent),ssFallback:r.ssFallback&&un(r.ssFallback),el:r.el,anchor:r.anchor,ctx:r.ctx,ce:r.ce};return o&&t&&es(g,o.clone(g)),g}function ao(r=" ",d=0){return pt(vo,null,r,d)}function k_(r,d){const w=pt(Ho,null,r);return w.staticCount=d,w}function M_(r="",d=!1){return d?(Gr(),Xn(ar,null,r)):pt(ar,null,r)}function Br(r){return r==null||typeof r=="boolean"?pt(ar):st(r)?pt(gr,null,r.slice()):typeof r=="object"?Mn(r):pt(vo,null,String(r))}function Mn(r){return r.el===null&&r.patchFlag!==-1||r.memo?r:un(r)}function al(r,d){let w=0;const{shapeFlag:t}=r;if(d==null)d=null;else if(st(d))w=16;else if(typeof d=="object")if(t&65){const x=d.default;x&&(x._c&&(x._d=!1),al(r,x()),x._c&&(x._d=!0));return}else{w=32;const x=d._;!x&&!Ld(d)?d._ctx=Kt:x===3&&Kt&&(Kt.slots._===1?d._=1:(d._=2,r.patchFlag|=1024))}else at(d)?(d={default:d,_ctx:Kt},w=32):(d=String(d),t&64?(w=16,d=[ao(d)]):w=8);r.children=d,r.shapeFlag|=w}function tf(...r){const d={};for(let w=0;w$t||Kt;let $s,ga;{const r=Yc(),d=(w,t)=>{let x;return(x=r[w])||(x=r[w]=[]),x.push(t),v=>{x.length>1?x.forEach(s=>s(v)):x[0](v)}};$s=d("__VUE_INSTANCE_SETTERS__",w=>$t=w),ga=d("__VUE_SSR_SETTERS__",w=>ds=w)}const Qn=r=>{const d=$t;return $s(r),r.scope.on(),()=>{r.scope.off(),$s(d)}},va=()=>{$t&&$t.scope.off(),$s(null)};function rf(r){return r.vnode.shapeFlag&4}let ds=!1;function Om(r,d=!1){d&&ga(d);const{props:w,children:t}=r.vnode,x=rf(r);om(r,w,x,d),am(r,t);const v=x?Pm(r,d):void 0;return d&&ga(!1),v}function Pm(r,d){const w=r.type;r.accessCache=Object.create(null),r.proxy=new Proxy(r.ctx,$p);const{setup:t}=w;if(t){const x=r.setupContext=t.length>1?of(r):null,v=Qn(r);Nn();const s=Ln(t,r,0,[r.props,x]);if(Un(),v(),za(s)){if(s.then(va,va),d)return s.then(c=>{ba(r,c,d)}).catch(c=>{So(c,r,0)});r.asyncDep=s}else ba(r,s,d)}else nf(r,d)}function ba(r,d,w){at(d)?r.type.__ssrInlineRender?r.ssrRender=d:r.render=d:Ct(d)&&(r.setupState=pd(d)),nf(r,w)}let Ru;function nf(r,d,w){const t=r.type;if(!r.render){if(!d&&Ru&&!t.render){const x=t.template||ol(r).template;if(x){const{isCustomElement:v,compilerOptions:s}=r.appContext.config,{delimiters:c,compilerOptions:o}=t,u=Xt(Xt({isCustomElement:v,delimiters:c},s),o);t.render=Ru(x,u)}}r.render=t.render||Vr}{const x=Qn(r);Nn();try{Zp(r)}finally{Un(),x()}}}const Am={get(r,d){return br(r,"get",""),r[d]}};function of(r){const d=w=>{r.exposed=w||{}};return{attrs:new Proxy(r.attrs,Am),slots:r.slots,emit:r.emit,expose:d}}function di(r){return r.exposed?r.exposeProxy||(r.exposeProxy=new Proxy(pd(bp(r.exposed)),{get(d,w){if(w in d)return d[w];if(w in Vo)return Vo[w](r)},has(d,w){return w in d||w in Vo}})):r.proxy}function _a(r,d=!0){return at(r)?r.displayName||r.name:r.name||d&&r.__name}function Rm(r){return at(r)&&"__vccOpts"in r}const jt=(r,d)=>_p(r,d,ds);function rr(r,d,w){const t=arguments.length;return t===2?Ct(d)&&!st(d)?_o(d)?pt(r,null,[d]):pt(r,d):pt(r,null,d):(t>3?w=Array.prototype.slice.call(arguments,2):t===3&&_o(w)&&(w=[w]),pt(r,d,w))}const sf="3.4.31";/** +* @vue/runtime-dom v3.4.31 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT -**/const Am="http://www.w3.org/2000/svg",Rm="http://www.w3.org/1998/Math/MathML",hn=typeof document<"u"?document:null,Iu=hn&&hn.createElement("template"),Lm={insert:(r,d,w)=>{d.insertBefore(r,w||null)},remove:r=>{const d=r.parentNode;d&&d.removeChild(r)},createElement:(r,d,w,t)=>{const x=d==="svg"?hn.createElementNS(Am,r):d==="mathml"?hn.createElementNS(Rm,r):w?hn.createElement(r,{is:w}):hn.createElement(r);return r==="select"&&t&&t.multiple!=null&&x.setAttribute("multiple",t.multiple),x},createText:r=>hn.createTextNode(r),createComment:r=>hn.createComment(r),setText:(r,d)=>{r.nodeValue=d},setElementText:(r,d)=>{r.textContent=d},parentNode:r=>r.parentNode,nextSibling:r=>r.nextSibling,querySelector:r=>hn.querySelector(r),setScopeId(r,d){r.setAttribute(d,"")},insertStaticContent(r,d,w,t,x,v){const s=w?w.previousSibling:d.lastChild;if(x&&(x===v||x.nextSibling))for(;d.insertBefore(x.cloneNode(!0),w),!(x===v||!(x=x.nextSibling)););else{Iu.innerHTML=t==="svg"?`${r}`:t==="mathml"?`${r}`:r;const c=Iu.content;if(t==="svg"||t==="mathml"){const o=c.firstChild;for(;o.firstChild;)c.appendChild(o.firstChild);c.removeChild(o)}d.insertBefore(c,w)}return[s?s.nextSibling:d.firstChild,w?w.previousSibling:d.lastChild]}},jn="transition",Do="animation",ts=Symbol("_vtc"),fs=(r,{slots:d})=>rr(wm,Im(r),d);fs.displayName="Transition";const sf={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};fs.props=Xt({},Xd,sf);const Gn=(r,d=[])=>{st(r)?r.forEach(w=>w(...d)):r&&r(...d)},Du=r=>r?st(r)?r.some(d=>d.length>1):r.length>1:!1;function Im(r){const d={};for(const I in r)I in sf||(d[I]=r[I]);if(r.css===!1)return d;const{name:w="v",type:t,duration:x,enterFromClass:v=`${w}-enter-from`,enterActiveClass:s=`${w}-enter-active`,enterToClass:c=`${w}-enter-to`,appearFromClass:o=v,appearActiveClass:u=s,appearToClass:g=c,leaveFromClass:p=`${w}-leave-from`,leaveActiveClass:n=`${w}-leave-active`,leaveToClass:i=`${w}-leave-to`}=r,a=Dm(x),h=a&&a[0],m=a&&a[1],{onBeforeEnter:l,onEnter:f,onEnterCancelled:y,onLeave:b,onLeaveCancelled:j,onBeforeAppear:k=l,onAppear:E=f,onAppearCancelled:M=y}=d,P=(I,A,N)=>{Vn(I,A?g:c),Vn(I,A?u:s),N&&N()},L=(I,A)=>{I._isLeaving=!1,Vn(I,p),Vn(I,i),Vn(I,n),A&&A()},C=I=>(A,N)=>{const F=I?E:f,B=()=>P(A,I,N);Gn(F,[A,B]),Fu(()=>{Vn(A,I?o:v),Sn(A,I?g:c),Du(F)||Nu(A,t,h,B)})};return Xt(d,{onBeforeEnter(I){Gn(l,[I]),Sn(I,v),Sn(I,s)},onBeforeAppear(I){Gn(k,[I]),Sn(I,o),Sn(I,u)},onEnter:C(!1),onAppear:C(!0),onLeave(I,A){I._isLeaving=!0;const N=()=>L(I,A);Sn(I,p),Sn(I,n),Um(),Fu(()=>{I._isLeaving&&(Vn(I,p),Sn(I,i),Du(b)||Nu(I,t,m,N))}),Gn(b,[I,N])},onEnterCancelled(I){P(I,!1),Gn(y,[I])},onAppearCancelled(I){P(I,!0),Gn(M,[I])},onLeaveCancelled(I){L(I),Gn(j,[I])}})}function Dm(r){if(r==null)return null;if(Ct(r))return[Ui(r.enter),Ui(r.leave)];{const d=Ui(r);return[d,d]}}function Ui(r){return Yc(r)}function Sn(r,d){d.split(/\s+/).forEach(w=>w&&r.classList.add(w)),(r[ts]||(r[ts]=new Set)).add(d)}function Vn(r,d){d.split(/\s+/).forEach(t=>t&&r.classList.remove(t));const w=r[ts];w&&(w.delete(d),w.size||(r[ts]=void 0))}function Fu(r){requestAnimationFrame(()=>{requestAnimationFrame(r)})}let Fm=0;function Nu(r,d,w,t){const x=r._endId=++Fm,v=()=>{x===r._endId&&t()};if(w)return setTimeout(v,w);const{type:s,timeout:c,propCount:o}=Nm(r,d);if(!s)return t();const u=s+"end";let g=0;const p=()=>{r.removeEventListener(u,n),v()},n=i=>{i.target===r&&++g>=o&&p()};setTimeout(()=>{g(w[a]||"").split(", "),x=t(`${jn}Delay`),v=t(`${jn}Duration`),s=Uu(x,v),c=t(`${Do}Delay`),o=t(`${Do}Duration`),u=Uu(c,o);let g=null,p=0,n=0;d===jn?s>0&&(g=jn,p=s,n=v.length):d===Do?u>0&&(g=Do,p=u,n=o.length):(p=Math.max(s,u),g=p>0?s>u?jn:Do:null,n=g?g===jn?v.length:o.length:0);const i=g===jn&&/\b(transform|all)(,|$)/.test(t(`${jn}Property`).toString());return{type:g,timeout:p,propCount:n,hasTransform:i}}function Uu(r,d){for(;r.lengthBu(w)+Bu(r[t])))}function Bu(r){return r==="auto"?0:Number(r.slice(0,-1).replace(",","."))*1e3}function Um(){return document.body.offsetHeight}function Bm(r,d,w){const t=r[ts];t&&(d=(d?[d,...t]:[...t]).join(" ")),d==null?r.removeAttribute("class"):w?r.setAttribute("class",d):r.className=d}const Gu=Symbol("_vod"),Gm=Symbol("_vsh"),Vm=Symbol(""),Hm=/(^|;)\s*display\s*:/;function zm(r,d,w){const t=r.style,x=Gt(w);let v=!1;if(w&&!x){if(d)if(Gt(d))for(const s of d.split(";")){const c=s.slice(0,s.indexOf(":")).trim();w[c]==null&&Ns(t,c,"")}else for(const s in d)w[s]==null&&Ns(t,s,"");for(const s in w)s==="display"&&(v=!0),Ns(t,s,w[s])}else if(x){if(d!==w){const s=t[Vm];s&&(w+=";"+s),t.cssText=w,v=Hm.test(w)}}else d&&r.removeAttribute("style");Gu in r&&(r[Gu]=v?t.display:"",r[Gm]&&(t.display="none"))}const Vu=/\s*!important$/;function Ns(r,d,w){if(st(w))w.forEach(t=>Ns(r,d,t));else if(w==null&&(w=""),d.startsWith("--"))r.setProperty(d,w);else{const t=Wm(r,d);Vu.test(w)?r.setProperty(jo(t),w.replace(Vu,""),"important"):r[t]=w}}const Hu=["Webkit","Moz","ms"],Bi={};function Wm(r,d){const w=Bi[d];if(w)return w;let t=an(d);if(t!=="filter"&&t in r)return Bi[d]=t;t=si(t);for(let x=0;xGi||(Km.then(()=>Gi=0),Gi=Date.now());function Qm(r,d){const w=t=>{if(!t._vts)t._vts=Date.now();else if(t._vts<=w.attached)return;zr(Jm(t,w.value),d,5,[t])};return w.value=r,w.attached=Zm(),w}function Jm(r,d){if(st(d)){const w=r.stopImmediatePropagation;return r.stopImmediatePropagation=()=>{w.call(r),r._stopped=!0},d.map(t=>x=>!x._stopped&&t&&t(x))}else return d}const Yu=r=>r.charCodeAt(0)===111&&r.charCodeAt(1)===110&&r.charCodeAt(2)>96&&r.charCodeAt(2)<123,ey=(r,d,w,t,x,v,s,c,o)=>{const u=x==="svg";d==="class"?Bm(r,t,u):d==="style"?zm(r,w,t):ss(d)?Va(d)||Ym(r,d,w,t,s):(d[0]==="."?(d=d.slice(1),!0):d[0]==="^"?(d=d.slice(1),!1):ty(r,d,t,u))?(qm(r,d,t,v,s,c,o),(d==="value"||d==="checked"||d==="selected")&&Wu(r,d,t,u,s,d!=="value")):(d==="true-value"?r._trueValue=t:d==="false-value"&&(r._falseValue=t),Wu(r,d,t,u))};function ty(r,d,w,t){if(t)return!!(d==="innerHTML"||d==="textContent"||d in r&&Yu(d)&&at(w));if(d==="spellcheck"||d==="draggable"||d==="translate"||d==="form"||d==="list"&&r.tagName==="INPUT"||d==="type"&&r.tagName==="TEXTAREA")return!1;if(d==="width"||d==="height"){const x=r.tagName;if(x==="IMG"||x==="VIDEO"||x==="CANVAS"||x==="SOURCE")return!1}return Yu(d)&&Gt(w)?!1:d in r}const $u=r=>{const d=r.props["onUpdate:modelValue"]||!1;return st(d)?w=>ho(d,w):d};function ry(r){r.target.composing=!0}function Ku(r){const d=r.target;d.composing&&(d.composing=!1,d.dispatchEvent(new Event("input")))}const Vi=Symbol("_assign"),M_={created(r,{modifiers:{lazy:d,trim:w,number:t}},x){r[Vi]=$u(x);const v=t||x.props&&x.props.type==="number";so(r,d?"change":"input",s=>{if(s.target.composing)return;let c=r.value;w&&(c=c.trim()),v&&(c=oa(c)),r[Vi](c)}),w&&so(r,"change",()=>{r.value=r.value.trim()}),d||(so(r,"compositionstart",ry),so(r,"compositionend",Ku),so(r,"change",Ku))},mounted(r,{value:d}){r.value=d??""},beforeUpdate(r,{value:d,oldValue:w,modifiers:{lazy:t,trim:x,number:v}},s){if(r[Vi]=$u(s),r.composing)return;const c=(v||r.type==="number")&&!/^0\d/.test(r.value)?oa(r.value):r.value,o=d??"";c!==o&&(document.activeElement===r&&r.type!=="range"&&(t&&d===w||x&&r.value.trim()===o)||(r.value=o))}},af=Xt({patchProp:ey},Lm);let Wo,Zu=!1;function ny(){return Wo||(Wo=cm(af))}function oy(){return Wo=Zu?Wo:dm(af),Zu=!0,Wo}const sy=(...r)=>{const d=ny().createApp(...r),{mount:w}=d;return d.mount=t=>{const x=uf(t);if(!x)return;const v=d._component;!at(v)&&!v.render&&!v.template&&(v.template=x.innerHTML),x.innerHTML="";const s=w(x,!1,lf(x));return x instanceof Element&&(x.removeAttribute("v-cloak"),x.setAttribute("data-v-app","")),s},d},iy=(...r)=>{const d=oy().createApp(...r),{mount:w}=d;return d.mount=t=>{const x=uf(t);if(x)return w(x,!0,lf(x))},d};function lf(r){if(r instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&r instanceof MathMLElement)return"mathml"}function uf(r){return Gt(r)?document.querySelector(r):r}const ay=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,ly=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,uy=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function cy(r,d){if(r==="__proto__"||r==="constructor"&&d&&typeof d=="object"&&"prototype"in d){dy(r);return}return d}function dy(r){console.warn(`[destr] Dropping "${r}" key to prevent prototype pollution.`)}function Ks(r,d={}){if(typeof r!="string")return r;const w=r.trim();if(r[0]==='"'&&r.endsWith('"')&&!r.includes("\\"))return w.slice(1,-1);if(w.length<=9){const t=w.toLowerCase();if(t==="true")return!0;if(t==="false")return!1;if(t==="undefined")return;if(t==="null")return null;if(t==="nan")return Number.NaN;if(t==="infinity")return Number.POSITIVE_INFINITY;if(t==="-infinity")return Number.NEGATIVE_INFINITY}if(!uy.test(r)){if(d.strict)throw new SyntaxError("[destr] Invalid JSON");return r}try{if(ay.test(r)||ly.test(r)){if(d.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(r,cy)}return JSON.parse(r)}catch(t){if(d.strict)throw t;return r}}const fy=/#/g,hy=/&/g,py=/\//g,my=/=/g,ul=/\+/g,yy=/%5e/gi,gy=/%60/gi,vy=/%7c/gi,by=/%20/gi;function _y(r){return encodeURI(""+r).replace(vy,"|")}function wa(r){return _y(typeof r=="string"?r:JSON.stringify(r)).replace(ul,"%2B").replace(by,"+").replace(fy,"%23").replace(hy,"%26").replace(gy,"`").replace(yy,"^").replace(py,"%2F")}function Hi(r){return wa(r).replace(my,"%3D")}function Zs(r=""){try{return decodeURIComponent(""+r)}catch{return""+r}}function wy(r){return Zs(r.replace(ul," "))}function xy(r){return Zs(r.replace(ul," "))}function cf(r=""){const d={};r[0]==="?"&&(r=r.slice(1));for(const w of r.split("&")){const t=w.match(/([^=]+)=?(.*)/)||[];if(t.length<2)continue;const x=wy(t[1]);if(x==="__proto__"||x==="constructor")continue;const v=xy(t[2]||"");d[x]===void 0?d[x]=v:Array.isArray(d[x])?d[x].push(v):d[x]=[d[x],v]}return d}function jy(r,d){return(typeof d=="number"||typeof d=="boolean")&&(d=String(d)),d?Array.isArray(d)?d.map(w=>`${Hi(r)}=${wa(w)}`).join("&"):`${Hi(r)}=${wa(d)}`:Hi(r)}function Sy(r){return Object.keys(r).filter(d=>r[d]!==void 0).map(d=>jy(d,r[d])).filter(Boolean).join("&")}const Ey=/^[\s\w\0+.-]{2,}:([/\\]{1,2})/,Ty=/^[\s\w\0+.-]{2,}:([/\\]{2})?/,ky=/^([/\\]\s*){2,}[^/\\]/,My=/^[\s\0]*(blob|data|javascript|vbscript):$/i,Cy=/\/$|\/\?|\/#/,Oy=/^\.?\//;function gn(r,d={}){return typeof d=="boolean"&&(d={acceptRelative:d}),d.strict?Ey.test(r):Ty.test(r)||(d.acceptRelative?ky.test(r):!1)}function Py(r){return!!r&&My.test(r)}function xa(r="",d){return d?Cy.test(r):r.endsWith("/")}function fi(r="",d){if(!d)return(xa(r)?r.slice(0,-1):r)||"/";if(!xa(r,!0))return r||"/";let w=r,t="";const x=r.indexOf("#");x>=0&&(w=r.slice(0,x),t=r.slice(x));const[v,...s]=w.split("?");return((v.endsWith("/")?v.slice(0,-1):v)||"/")+(s.length>0?`?${s.join("?")}`:"")+t}function Qs(r="",d){if(!d)return r.endsWith("/")?r:r+"/";if(xa(r,!0))return r||"/";let w=r,t="";const x=r.indexOf("#");if(x>=0&&(w=r.slice(0,x),t=r.slice(x),!w))return t;const[v,...s]=w.split("?");return v+"/"+(s.length>0?`?${s.join("?")}`:"")+t}function Ay(r=""){return r.startsWith("/")}function Qu(r=""){return Ay(r)?r:"/"+r}function Ry(r,d){if(ff(d)||gn(r))return r;const w=fi(d);return r.startsWith(w)?r:hi(w,r)}function Ju(r,d){if(ff(d))return r;const w=fi(d);if(!r.startsWith(w))return r;const t=r.slice(w.length);return t[0]==="/"?t:"/"+t}function df(r,d){const w=hs(r),t={...cf(w.search),...d};return w.search=Sy(t),Dy(w)}function ff(r){return!r||r==="/"}function Ly(r){return r&&r!=="/"}function hi(r,...d){let w=r||"";for(const t of d.filter(x=>Ly(x)))if(w){const x=t.replace(Oy,"");w=Qs(w)+x}else w=t;return w}function hf(...r){var s,c,o,u;const d=/\/(?!\/)/,w=r.filter(Boolean),t=[];let x=0;for(const g of w)if(!(!g||g==="/")){for(const[p,n]of g.split(d).entries())if(!(!n||n===".")){if(n===".."){if(t.length===1&&gn(t[0]))continue;t.pop(),x--;continue}if(p===1&&((s=t[t.length-1])!=null&&s.endsWith(":/"))){t[t.length-1]+="/"+n;continue}t.push(n),x++}}let v=t.join("/");return x>=0?(c=w[0])!=null&&c.startsWith("/")&&!v.startsWith("/")?v="/"+v:(o=w[0])!=null&&o.startsWith("./")&&!v.startsWith("./")&&(v="./"+v):v="../".repeat(-1*x)+v,(u=w[w.length-1])!=null&&u.endsWith("/")&&!v.endsWith("/")&&(v+="/"),v}function Iy(r,d,w={}){return w.trailingSlash||(r=Qs(r),d=Qs(d)),w.leadingSlash||(r=Qu(r),d=Qu(d)),w.encoding||(r=Zs(r),d=Zs(d)),r===d}const pf=Symbol.for("ufo:protocolRelative");function hs(r="",d){const w=r.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);if(w){const[,p,n=""]=w;return{protocol:p.toLowerCase(),pathname:n,href:p+n,auth:"",host:"",search:"",hash:""}}if(!gn(r,{acceptRelative:!0}))return d?hs(d+r):ec(r);const[,t="",x,v=""]=r.replace(/\\/g,"/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/)||[],[,s="",c=""]=v.match(/([^#/?]*)(.*)?/)||[],{pathname:o,search:u,hash:g}=ec(c.replace(/\/(?=[A-Za-z]:)/,""));return{protocol:t.toLowerCase(),auth:x?x.slice(0,Math.max(0,x.length-1)):"",host:s,pathname:o,search:u,hash:g,[pf]:!t}}function ec(r=""){const[d="",w="",t=""]=(r.match(/([^#?]*)(\?[^#]*)?(#.*)?/)||[]).splice(1);return{pathname:d,search:w,hash:t}}function Dy(r){const d=r.pathname||"",w=r.search?(r.search.startsWith("?")?"":"?")+r.search:"",t=r.hash||"",x=r.auth?r.auth+"@":"",v=r.host||"";return(r.protocol||r[pf]?(r.protocol||"")+"//":"")+x+v+d+w+t}class Fy extends Error{constructor(d,w){super(d,w),this.name="FetchError",w!=null&&w.cause&&!this.cause&&(this.cause=w.cause)}}function Ny(r){var o,u,g,p,n;const d=((o=r.error)==null?void 0:o.message)||((u=r.error)==null?void 0:u.toString())||"",w=((g=r.request)==null?void 0:g.method)||((p=r.options)==null?void 0:p.method)||"GET",t=((n=r.request)==null?void 0:n.url)||String(r.request)||"/",x=`[${w}] ${JSON.stringify(t)}`,v=r.response?`${r.response.status} ${r.response.statusText}`:"",s=`${x}: ${v}${d?` ${d}`:""}`,c=new Fy(s,r.error?{cause:r.error}:void 0);for(const i of["request","options","response"])Object.defineProperty(c,i,{get(){return r[i]}});for(const[i,a]of[["data","_data"],["status","status"],["statusCode","status"],["statusText","statusText"],["statusMessage","statusText"]])Object.defineProperty(c,i,{get(){return r.response&&r.response[a]}});return c}const Uy=new Set(Object.freeze(["PATCH","POST","PUT","DELETE"]));function tc(r="GET"){return Uy.has(r.toUpperCase())}function By(r){if(r===void 0)return!1;const d=typeof r;return d==="string"||d==="number"||d==="boolean"||d===null?!0:d!=="object"?!1:Array.isArray(r)?!0:r.buffer?!1:r.constructor&&r.constructor.name==="Object"||typeof r.toJSON=="function"}const Gy=new Set(["image/svg","application/xml","application/xhtml","application/html"]),Vy=/^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;function Hy(r=""){if(!r)return"json";const d=r.split(";").shift()||"";return Vy.test(d)?"json":Gy.has(d)||d.startsWith("text/")?"text":"blob"}function zy(r,d,w=globalThis.Headers){const t={...d,...r};if(d!=null&&d.params&&(r!=null&&r.params)&&(t.params={...d==null?void 0:d.params,...r==null?void 0:r.params}),d!=null&&d.query&&(r!=null&&r.query)&&(t.query={...d==null?void 0:d.query,...r==null?void 0:r.query}),d!=null&&d.headers&&(r!=null&&r.headers)){t.headers=new w((d==null?void 0:d.headers)||{});for(const[x,v]of new w((r==null?void 0:r.headers)||{}))t.headers.set(x,v)}return t}const Wy=new Set([408,409,425,429,500,502,503,504]),qy=new Set([101,204,205,304]);function mf(r={}){const{fetch:d=globalThis.fetch,Headers:w=globalThis.Headers,AbortController:t=globalThis.AbortController}=r;async function x(c){const o=c.error&&c.error.name==="AbortError"&&!c.options.timeout||!1;if(c.options.retry!==!1&&!o){let g;typeof c.options.retry=="number"?g=c.options.retry:g=tc(c.options.method)?0:1;const p=c.response&&c.response.status||500;if(g>0&&(Array.isArray(c.options.retryStatusCodes)?c.options.retryStatusCodes.includes(p):Wy.has(p))){const n=c.options.retryDelay||0;return n>0&&await new Promise(i=>setTimeout(i,n)),v(c.request,{...c.options,retry:g-1})}}const u=Ny(c);throw Error.captureStackTrace&&Error.captureStackTrace(u,v),u}const v=async function(o,u={}){var i;const g={request:o,options:zy(u,r.defaults,w),response:void 0,error:void 0};g.options.method=(i=g.options.method)==null?void 0:i.toUpperCase(),g.options.onRequest&&await g.options.onRequest(g),typeof g.request=="string"&&(g.options.baseURL&&(g.request=Ry(g.request,g.options.baseURL)),(g.options.query||g.options.params)&&(g.request=df(g.request,{...g.options.params,...g.options.query}))),g.options.body&&tc(g.options.method)&&(By(g.options.body)?(g.options.body=typeof g.options.body=="string"?g.options.body:JSON.stringify(g.options.body),g.options.headers=new w(g.options.headers||{}),g.options.headers.has("content-type")||g.options.headers.set("content-type","application/json"),g.options.headers.has("accept")||g.options.headers.set("accept","application/json")):("pipeTo"in g.options.body&&typeof g.options.body.pipeTo=="function"||typeof g.options.body.pipe=="function")&&("duplex"in g.options||(g.options.duplex="half")));let p;if(!g.options.signal&&g.options.timeout){const a=new t;p=setTimeout(()=>a.abort(),g.options.timeout),g.options.signal=a.signal}try{g.response=await d(g.request,g.options)}catch(a){return g.error=a,g.options.onRequestError&&await g.options.onRequestError(g),await x(g)}finally{p&&clearTimeout(p)}if(g.response.body&&!qy.has(g.response.status)&&g.options.method!=="HEAD"){const a=(g.options.parseResponse?"json":g.options.responseType)||Hy(g.response.headers.get("content-type")||"");switch(a){case"json":{const h=await g.response.text(),m=g.options.parseResponse||Ks;g.response._data=m(h);break}case"stream":{g.response._data=g.response.body;break}default:g.response._data=await g.response[a]()}}return g.options.onResponse&&await g.options.onResponse(g),!g.options.ignoreResponseError&&g.response.status>=400&&g.response.status<600?(g.options.onResponseError&&await g.options.onResponseError(g),await x(g)):g.response},s=async function(o,u){return(await v(o,u))._data};return s.raw=v,s.native=(...c)=>d(...c),s.create=(c={})=>mf({...r,defaults:{...r.defaults,...c}}),s}const cl=function(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global;throw new Error("unable to locate global object")}(),Xy=cl.fetch||(()=>Promise.reject(new Error("[ofetch] global.fetch is not supported!"))),Yy=cl.Headers,$y=cl.AbortController,Ky=mf({fetch:Xy,Headers:Yy,AbortController:$y}),Zy=Ky,Qy=()=>{var r;return((r=window==null?void 0:window.__NUXT__)==null?void 0:r.config)||{}},Js=Qy().app,Jy=()=>Js.baseURL,eg=()=>Js.buildAssetsDir,dl=(...r)=>hf(yf(),eg(),...r),yf=(...r)=>{const d=Js.cdnURL||Js.baseURL;return r.length?hf(d,...r):d};globalThis.__buildAssetsURL=dl,globalThis.__publicAssetsURL=yf;globalThis.$fetch||(globalThis.$fetch=Zy.create({baseURL:Jy()}));function ja(r,d={},w){for(const t in r){const x=r[t],v=w?`${w}:${t}`:t;typeof x=="object"&&x!==null?ja(x,d,v):typeof x=="function"&&(d[v]=x)}return d}const tg={run:r=>r()},rg=()=>tg,gf=typeof console.createTask<"u"?console.createTask:rg;function ng(r,d){const w=d.shift(),t=gf(w);return r.reduce((x,v)=>x.then(()=>t.run(()=>v(...d))),Promise.resolve())}function og(r,d){const w=d.shift(),t=gf(w);return Promise.all(r.map(x=>t.run(()=>x(...d))))}function zi(r,d){for(const w of[...r])w(d)}class sg{constructor(){this._hooks={},this._before=void 0,this._after=void 0,this._deprecatedMessages=void 0,this._deprecatedHooks={},this.hook=this.hook.bind(this),this.callHook=this.callHook.bind(this),this.callHookWith=this.callHookWith.bind(this)}hook(d,w,t={}){if(!d||typeof w!="function")return()=>{};const x=d;let v;for(;this._deprecatedHooks[d];)v=this._deprecatedHooks[d],d=v.to;if(v&&!t.allowDeprecated){let s=v.message;s||(s=`${x} hook has been deprecated`+(v.to?`, please use ${v.to}`:"")),this._deprecatedMessages||(this._deprecatedMessages=new Set),this._deprecatedMessages.has(s)||(console.warn(s),this._deprecatedMessages.add(s))}if(!w.name)try{Object.defineProperty(w,"name",{get:()=>"_"+d.replace(/\W+/g,"_")+"_hook_cb",configurable:!0})}catch{}return this._hooks[d]=this._hooks[d]||[],this._hooks[d].push(w),()=>{w&&(this.removeHook(d,w),w=void 0)}}hookOnce(d,w){let t,x=(...v)=>(typeof t=="function"&&t(),t=void 0,x=void 0,w(...v));return t=this.hook(d,x),t}removeHook(d,w){if(this._hooks[d]){const t=this._hooks[d].indexOf(w);t!==-1&&this._hooks[d].splice(t,1),this._hooks[d].length===0&&delete this._hooks[d]}}deprecateHook(d,w){this._deprecatedHooks[d]=typeof w=="string"?{to:w}:w;const t=this._hooks[d]||[];delete this._hooks[d];for(const x of t)this.hook(d,x)}deprecateHooks(d){Object.assign(this._deprecatedHooks,d);for(const w in d)this.deprecateHook(w,d[w])}addHooks(d){const w=ja(d),t=Object.keys(w).map(x=>this.hook(x,w[x]));return()=>{for(const x of t.splice(0,t.length))x()}}removeHooks(d){const w=ja(d);for(const t in w)this.removeHook(t,w[t])}removeAllHooks(){for(const d in this._hooks)delete this._hooks[d]}callHook(d,...w){return w.unshift(d),this.callHookWith(ng,d,...w)}callHookParallel(d,...w){return w.unshift(d),this.callHookWith(og,d,...w)}callHookWith(d,w,...t){const x=this._before||this._after?{name:w,args:t,context:{}}:void 0;this._before&&zi(this._before,x);const v=d(w in this._hooks?[...this._hooks[w]]:[],t);return v instanceof Promise?v.finally(()=>{this._after&&x&&zi(this._after,x)}):(this._after&&x&&zi(this._after,x),v)}beforeEach(d){return this._before=this._before||[],this._before.push(d),()=>{if(this._before!==void 0){const w=this._before.indexOf(d);w!==-1&&this._before.splice(w,1)}}}afterEach(d){return this._after=this._after||[],this._after.push(d),()=>{if(this._after!==void 0){const w=this._after.indexOf(d);w!==-1&&this._after.splice(w,1)}}}}function vf(){return new sg}function ig(r={}){let d,w=!1;const t=s=>{if(d&&d!==s)throw new Error("Context conflict")};let x;if(r.asyncContext){const s=r.AsyncLocalStorage||globalThis.AsyncLocalStorage;s?x=new s:console.warn("[unctx] `AsyncLocalStorage` is not provided.")}const v=()=>{if(x&&d===void 0){const s=x.getStore();if(s!==void 0)return s}return d};return{use:()=>{const s=v();if(s===void 0)throw new Error("Context is not available");return s},tryUse:()=>v(),set:(s,c)=>{c||t(s),d=s,w=!0},unset:()=>{d=void 0,w=!1},call:(s,c)=>{t(s),d=s;try{return x?x.run(s,c):c()}finally{w||(d=void 0)}},async callAsync(s,c){d=s;const o=()=>{d=s},u=()=>d===s?o:void 0;Sa.add(u);try{const g=x?x.run(s,c):c();return w||(d=void 0),await g}finally{Sa.delete(u)}}}}function ag(r={}){const d={};return{get(w,t={}){return d[w]||(d[w]=ig({...r,...t})),d[w],d[w]}}}const ei=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof global<"u"?global:typeof window<"u"?window:{},rc="__unctx__",lg=ei[rc]||(ei[rc]=ag()),ug=(r,d={})=>lg.get(r,d),nc="__unctx_async_handlers__",Sa=ei[nc]||(ei[nc]=new Set);function rs(r){const d=[];for(const x of Sa){const v=x();v&&d.push(v)}const w=()=>{for(const x of d)x()};let t=r();return t&&typeof t=="object"&&"catch"in t&&(t=t.catch(x=>{throw w(),x})),[t,w]}const bf=ug("nuxt-app",{asyncContext:!1}),cg="__nuxt_plugin";function dg(r){let d=0;const w={_scope:Yh(),provide:void 0,globalName:"nuxt",versions:{get nuxt(){return"3.11.2"},get vue(){return w.vueApp.version}},payload:Un({data:{},state:{},once:new Set,_errors:{},...window.__NUXT__??{}}),static:{data:{}},runWithContext:x=>w._scope.run(()=>pg(w,x)),isHydrating:!0,deferHydration(){if(!w.isHydrating)return()=>{};d++;let x=!1;return()=>{if(!x&&(x=!0,d--,d===0))return w.isHydrating=!1,w.callHook("app:suspense:resolve")}},_asyncDataPromises:{},_asyncData:{},_payloadRevivers:{},...r};w.hooks=vf(),w.hook=w.hooks.hook,w.callHook=w.hooks.callHook,w.provide=(x,v)=>{const s="$"+x;Ps(w,s,v),Ps(w.vueApp.config.globalProperties,s,v)},Ps(w.vueApp,"$nuxt",w),Ps(w.vueApp.config.globalProperties,"$nuxt",w);{window.addEventListener("nuxt.preloadError",v=>{w.callHook("app:chunkError",{error:v.payload})}),window.useNuxtApp=window.useNuxtApp||It;const x=w.hook("app:error",(...v)=>{console.error("[nuxt] error caught during app initialization",...v)});w.hook("app:mounted",x)}const t=w.payload.config;return w.provide("config",t),w}async function fg(r,d){if(d.hooks&&r.hooks.addHooks(d.hooks),typeof d=="function"){const{provide:w}=await r.runWithContext(()=>d(r))||{};if(w&&typeof w=="object")for(const t in w)r.provide(t,w[t])}}async function hg(r,d){const w=[],t=[],x=[],v=[];let s=0;async function c(o){var g;const u=((g=o.dependsOn)==null?void 0:g.filter(p=>d.some(n=>n._name===p)&&!w.includes(p)))??[];if(u.length>0)t.push([new Set(u),o]);else{const p=fg(r,o).then(async()=>{o._name&&(w.push(o._name),await Promise.all(t.map(async([n,i])=>{n.has(o._name)&&(n.delete(o._name),n.size===0&&(s++,await c(i)))})))});o.parallel?x.push(p.catch(n=>v.push(n))):await p}}for(const o of d)await c(o);if(await Promise.all(x),s)for(let o=0;o{}),r,{[cg]:!0,_name:d})}function pg(r,d,w){const t=()=>d();return bf.set(r),r.vueApp.runWithContext(t)}function mg(){var d;let r;return Od()&&(r=(d=Eo())==null?void 0:d.appContext.app.$nuxt),r=r||bf.tryUse(),r||null}function It(){const r=mg();if(!r)throw new Error("[nuxt] instance unavailable");return r}function pi(r){return It().$config}function Ps(r,d,w){Object.defineProperty(r,d,{get:()=>w})}function yg(r,d){return{ctx:{table:r},matchAll:w=>wf(w,r)}}function _f(r){const d={};for(const w in r)d[w]=w==="dynamic"?new Map(Object.entries(r[w]).map(([t,x])=>[t,_f(x)])):new Map(Object.entries(r[w]));return d}function gg(r){return yg(_f(r))}function wf(r,d,w){r.endsWith("/")&&(r=r.slice(0,-1)||"/");const t=[];for(const[v,s]of oc(d.wildcard))(r===v||r.startsWith(v+"/"))&&t.push(s);for(const[v,s]of oc(d.dynamic))if(r.startsWith(v+"/")){const c="/"+r.slice(v.length).split("/").splice(2).join("/");t.push(...wf(c,s))}const x=d.static.get(r);return x&&t.push(x),t.filter(Boolean)}function oc(r){return[...r.entries()].sort((d,w)=>d[0].length-w[0].length)}function Wi(r){if(r===null||typeof r!="object")return!1;const d=Object.getPrototypeOf(r);return d!==null&&d!==Object.prototype&&Object.getPrototypeOf(d)!==null||Symbol.iterator in r?!1:Symbol.toStringTag in r?Object.prototype.toString.call(r)==="[object Module]":!0}function Ea(r,d,w=".",t){if(!Wi(d))return Ea(r,{},w,t);const x=Object.assign({},d);for(const v in r){if(v==="__proto__"||v==="constructor")continue;const s=r[v];s!=null&&(t&&t(x,v,s,w)||(Array.isArray(s)&&Array.isArray(x[v])?x[v]=[...s,...x[v]]:Wi(s)&&Wi(x[v])?x[v]=Ea(s,x[v],(w?`${w}.`:"")+v.toString(),t):x[v]=s))}return x}function xf(r){return(...d)=>d.reduce((w,t)=>Ea(w,t,"",r),{})}const jf=xf(),vg=xf((r,d,w)=>{if(r[d]!==void 0&&typeof w=="function")return r[d]=w(r[d]),!0});function bg(r,d){try{return d in r}catch{return!1}}var _g=Object.defineProperty,wg=(r,d,w)=>d in r?_g(r,d,{enumerable:!0,configurable:!0,writable:!0,value:w}):r[d]=w,zn=(r,d,w)=>(wg(r,typeof d!="symbol"?d+"":d,w),w);class Ta extends Error{constructor(d,w={}){super(d,w),zn(this,"statusCode",500),zn(this,"fatal",!1),zn(this,"unhandled",!1),zn(this,"statusMessage"),zn(this,"data"),zn(this,"cause"),w.cause&&!this.cause&&(this.cause=w.cause)}toJSON(){const d={message:this.message,statusCode:Ma(this.statusCode,500)};return this.statusMessage&&(d.statusMessage=Sf(this.statusMessage)),this.data!==void 0&&(d.data=this.data),d}}zn(Ta,"__h3_error__",!0);function ka(r){if(typeof r=="string")return new Ta(r);if(xg(r))return r;const d=new Ta(r.message??r.statusMessage??"",{cause:r.cause||r});if(bg(r,"stack"))try{Object.defineProperty(d,"stack",{get(){return r.stack}})}catch{try{d.stack=r.stack}catch{}}if(r.data&&(d.data=r.data),r.statusCode?d.statusCode=Ma(r.statusCode,d.statusCode):r.status&&(d.statusCode=Ma(r.status,d.statusCode)),r.statusMessage?d.statusMessage=r.statusMessage:r.statusText&&(d.statusMessage=r.statusText),d.statusMessage){const w=d.statusMessage;Sf(d.statusMessage)!==w&&console.warn("[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default.")}return r.fatal!==void 0&&(d.fatal=r.fatal),r.unhandled!==void 0&&(d.unhandled=r.unhandled),d}function xg(r){var d;return((d=r==null?void 0:r.constructor)==null?void 0:d.__h3_error__)===!0}const jg=/[^\u0009\u0020-\u007E]/g;function Sf(r=""){return r.replace(jg,"")}function Ma(r,d=200){return!r||(typeof r=="string"&&(r=Number.parseInt(r,10)),r<100||r>999)?d:r}const Ef=Symbol("layout-meta"),ps=Symbol("route"),qr=()=>{var r;return(r=It())==null?void 0:r.$router},mi=()=>Od()?Ht(ps,It()._route):It()._route;const Sg=()=>{try{if(It()._processingMiddleware)return!0}catch{return!1}return!1},Eg=(r,d)=>{r||(r="/");const w=typeof r=="string"?r:df(r.path||"/",r.query||{})+(r.hash||"");if(d!=null&&d.open){const{target:c="_blank",windowFeatures:o={}}=d.open,u=Object.entries(o).filter(([g,p])=>p!==void 0).map(([g,p])=>`${g.toLowerCase()}=${p}`).join(", ");return open(w,c,u),Promise.resolve()}const t=(d==null?void 0:d.external)||gn(w,{acceptRelative:!0});if(t){if(!(d!=null&&d.external))throw new Error("Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`.");const c=hs(w).protocol;if(c&&Py(c))throw new Error(`Cannot navigate to a URL with '${c}' protocol.`)}const x=Sg();if(!t&&x)return r;const v=qr(),s=It();return t?(s._scope.stop(),d!=null&&d.replace?location.replace(w):location.href=w,x?s.isHydrating?new Promise(()=>{}):!1:Promise.resolve()):d!=null&&d.replace?v.replace(r):v.push(r)},Tf="__nuxt_error",yi=()=>Sp(It().payload,"error"),lo=r=>{const d=gi(r);try{const w=It(),t=yi();w.hooks.callHook("app:error",d),t.value=t.value||d}catch{throw d}return d},Tg=async(r={})=>{const d=It(),w=yi();d.callHook("app:error:cleared",r),r.redirect&&await qr().replace(r.redirect),w.value=null},kg=r=>!!r&&typeof r=="object"&&Tf in r,gi=r=>{const d=ka(r);return Object.defineProperty(d,Tf,{value:!0,configurable:!1,writable:!1}),d},Mg=-1,Cg=-2,Og=-3,Pg=-4,Ag=-5,Rg=-6;function Lg(r,d){return Ig(JSON.parse(r),d)}function Ig(r,d){if(typeof r=="number")return x(r,!0);if(!Array.isArray(r)||r.length===0)throw new Error("Invalid input");const w=r,t=Array(w.length);function x(v,s=!1){if(v===Mg)return;if(v===Og)return NaN;if(v===Pg)return 1/0;if(v===Ag)return-1/0;if(v===Rg)return-0;if(s)throw new Error("Invalid input");if(v in t)return t[v];const c=w[v];if(!c||typeof c!="object")t[v]=c;else if(Array.isArray(c))if(typeof c[0]=="string"){const o=c[0],u=d==null?void 0:d[o];if(u)return t[v]=u(x(c[1]));switch(o){case"Date":t[v]=new Date(c[1]);break;case"Set":const g=new Set;t[v]=g;for(let i=1;i>>9)+65536).toString(16).substring(1,8).toLowerCase()}function sc(r){return r._h||fl(r._d?r._d:`${r.tag}:${r.textContent||r.innerHTML||""}:${Object.entries(r.props).map(([d,w])=>`${d}:${String(w)}`).join(",")}`)}function Mf(r,d){const{props:w,tag:t}=r;if(Ug.includes(t))return t;if(t==="link"&&w.rel==="canonical")return"canonical";if(w.charset)return"charset";const x=["id"];t==="meta"&&x.push("name","property","http-equiv");for(const v of x)if(typeof w[v]<"u"){const s=String(w[v]);return`${t}:${v}:${s}`}return!1}function ic(r,d){return r==null?d||null:typeof r=="function"?r(d):r}function Cf(r,d){const w=[],t=d.resolveKeyData||(v=>v.key),x=d.resolveValueData||(v=>v.value);for(const[v,s]of Object.entries(r))w.push(...(Array.isArray(s)?s:[s]).map(c=>{const o={key:v,value:c},u=x(o);return typeof u=="object"?Cf(u,d):Array.isArray(u)?u:{[typeof d.key=="function"?d.key(o):d.key]:t(o),[typeof d.value=="function"?d.value(o):d.value]:u}}).flat());return w}function Of(r,d){return Object.entries(r).map(([w,t])=>{if(typeof t=="object"&&(t=Of(t,d)),d.resolve){const x=d.resolve({key:w,value:t});if(typeof x<"u")return x}return typeof t=="number"&&(t=t.toString()),typeof t=="string"&&d.wrapValue&&(t=t.replace(new RegExp(d.wrapValue,"g"),`\\${d.wrapValue}`),t=`${d.wrapValue}${t}${d.wrapValue}`),`${w}${d.keyValueSeparator||""}${t}`}).join(d.entrySeparator||"")}const mr=r=>({keyValue:r,metaKey:"property"}),qi=r=>({keyValue:r}),hl={appleItunesApp:{unpack:{entrySeparator:", ",resolve({key:r,value:d}){return`${pn(r)}=${d}`}}},articleExpirationTime:mr("article:expiration_time"),articleModifiedTime:mr("article:modified_time"),articlePublishedTime:mr("article:published_time"),bookReleaseDate:mr("book:release_date"),charset:{metaKey:"charset"},contentSecurityPolicy:{unpack:{entrySeparator:"; ",resolve({key:r,value:d}){return`${pn(r)} ${d}`}},metaKey:"http-equiv"},contentType:{metaKey:"http-equiv"},defaultStyle:{metaKey:"http-equiv"},fbAppId:mr("fb:app_id"),msapplicationConfig:qi("msapplication-Config"),msapplicationTileColor:qi("msapplication-TileColor"),msapplicationTileImage:qi("msapplication-TileImage"),ogAudioSecureUrl:mr("og:audio:secure_url"),ogAudioUrl:mr("og:audio"),ogImageSecureUrl:mr("og:image:secure_url"),ogImageUrl:mr("og:image"),ogSiteName:mr("og:site_name"),ogVideoSecureUrl:mr("og:video:secure_url"),ogVideoUrl:mr("og:video"),profileFirstName:mr("profile:first_name"),profileLastName:mr("profile:last_name"),profileUsername:mr("profile:username"),refresh:{metaKey:"http-equiv",unpack:{entrySeparator:";",resolve({key:r,value:d}){if(r==="seconds")return`${d}`}}},robots:{unpack:{entrySeparator:", ",resolve({key:r,value:d}){return typeof d=="boolean"?`${pn(r)}`:`${pn(r)}:${d}`}}},xUaCompatible:{metaKey:"http-equiv"}},Pf=["og","book","article","profile"];function Af(r){var w;const d=pn(r).split(":")[0];return Pf.includes(d)?"property":((w=hl[r])==null?void 0:w.metaKey)||"name"}function Gg(r){var d;return((d=hl[r])==null?void 0:d.keyValue)||pn(r)}function pn(r){const d=r.replace(/([A-Z])/g,"-$1").toLowerCase(),w=d.split("-")[0];return Pf.includes(w)||w==="twitter"?r.replace(/([A-Z])/g,":$1").toLowerCase():d}function Ca(r){if(Array.isArray(r))return r.map(w=>Ca(w));if(typeof r!="object"||Array.isArray(r))return r;const d={};for(const[w,t]of Object.entries(r))d[pn(w)]=Ca(t);return d}function Vg(r,d){const w=hl[d];return d==="refresh"?`${r.seconds};url=${r.url}`:Of(Ca(r),{keyValueSeparator:"=",entrySeparator:", ",resolve({value:t,key:x}){if(t===null)return"";if(typeof t=="boolean")return`${x}`},...w==null?void 0:w.unpack})}const Rf=["og:image","og:video","og:audio","twitter:image"];function Lf(r){const d={};return Object.entries(r).forEach(([w,t])=>{String(t)!=="false"&&w&&(d[w]=t)}),d}function ac(r,d){const w=Lf(d),t=pn(r),x=Af(t);if(Rf.includes(t)){const v={};return Object.entries(w).forEach(([s,c])=>{v[`${r}${s==="url"?"":`${s.charAt(0).toUpperCase()}${s.slice(1)}`}`]=c}),pl(v).sort((s,c)=>{var o,u;return(((o=s[x])==null?void 0:o.length)||0)-(((u=c[x])==null?void 0:u.length)||0)})}return[{[x]:t,...w}]}function pl(r){const d=[],w={};Object.entries(r).forEach(([x,v])=>{if(!Array.isArray(v)){if(typeof v=="object"&&v){if(Rf.includes(pn(x))){d.push(...ac(x,v));return}w[x]=Lf(v)}else w[x]=v;return}v.forEach(s=>{d.push(...typeof s=="string"?pl({[x]:s}):ac(x,s))})});const t=Cf(w,{key({key:x}){return Af(x)},value({key:x}){return x==="charset"?"charset":"content"},resolveKeyData({key:x}){return Gg(x)},resolveValueData({value:x,key:v}){return x===null?"_null":typeof x=="object"?Vg(x,v):typeof x=="number"?x.toString():x}});return[...d,...t].map(x=>(x.content==="_null"&&(x.content=null),x))}async function Hg(r,d,w){const t={tag:r,props:await If(typeof d=="object"&&typeof d!="function"&&!(d instanceof Promise)?{...d}:{[["script","noscript","style"].includes(r)?"innerHTML":"textContent"]:d},["templateParams","titleTemplate"].includes(r))};return kf.forEach(x=>{const v=typeof t.props[x]<"u"?t.props[x]:w[x];typeof v<"u"&&((!["innerHTML","textContent","children"].includes(x)||Fg.includes(t.tag))&&(t[x==="children"?"innerHTML":x]=v),delete t.props[x])}),t.props.body&&(t.tagPosition="bodyClose",delete t.props.body),t.tag==="script"&&typeof t.innerHTML=="object"&&(t.innerHTML=JSON.stringify(t.innerHTML),t.props.type=t.props.type||"application/json"),Array.isArray(t.props.content)?t.props.content.map(x=>({...t,props:{...t.props,content:x}})):t}function zg(r,d){var t;const w=r==="class"?" ":";";return typeof d=="object"&&!Array.isArray(d)&&(d=Object.entries(d).filter(([,x])=>x).map(([x,v])=>r==="style"?`${x}:${v}`:x)),(t=String(Array.isArray(d)?d.join(w):d))==null?void 0:t.split(w).filter(x=>x.trim()).filter(Boolean).join(w)}async function If(r,d){for(const w of Object.keys(r)){if(["class","style"].includes(w)){r[w]=zg(w,r[w]);continue}if(r[w]instanceof Promise&&(r[w]=await r[w]),!d&&!kf.includes(w)){const t=String(r[w]),x=w.startsWith("data-");t==="true"||t===""?r[w]=x?"true":!0:r[w]||(x&&t==="false"?r[w]="false":delete r[w])}}return r}const Wg=10;async function qg(r){const d=[];return Object.entries(r.resolvedInput).filter(([w,t])=>typeof t<"u"&&Ng.includes(w)).forEach(([w,t])=>{const x=Dg(t);d.push(...x.map(v=>Hg(w,v,r)).flat())}),(await Promise.all(d)).flat().filter(Boolean).map((w,t)=>(w._e=r._i,r.mode&&(w._m=r.mode),w._p=(r._i<o&&o[u]||void 0,d):c=d[s],typeof c<"u"?(c||"").replace(/"/g,'\\"'):!1}let x=r;try{x=decodeURI(r)}catch{}return(x.match(/%(\w+\.+\w+)|%(\w+)/g)||[]).sort().reverse().forEach(s=>{const c=t(s.slice(1));typeof c=="string"&&(r=r.replace(new RegExp(`\\${s}(\\W|$)`,"g"),(o,u)=>`${c}${u}`).trim())}),r.includes(En)&&(r.endsWith(En)&&(r=r.slice(0,-En.length).trim()),r.startsWith(En)&&(r=r.slice(En.length).trim()),r=r.replace(new RegExp(`\\${En}\\s*\\${En}`,"g"),En),r=Bs(r,{separator:w},w)),r}async function Df(r,d={}){var g;const w=d.document||r.resolvedOptions.document;if(!w||!r.dirty)return;const t={shouldRender:!0,tags:[]};if(await r.hooks.callHook("dom:beforeRender",t),!t.shouldRender)return;const x=(await r.resolveTags()).map(p=>({tag:p,id:Us.includes(p.tag)?sc(p):p.tag,shouldRender:!0}));let v=r._dom;if(!v){v={elMap:{htmlAttrs:w.documentElement,bodyAttrs:w.body}};for(const p of["body","head"]){const n=(g=w[p])==null?void 0:g.children,i=[];for(const a of[...n].filter(h=>Us.includes(h.tagName.toLowerCase()))){const h={tag:a.tagName.toLowerCase(),props:await If(a.getAttributeNames().reduce((f,y)=>({...f,[y]:a.getAttribute(y)}),{})),innerHTML:a.innerHTML};let m=1,l=Mf(h);for(;l&&i.find(f=>f._d===l);)l=`${l}:${m++}`;h._d=l||void 0,i.push(h),v.elMap[a.getAttribute("data-hid")||sc(h)]=a}}}v.pendingSideEffects={...v.sideEffects||{}},v.sideEffects={};function s(p,n,i){const a=`${p}:${n}`;v.sideEffects[a]=i,delete v.pendingSideEffects[a]}function c({id:p,$el:n,tag:i}){const a=i.tag.endsWith("Attrs");v.elMap[p]=n,a||(["textContent","innerHTML"].forEach(h=>{i[h]&&i[h]!==n[h]&&(n[h]=i[h])}),s(p,"el",()=>{var h;(h=v.elMap[p])==null||h.remove(),delete v.elMap[p]}));for(const[h,m]of Object.entries(i._eventHandlers||{}))n.getAttribute(`data-${h}`)!==""&&((i.tag==="bodyAttrs"?w.defaultView:n).addEventListener(h.replace("on",""),m.bind(n)),n.setAttribute(`data-${h}`,""));Object.entries(i.props).forEach(([h,m])=>{const l=`attr:${h}`;if(h==="class")for(const f of(m||"").split(" ").filter(Boolean))a&&s(p,`${l}:${f}`,()=>n.classList.remove(f)),!n.classList.contains(f)&&n.classList.add(f);else if(h==="style")for(const f of(m||"").split(";").filter(Boolean)){const[y,...b]=f.split(":").map(j=>j.trim());s(p,`${l}:${y}`,()=>{n.style.removeProperty(y)}),n.style.setProperty(y,b.join(":"))}else n.getAttribute(h)!==m&&n.setAttribute(h,m===!0?"":String(m)),a&&s(p,l,()=>n.removeAttribute(h))})}const o=[],u={bodyClose:void 0,bodyOpen:void 0,head:void 0};for(const p of x){const{tag:n,shouldRender:i,id:a}=p;if(i){if(n.tag==="title"){w.title=n.textContent;continue}p.$el=p.$el||v.elMap[a],p.$el?c(p):Us.includes(n.tag)&&o.push(p)}}for(const p of o){const n=p.tag.tagPosition||"head";p.$el=w.createElement(p.tag.tag),c(p),u[n]=u[n]||w.createDocumentFragment(),u[n].appendChild(p.$el)}for(const p of x)await r.hooks.callHook("dom:renderTag",p,w,s);u.head&&w.head.appendChild(u.head),u.bodyOpen&&w.body.insertBefore(u.bodyOpen,w.body.firstChild),u.bodyClose&&w.body.appendChild(u.bodyClose),Object.values(v.pendingSideEffects).forEach(p=>p()),r._dom=v,r.dirty=!1,await r.hooks.callHook("dom:rendered",{renders:x})}async function Yg(r,d={}){const w=d.delayFn||(t=>setTimeout(t,10));return r._domUpdatePromise=r._domUpdatePromise||new Promise(t=>w(async()=>{await Df(r,d),delete r._domUpdatePromise,t()}))}function $g(r){return d=>{var t,x;const w=((x=(t=d.resolvedOptions.document)==null?void 0:t.head.querySelector('script[id="unhead:payload"]'))==null?void 0:x.innerHTML)||!1;return w&&d.push(JSON.parse(w)),{mode:"client",hooks:{"entries:updated":function(v){Yg(v,r)}}}}}const Kg=["templateParams","htmlAttrs","bodyAttrs"],Zg={hooks:{"tag:normalise":function({tag:r}){["hid","vmid","key"].forEach(t=>{r.props[t]&&(r.key=r.props[t],delete r.props[t])});const w=Mf(r)||(r.key?`${r.tag}:${r.key}`:!1);w&&(r._d=w)},"tags:resolve":function(r){const d={};r.tags.forEach(t=>{const x=(t.key?`${t.tag}:${t.key}`:t._d)||t._p,v=d[x];if(v){let c=t==null?void 0:t.tagDuplicateStrategy;if(!c&&Kg.includes(t.tag)&&(c="merge"),c==="merge"){const o=v.props;["class","style"].forEach(u=>{o[u]&&(t.props[u]?(u==="style"&&!o[u].endsWith(";")&&(o[u]+=";"),t.props[u]=`${o[u]} ${t.props[u]}`):t.props[u]=o[u])}),d[x].props={...o,...t.props};return}else if(t._e===v._e){v._duped=v._duped||[],t._d=`${v._d}:${v._duped.length+1}`,v._duped.push(t);return}else if(ti(t)>ti(v))return}const s=Object.keys(t.props).length+(t.innerHTML?1:0)+(t.textContent?1:0);if(Us.includes(t.tag)&&s===0){delete d[x];return}d[x]=t});const w=[];Object.values(d).forEach(t=>{const x=t._duped;delete t._duped,w.push(t),x&&w.push(...x)}),r.tags=w,r.tags=r.tags.filter(t=>!(t.tag==="meta"&&(t.props.name||t.props.property)&&!t.props.content))}}},Qg={mode:"server",hooks:{"tags:resolve":function(r){const d={};r.tags.filter(w=>["titleTemplate","templateParams","title"].includes(w.tag)&&w._m==="server").forEach(w=>{d[w.tag]=w.tag.startsWith("title")?w.textContent:w.props}),Object.keys(d).length&&r.tags.push({tag:"script",innerHTML:JSON.stringify(d),props:{id:"unhead:payload",type:"application/json"}})}}},Jg=["script","link","bodyAttrs"],ev=r=>({hooks:{"tags:resolve":function(d){for(const w of d.tags.filter(t=>Jg.includes(t.tag)))Object.entries(w.props).forEach(([t,x])=>{t.startsWith("on")&&typeof x=="function"&&(r.ssr&&cc.includes(t)?w.props[t]=`this.dataset.${t}fired = true`:delete w.props[t],w._eventHandlers=w._eventHandlers||{},w._eventHandlers[t]=x)}),r.ssr&&w._eventHandlers&&(w.props.src||w.props.href)&&(w.key=w.key||fl(w.props.src||w.props.href))},"dom:renderTag":function({$el:d,tag:w}){var t,x;for(const v of Object.keys((d==null?void 0:d.dataset)||{}).filter(s=>cc.some(c=>`${c}fired`===s))){const s=v.replace("fired","");(x=(t=w._eventHandlers)==null?void 0:t[s])==null||x.call(d,new Event(s.replace("on","")))}}}}),tv=["link","style","script","noscript"],rv={hooks:{"tag:normalise":({tag:r})=>{r.key&&tv.includes(r.tag)&&(r.props["data-hid"]=r._h=fl(r.key))}}},nv={hooks:{"tags:resolve":r=>{const d=w=>{var t;return(t=r.tags.find(x=>x._d===w))==null?void 0:t._p};for(const{prefix:w,offset:t}of Xg)for(const x of r.tags.filter(v=>typeof v.tagPriority=="string"&&v.tagPriority.startsWith(w))){const v=d(x.tagPriority.replace(w,""));typeof v<"u"&&(x._p=v+t)}r.tags.sort((w,t)=>w._p-t._p).sort((w,t)=>ti(w)-ti(t))}}},ov={meta:"content",link:"href",htmlAttrs:"lang"},sv=r=>({hooks:{"tags:resolve":d=>{var c;const{tags:w}=d,t=(c=w.find(o=>o.tag==="title"))==null?void 0:c.textContent,x=w.findIndex(o=>o.tag==="templateParams"),v=x!==-1?w[x].props:{},s=v.separator||"|";delete v.separator,v.pageTitle=Bs(v.pageTitle||t||"",v,s);for(const o of w.filter(u=>u.processTemplateParams!==!1)){const u=ov[o.tag];u&&typeof o.props[u]=="string"?o.props[u]=Bs(o.props[u],v,s):(o.processTemplateParams===!0||["titleTemplate","title"].includes(o.tag))&&["innerHTML","textContent"].forEach(g=>{typeof o[g]=="string"&&(o[g]=Bs(o[g],v,s))})}r._templateParams=v,r._separator=s,d.tags=w.filter(o=>o.tag!=="templateParams")}}}),iv={hooks:{"tags:resolve":r=>{const{tags:d}=r;let w=d.findIndex(x=>x.tag==="titleTemplate");const t=d.findIndex(x=>x.tag==="title");if(t!==-1&&w!==-1){const x=ic(d[w].textContent,d[t].textContent);x!==null?d[t].textContent=x||d[t].textContent:delete d[t]}else if(w!==-1){const x=ic(d[w].textContent);x!==null&&(d[w].textContent=x,d[w].tag="title",w=-1)}w!==-1&&delete d[w],r.tags=d.filter(Boolean)}}},av={hooks:{"tags:afterResolve":function(r){for(const d of r.tags)typeof d.innerHTML=="string"&&(d.innerHTML&&["application/ld+json","application/json"].includes(d.props.type)?d.innerHTML=d.innerHTML.replace(/{c.dirty=!0,d.callHook("entries:updated",c)};let x=0,v=[];const s=[],c={plugins:s,dirty:!1,resolvedOptions:r,hooks:d,headEntries(){return v},use(o){const u=typeof o=="function"?o(c):o;(!u.key||!s.some(g=>g.key===u.key))&&(s.push(u),dc(u.mode,w)&&d.addHooks(u.hooks||{}))},push(o,u){u==null||delete u.head;const g={_i:x++,input:o,...u};return dc(g.mode,w)&&(v.push(g),t()),{dispose(){v=v.filter(p=>p._i!==g._i),d.callHook("entries:updated",c),t()},patch(p){v=v.map(n=>(n._i===g._i&&(n.input=g.input=p),n)),t()}}},async resolveTags(){const o={tags:[],entries:[...v]};await d.callHook("entries:resolve",o);for(const u of o.entries){const g=u.resolvedInput||u.input;if(u.resolvedInput=await(u.transform?u.transform(g):g),u.resolvedInput)for(const p of await qg(u)){const n={tag:p,entry:u,resolvedOptions:c.resolvedOptions};await d.callHook("tag:normalise",n),o.tags.push(n.tag)}}return await d.callHook("tags:beforeResolve",o),await d.callHook("tags:resolve",o),await d.callHook("tags:afterResolve",o),o.tags},ssr:w};return[Zg,Qg,ev,rv,nv,sv,iv,av,...(r==null?void 0:r.plugins)||[]].forEach(o=>c.use(o)),c.hooks.callHook("init",c),c}function cv(){return Ff}const dv=of.startsWith("3");function fv(r){return typeof r=="function"?r():Bt(r)}function ri(r,d=""){if(r instanceof Promise)return r;const w=fv(r);return!r||!w?w:Array.isArray(w)?w.map(t=>ri(t,d)):typeof w=="object"?Object.fromEntries(Object.entries(w).map(([t,x])=>t==="titleTemplate"||t.startsWith("on")?[t,Bt(x)]:[t,ri(x,t)])):w}const hv={hooks:{"entries:resolve":function(r){for(const d of r.entries)d.resolvedInput=ri(d.input)}}},Nf="usehead";function pv(r){return{install(w){dv&&(w.config.globalProperties.$unhead=r,w.config.globalProperties.$head=r,w.provide(Nf,r))}}.install}function mv(r={}){r.domDelayFn=r.domDelayFn||(w=>Fr(()=>setTimeout(()=>w(),0)));const d=lv(r);return d.use(hv),d.install=pv(d),d}const Oa=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},Pa="__unhead_injection_handler__";function yv(r){Oa[Pa]=r}function gv(){if(Pa in Oa)return Oa[Pa]();const r=Ht(Nf);return r||cv()}function vv(r,d={}){const w=d.head||gv();if(w)return w.ssr?w.push(r,d):bv(w,r,d)}function bv(r,d,w={}){const t=mt(!1),x=mt({});ln(()=>{x.value=t.value?{}:ri(d)});const v=r.push(x.value,w);return In(x,c=>{v.patch(c)}),Eo()&&(ls(()=>{v.dispose()}),Wd(()=>{t.value=!0}),zd(()=>{t.value=!1})),v}function _v(r,d){const{title:w,titleTemplate:t,...x}=r;return vv({title:w,titleTemplate:t,_flatMeta:x},{...d,transform(v){const s=pl({...v._flatMeta});return delete v._flatMeta,{...v,meta:s}}})}const wv={nuxt:{buildId:"e858341f-e36c-4a7e-a593-6a1877733ce0"}},xv=vg(wv);function Uf(){const r=It();return r._appConfig||(r._appConfig=Un(xv)),r._appConfig}const jv=!1,Aa=!1,Sv=!1,Ev={componentName:"NuxtLink"},C_={deep:!0},O_={},Tv="#__nuxt";let Gs,Bf;function kv(){var d;const r=(d=Uf().nuxt)==null?void 0:d.buildId;return Gs=$fetch(dl(`builds/meta/${r}.json`)),Gs.then(w=>{Bf=gg(w.matcher)}),Gs}function vi(){return Gs||kv()}async function ml(r){return await vi(),jf({},...Bf.matchAll(r).reverse())}function fc(r,d={}){const w=Cv(r,d),t=It(),x=t._payloadCache=t._payloadCache||{};return w in x||(x[w]=Ov(r).then(v=>v?Gf(w).then(s=>s||(delete x[w],null)):(x[w]=null,null))),x[w]}const Mv="_payload.json";function Cv(r,d={}){var x;const w=new URL(r,"http://localhost");if(w.host!=="localhost"||gn(w.pathname,{acceptRelative:!0}))throw new Error("Payload URL must not include hostname: "+r);const t=d.hash||(d.fresh?Date.now():(x=Uf().nuxt)==null?void 0:x.buildId);return hi(pi().app.baseURL,w.pathname,Mv+(t?`?${t}`:""))}async function Gf(r){const d=fetch(r).then(w=>w.text().then(Vf));try{return await d}catch(w){console.warn("[nuxt] Cannot load payload ",r,w)}return null}async function Ov(r=mi().path){if(r=fi(r),(await vi()).prerendered.includes(r))return!0;const w=await ml(r);return!!w.prerender&&!w.redirect}let As=null;async function Pv(){if(As)return As;const r=document.getElementById("__NUXT_DATA__");if(!r)return{};const d=await Vf(r.textContent||""),w=r.dataset.src?await Gf(r.dataset.src):void 0;return As={...d,...w,...window.__NUXT__},As}async function Vf(r){return await Lg(r,It()._payloadRevivers)}function Av(r,d){It()._payloadRevivers[r]=d}const hc={NuxtError:r=>gi(r),EmptyShallowRef:r=>Ko(r==="_"?void 0:r==="0n"?BigInt(0):Ks(r)),EmptyRef:r=>mt(r==="_"?void 0:r==="0n"?BigInt(0):Ks(r)),ShallowRef:r=>Ko(r),ShallowReactive:r=>as(r),Ref:r=>mt(r),Reactive:r=>Un(r)},Rv=vn({name:"nuxt:revive-payload:client",order:-30,async setup(r){let d,w;for(const t in hc)Av(t,hc[t]);Object.assign(r.payload,([d,w]=rs(()=>r.runWithContext(Pv)),d=await d,w(),d)),window.__NUXT__=r.payload}}),Lv=[],Iv=vn({name:"nuxt:head",enforce:"pre",setup(r){const d=mv({plugins:Lv});yv(()=>It().vueApp._context.provides.usehead),r.vueApp.use(d);{let w=!0;const t=async()=>{w=!1,await Df(d)};d.hooks.hook("dom:beforeRender",x=>{x.shouldRender=!w}),r.hooks.hook("page:start",()=>{w=!0}),r.hooks.hook("page:finish",()=>{r.isHydrating||t()}),r.hooks.hook("app:error",t),r.hooks.hook("app:suspense:resolve",t)}}});/*! - * vue-router v4.3.3 +**/const Lm="http://www.w3.org/2000/svg",Im="http://www.w3.org/1998/Math/MathML",hn=typeof document<"u"?document:null,Lu=hn&&hn.createElement("template"),Dm={insert:(r,d,w)=>{d.insertBefore(r,w||null)},remove:r=>{const d=r.parentNode;d&&d.removeChild(r)},createElement:(r,d,w,t)=>{const x=d==="svg"?hn.createElementNS(Lm,r):d==="mathml"?hn.createElementNS(Im,r):w?hn.createElement(r,{is:w}):hn.createElement(r);return r==="select"&&t&&t.multiple!=null&&x.setAttribute("multiple",t.multiple),x},createText:r=>hn.createTextNode(r),createComment:r=>hn.createComment(r),setText:(r,d)=>{r.nodeValue=d},setElementText:(r,d)=>{r.textContent=d},parentNode:r=>r.parentNode,nextSibling:r=>r.nextSibling,querySelector:r=>hn.querySelector(r),setScopeId(r,d){r.setAttribute(d,"")},insertStaticContent(r,d,w,t,x,v){const s=w?w.previousSibling:d.lastChild;if(x&&(x===v||x.nextSibling))for(;d.insertBefore(x.cloneNode(!0),w),!(x===v||!(x=x.nextSibling)););else{Lu.innerHTML=t==="svg"?`${r}`:t==="mathml"?`${r}`:r;const c=Lu.content;if(t==="svg"||t==="mathml"){const o=c.firstChild;for(;o.firstChild;)c.appendChild(o.firstChild);c.removeChild(o)}d.insertBefore(c,w)}return[s?s.nextSibling:d.firstChild,w?w.previousSibling:d.lastChild]}},jn="transition",Do="animation",ts=Symbol("_vtc"),fs=(r,{slots:d})=>rr(jm,Fm(r),d);fs.displayName="Transition";const af={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};fs.props=Xt({},Yd,af);const Vn=(r,d=[])=>{st(r)?r.forEach(w=>w(...d)):r&&r(...d)},Iu=r=>r?st(r)?r.some(d=>d.length>1):r.length>1:!1;function Fm(r){const d={};for(const I in r)I in af||(d[I]=r[I]);if(r.css===!1)return d;const{name:w="v",type:t,duration:x,enterFromClass:v=`${w}-enter-from`,enterActiveClass:s=`${w}-enter-active`,enterToClass:c=`${w}-enter-to`,appearFromClass:o=v,appearActiveClass:u=s,appearToClass:g=c,leaveFromClass:p=`${w}-leave-from`,leaveActiveClass:n=`${w}-leave-active`,leaveToClass:i=`${w}-leave-to`}=r,a=Nm(x),h=a&&a[0],y=a&&a[1],{onBeforeEnter:l,onEnter:f,onEnterCancelled:m,onLeave:b,onLeaveCancelled:j,onBeforeAppear:k=l,onAppear:E=f,onAppearCancelled:M=m}=d,P=(I,A,N)=>{Hn(I,A?g:c),Hn(I,A?u:s),N&&N()},L=(I,A)=>{I._isLeaving=!1,Hn(I,p),Hn(I,i),Hn(I,n),A&&A()},C=I=>(A,N)=>{const F=I?E:f,B=()=>P(A,I,N);Vn(F,[A,B]),Du(()=>{Hn(A,I?o:v),Sn(A,I?g:c),Iu(F)||Fu(A,t,h,B)})};return Xt(d,{onBeforeEnter(I){Vn(l,[I]),Sn(I,v),Sn(I,s)},onBeforeAppear(I){Vn(k,[I]),Sn(I,o),Sn(I,u)},onEnter:C(!1),onAppear:C(!0),onLeave(I,A){I._isLeaving=!0;const N=()=>L(I,A);Sn(I,p),Sn(I,n),Gm(),Du(()=>{I._isLeaving&&(Hn(I,p),Sn(I,i),Iu(b)||Fu(I,t,y,N))}),Vn(b,[I,N])},onEnterCancelled(I){P(I,!1),Vn(m,[I])},onAppearCancelled(I){P(I,!0),Vn(M,[I])},onLeaveCancelled(I){L(I),Vn(j,[I])}})}function Nm(r){if(r==null)return null;if(Ct(r))return[Ui(r.enter),Ui(r.leave)];{const d=Ui(r);return[d,d]}}function Ui(r){return Xc(r)}function Sn(r,d){d.split(/\s+/).forEach(w=>w&&r.classList.add(w)),(r[ts]||(r[ts]=new Set)).add(d)}function Hn(r,d){d.split(/\s+/).forEach(t=>t&&r.classList.remove(t));const w=r[ts];w&&(w.delete(d),w.size||(r[ts]=void 0))}function Du(r){requestAnimationFrame(()=>{requestAnimationFrame(r)})}let Um=0;function Fu(r,d,w,t){const x=r._endId=++Um,v=()=>{x===r._endId&&t()};if(w)return setTimeout(v,w);const{type:s,timeout:c,propCount:o}=Bm(r,d);if(!s)return t();const u=s+"end";let g=0;const p=()=>{r.removeEventListener(u,n),v()},n=i=>{i.target===r&&++g>=o&&p()};setTimeout(()=>{g(w[a]||"").split(", "),x=t(`${jn}Delay`),v=t(`${jn}Duration`),s=Nu(x,v),c=t(`${Do}Delay`),o=t(`${Do}Duration`),u=Nu(c,o);let g=null,p=0,n=0;d===jn?s>0&&(g=jn,p=s,n=v.length):d===Do?u>0&&(g=Do,p=u,n=o.length):(p=Math.max(s,u),g=p>0?s>u?jn:Do:null,n=g?g===jn?v.length:o.length:0);const i=g===jn&&/\b(transform|all)(,|$)/.test(t(`${jn}Property`).toString());return{type:g,timeout:p,propCount:n,hasTransform:i}}function Nu(r,d){for(;r.lengthUu(w)+Uu(r[t])))}function Uu(r){return r==="auto"?0:Number(r.slice(0,-1).replace(",","."))*1e3}function Gm(){return document.body.offsetHeight}function Vm(r,d,w){const t=r[ts];t&&(d=(d?[d,...t]:[...t]).join(" ")),d==null?r.removeAttribute("class"):w?r.setAttribute("class",d):r.className=d}const Bu=Symbol("_vod"),Hm=Symbol("_vsh"),zm=Symbol(""),Wm=/(^|;)\s*display\s*:/;function qm(r,d,w){const t=r.style,x=Gt(w);let v=!1;if(w&&!x){if(d)if(Gt(d))for(const s of d.split(";")){const c=s.slice(0,s.indexOf(":")).trim();w[c]==null&&Ns(t,c,"")}else for(const s in d)w[s]==null&&Ns(t,s,"");for(const s in w)s==="display"&&(v=!0),Ns(t,s,w[s])}else if(x){if(d!==w){const s=t[zm];s&&(w+=";"+s),t.cssText=w,v=Wm.test(w)}}else d&&r.removeAttribute("style");Bu in r&&(r[Bu]=v?t.display:"",r[Hm]&&(t.display="none"))}const Gu=/\s*!important$/;function Ns(r,d,w){if(st(w))w.forEach(t=>Ns(r,d,t));else if(w==null&&(w=""),d.startsWith("--"))r.setProperty(d,w);else{const t=Xm(r,d);Gu.test(w)?r.setProperty(jo(t),w.replace(Gu,""),"important"):r[t]=w}}const Vu=["Webkit","Moz","ms"],Bi={};function Xm(r,d){const w=Bi[d];if(w)return w;let t=an(d);if(t!=="filter"&&t in r)return Bi[d]=t;t=si(t);for(let x=0;xGi||(Qm.then(()=>Gi=0),Gi=Date.now());function ey(r,d){const w=t=>{if(!t._vts)t._vts=Date.now();else if(t._vts<=w.attached)return;zr(ty(t,w.value),d,5,[t])};return w.value=r,w.attached=Jm(),w}function ty(r,d){if(st(d)){const w=r.stopImmediatePropagation;return r.stopImmediatePropagation=()=>{w.call(r),r._stopped=!0},d.map(t=>x=>!x._stopped&&t&&t(x))}else return d}const Xu=r=>r.charCodeAt(0)===111&&r.charCodeAt(1)===110&&r.charCodeAt(2)>96&&r.charCodeAt(2)<123,ry=(r,d,w,t,x,v,s,c,o)=>{const u=x==="svg";d==="class"?Vm(r,t,u):d==="style"?qm(r,w,t):ss(d)?Va(d)||Km(r,d,w,t,s):(d[0]==="."?(d=d.slice(1),!0):d[0]==="^"?(d=d.slice(1),!1):ny(r,d,t,u))?(Ym(r,d,t,v,s,c,o),!r.tagName.includes("-")&&(d==="value"||d==="checked"||d==="selected")&&zu(r,d,t,u,s,d!=="value")):(d==="true-value"?r._trueValue=t:d==="false-value"&&(r._falseValue=t),zu(r,d,t,u))};function ny(r,d,w,t){if(t)return!!(d==="innerHTML"||d==="textContent"||d in r&&Xu(d)&&at(w));if(d==="spellcheck"||d==="draggable"||d==="translate"||d==="form"||d==="list"&&r.tagName==="INPUT"||d==="type"&&r.tagName==="TEXTAREA")return!1;if(d==="width"||d==="height"){const x=r.tagName;if(x==="IMG"||x==="VIDEO"||x==="CANVAS"||x==="SOURCE")return!1}return Xu(d)&&Gt(w)?!1:d in r}const Yu=r=>{const d=r.props["onUpdate:modelValue"]||!1;return st(d)?w=>ho(d,w):d};function oy(r){r.target.composing=!0}function $u(r){const d=r.target;d.composing&&(d.composing=!1,d.dispatchEvent(new Event("input")))}const Vi=Symbol("_assign"),C_={created(r,{modifiers:{lazy:d,trim:w,number:t}},x){r[Vi]=Yu(x);const v=t||x.props&&x.props.type==="number";so(r,d?"change":"input",s=>{if(s.target.composing)return;let c=r.value;w&&(c=c.trim()),v&&(c=oa(c)),r[Vi](c)}),w&&so(r,"change",()=>{r.value=r.value.trim()}),d||(so(r,"compositionstart",oy),so(r,"compositionend",$u),so(r,"change",$u))},mounted(r,{value:d}){r.value=d??""},beforeUpdate(r,{value:d,oldValue:w,modifiers:{lazy:t,trim:x,number:v}},s){if(r[Vi]=Yu(s),r.composing)return;const c=(v||r.type==="number")&&!/^0\d/.test(r.value)?oa(r.value):r.value,o=d??"";c!==o&&(document.activeElement===r&&r.type!=="range"&&(t&&d===w||x&&r.value.trim()===o)||(r.value=o))}},lf=Xt({patchProp:ry},Dm);let Wo,Ku=!1;function sy(){return Wo||(Wo=fm(lf))}function iy(){return Wo=Ku?Wo:hm(lf),Ku=!0,Wo}const ay=(...r)=>{const d=sy().createApp(...r),{mount:w}=d;return d.mount=t=>{const x=cf(t);if(!x)return;const v=d._component;!at(v)&&!v.render&&!v.template&&(v.template=x.innerHTML),x.innerHTML="";const s=w(x,!1,uf(x));return x instanceof Element&&(x.removeAttribute("v-cloak"),x.setAttribute("data-v-app","")),s},d},ly=(...r)=>{const d=iy().createApp(...r),{mount:w}=d;return d.mount=t=>{const x=cf(t);if(x)return w(x,!0,uf(x))},d};function uf(r){if(r instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&r instanceof MathMLElement)return"mathml"}function cf(r){return Gt(r)?document.querySelector(r):r}const uy=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,cy=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,dy=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function fy(r,d){if(r==="__proto__"||r==="constructor"&&d&&typeof d=="object"&&"prototype"in d){hy(r);return}return d}function hy(r){console.warn(`[destr] Dropping "${r}" key to prevent prototype pollution.`)}function Ks(r,d={}){if(typeof r!="string")return r;const w=r.trim();if(r[0]==='"'&&r.endsWith('"')&&!r.includes("\\"))return w.slice(1,-1);if(w.length<=9){const t=w.toLowerCase();if(t==="true")return!0;if(t==="false")return!1;if(t==="undefined")return;if(t==="null")return null;if(t==="nan")return Number.NaN;if(t==="infinity")return Number.POSITIVE_INFINITY;if(t==="-infinity")return Number.NEGATIVE_INFINITY}if(!dy.test(r)){if(d.strict)throw new SyntaxError("[destr] Invalid JSON");return r}try{if(uy.test(r)||cy.test(r)){if(d.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(r,fy)}return JSON.parse(r)}catch(t){if(d.strict)throw t;return r}}const py=/#/g,my=/&/g,yy=/\//g,gy=/=/g,ll=/\+/g,vy=/%5e/gi,by=/%60/gi,_y=/%7c/gi,wy=/%20/gi;function xy(r){return encodeURI(""+r).replace(_y,"|")}function wa(r){return xy(typeof r=="string"?r:JSON.stringify(r)).replace(ll,"%2B").replace(wy,"+").replace(py,"%23").replace(my,"%26").replace(by,"`").replace(vy,"^").replace(yy,"%2F")}function Hi(r){return wa(r).replace(gy,"%3D")}function Zs(r=""){try{return decodeURIComponent(""+r)}catch{return""+r}}function jy(r){return Zs(r.replace(ll," "))}function Sy(r){return Zs(r.replace(ll," "))}function df(r=""){const d={};r[0]==="?"&&(r=r.slice(1));for(const w of r.split("&")){const t=w.match(/([^=]+)=?(.*)/)||[];if(t.length<2)continue;const x=jy(t[1]);if(x==="__proto__"||x==="constructor")continue;const v=Sy(t[2]||"");d[x]===void 0?d[x]=v:Array.isArray(d[x])?d[x].push(v):d[x]=[d[x],v]}return d}function Ey(r,d){return(typeof d=="number"||typeof d=="boolean")&&(d=String(d)),d?Array.isArray(d)?d.map(w=>`${Hi(r)}=${wa(w)}`).join("&"):`${Hi(r)}=${wa(d)}`:Hi(r)}function Ty(r){return Object.keys(r).filter(d=>r[d]!==void 0).map(d=>Ey(d,r[d])).filter(Boolean).join("&")}const ky=/^[\s\w\0+.-]{2,}:([/\\]{1,2})/,My=/^[\s\w\0+.-]{2,}:([/\\]{2})?/,Cy=/^([/\\]\s*){2,}[^/\\]/,Oy=/^[\s\0]*(blob|data|javascript|vbscript):$/i,Py=/\/$|\/\?|\/#/,Ay=/^\.?\//;function gn(r,d={}){return typeof d=="boolean"&&(d={acceptRelative:d}),d.strict?ky.test(r):My.test(r)||(d.acceptRelative?Cy.test(r):!1)}function Ry(r){return!!r&&Oy.test(r)}function xa(r="",d){return d?Py.test(r):r.endsWith("/")}function fi(r="",d){if(!d)return(xa(r)?r.slice(0,-1):r)||"/";if(!xa(r,!0))return r||"/";let w=r,t="";const x=r.indexOf("#");x>=0&&(w=r.slice(0,x),t=r.slice(x));const[v,...s]=w.split("?");return((v.endsWith("/")?v.slice(0,-1):v)||"/")+(s.length>0?`?${s.join("?")}`:"")+t}function Qs(r="",d){if(!d)return r.endsWith("/")?r:r+"/";if(xa(r,!0))return r||"/";let w=r,t="";const x=r.indexOf("#");if(x>=0&&(w=r.slice(0,x),t=r.slice(x),!w))return t;const[v,...s]=w.split("?");return v+"/"+(s.length>0?`?${s.join("?")}`:"")+t}function Ly(r=""){return r.startsWith("/")}function Zu(r=""){return Ly(r)?r:"/"+r}function Iy(r,d){if(hf(d)||gn(r))return r;const w=fi(d);return r.startsWith(w)?r:hi(w,r)}function Qu(r,d){if(hf(d))return r;const w=fi(d);if(!r.startsWith(w))return r;const t=r.slice(w.length);return t[0]==="/"?t:"/"+t}function ff(r,d){const w=hs(r),t={...df(w.search),...d};return w.search=Ty(t),Ny(w)}function hf(r){return!r||r==="/"}function Dy(r){return r&&r!=="/"}function hi(r,...d){let w=r||"";for(const t of d.filter(x=>Dy(x)))if(w){const x=t.replace(Ay,"");w=Qs(w)+x}else w=t;return w}function pf(...r){var s,c,o,u;const d=/\/(?!\/)/,w=r.filter(Boolean),t=[];let x=0;for(const g of w)if(!(!g||g==="/")){for(const[p,n]of g.split(d).entries())if(!(!n||n===".")){if(n===".."){if(t.length===1&&gn(t[0]))continue;t.pop(),x--;continue}if(p===1&&((s=t[t.length-1])!=null&&s.endsWith(":/"))){t[t.length-1]+="/"+n;continue}t.push(n),x++}}let v=t.join("/");return x>=0?(c=w[0])!=null&&c.startsWith("/")&&!v.startsWith("/")?v="/"+v:(o=w[0])!=null&&o.startsWith("./")&&!v.startsWith("./")&&(v="./"+v):v="../".repeat(-1*x)+v,(u=w[w.length-1])!=null&&u.endsWith("/")&&!v.endsWith("/")&&(v+="/"),v}function Fy(r,d,w={}){return w.trailingSlash||(r=Qs(r),d=Qs(d)),w.leadingSlash||(r=Zu(r),d=Zu(d)),w.encoding||(r=Zs(r),d=Zs(d)),r===d}const mf=Symbol.for("ufo:protocolRelative");function hs(r="",d){const w=r.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);if(w){const[,p,n=""]=w;return{protocol:p.toLowerCase(),pathname:n,href:p+n,auth:"",host:"",search:"",hash:""}}if(!gn(r,{acceptRelative:!0}))return d?hs(d+r):Ju(r);const[,t="",x,v=""]=r.replace(/\\/g,"/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/)||[],[,s="",c=""]=v.match(/([^#/?]*)(.*)?/)||[],{pathname:o,search:u,hash:g}=Ju(c.replace(/\/(?=[A-Za-z]:)/,""));return{protocol:t.toLowerCase(),auth:x?x.slice(0,Math.max(0,x.length-1)):"",host:s,pathname:o,search:u,hash:g,[mf]:!t}}function Ju(r=""){const[d="",w="",t=""]=(r.match(/([^#?]*)(\?[^#]*)?(#.*)?/)||[]).splice(1);return{pathname:d,search:w,hash:t}}function Ny(r){const d=r.pathname||"",w=r.search?(r.search.startsWith("?")?"":"?")+r.search:"",t=r.hash||"",x=r.auth?r.auth+"@":"",v=r.host||"";return(r.protocol||r[mf]?(r.protocol||"")+"//":"")+x+v+d+w+t}class Uy extends Error{constructor(d,w){super(d,w),this.name="FetchError",w!=null&&w.cause&&!this.cause&&(this.cause=w.cause)}}function By(r){var o,u,g,p,n;const d=((o=r.error)==null?void 0:o.message)||((u=r.error)==null?void 0:u.toString())||"",w=((g=r.request)==null?void 0:g.method)||((p=r.options)==null?void 0:p.method)||"GET",t=((n=r.request)==null?void 0:n.url)||String(r.request)||"/",x=`[${w}] ${JSON.stringify(t)}`,v=r.response?`${r.response.status} ${r.response.statusText}`:"",s=`${x}: ${v}${d?` ${d}`:""}`,c=new Uy(s,r.error?{cause:r.error}:void 0);for(const i of["request","options","response"])Object.defineProperty(c,i,{get(){return r[i]}});for(const[i,a]of[["data","_data"],["status","status"],["statusCode","status"],["statusText","statusText"],["statusMessage","statusText"]])Object.defineProperty(c,i,{get(){return r.response&&r.response[a]}});return c}const Gy=new Set(Object.freeze(["PATCH","POST","PUT","DELETE"]));function ec(r="GET"){return Gy.has(r.toUpperCase())}function Vy(r){if(r===void 0)return!1;const d=typeof r;return d==="string"||d==="number"||d==="boolean"||d===null?!0:d!=="object"?!1:Array.isArray(r)?!0:r.buffer?!1:r.constructor&&r.constructor.name==="Object"||typeof r.toJSON=="function"}const Hy=new Set(["image/svg","application/xml","application/xhtml","application/html"]),zy=/^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;function Wy(r=""){if(!r)return"json";const d=r.split(";").shift()||"";return zy.test(d)?"json":Hy.has(d)||d.startsWith("text/")?"text":"blob"}function qy(r,d,w=globalThis.Headers){const t={...d,...r};if(d!=null&&d.params&&(r!=null&&r.params)&&(t.params={...d==null?void 0:d.params,...r==null?void 0:r.params}),d!=null&&d.query&&(r!=null&&r.query)&&(t.query={...d==null?void 0:d.query,...r==null?void 0:r.query}),d!=null&&d.headers&&(r!=null&&r.headers)){t.headers=new w((d==null?void 0:d.headers)||{});for(const[x,v]of new w((r==null?void 0:r.headers)||{}))t.headers.set(x,v)}return t}const Xy=new Set([408,409,425,429,500,502,503,504]),Yy=new Set([101,204,205,304]);function yf(r={}){const{fetch:d=globalThis.fetch,Headers:w=globalThis.Headers,AbortController:t=globalThis.AbortController}=r;async function x(c){const o=c.error&&c.error.name==="AbortError"&&!c.options.timeout||!1;if(c.options.retry!==!1&&!o){let g;typeof c.options.retry=="number"?g=c.options.retry:g=ec(c.options.method)?0:1;const p=c.response&&c.response.status||500;if(g>0&&(Array.isArray(c.options.retryStatusCodes)?c.options.retryStatusCodes.includes(p):Xy.has(p))){const n=c.options.retryDelay||0;return n>0&&await new Promise(i=>setTimeout(i,n)),v(c.request,{...c.options,retry:g-1})}}const u=By(c);throw Error.captureStackTrace&&Error.captureStackTrace(u,v),u}const v=async function(o,u={}){var i;const g={request:o,options:qy(u,r.defaults,w),response:void 0,error:void 0};g.options.method=(i=g.options.method)==null?void 0:i.toUpperCase(),g.options.onRequest&&await g.options.onRequest(g),typeof g.request=="string"&&(g.options.baseURL&&(g.request=Iy(g.request,g.options.baseURL)),(g.options.query||g.options.params)&&(g.request=ff(g.request,{...g.options.params,...g.options.query}))),g.options.body&&ec(g.options.method)&&(Vy(g.options.body)?(g.options.body=typeof g.options.body=="string"?g.options.body:JSON.stringify(g.options.body),g.options.headers=new w(g.options.headers||{}),g.options.headers.has("content-type")||g.options.headers.set("content-type","application/json"),g.options.headers.has("accept")||g.options.headers.set("accept","application/json")):("pipeTo"in g.options.body&&typeof g.options.body.pipeTo=="function"||typeof g.options.body.pipe=="function")&&("duplex"in g.options||(g.options.duplex="half")));let p;if(!g.options.signal&&g.options.timeout){const a=new t;p=setTimeout(()=>a.abort(),g.options.timeout),g.options.signal=a.signal}try{g.response=await d(g.request,g.options)}catch(a){return g.error=a,g.options.onRequestError&&await g.options.onRequestError(g),await x(g)}finally{p&&clearTimeout(p)}if(g.response.body&&!Yy.has(g.response.status)&&g.options.method!=="HEAD"){const a=(g.options.parseResponse?"json":g.options.responseType)||Wy(g.response.headers.get("content-type")||"");switch(a){case"json":{const h=await g.response.text(),y=g.options.parseResponse||Ks;g.response._data=y(h);break}case"stream":{g.response._data=g.response.body;break}default:g.response._data=await g.response[a]()}}return g.options.onResponse&&await g.options.onResponse(g),!g.options.ignoreResponseError&&g.response.status>=400&&g.response.status<600?(g.options.onResponseError&&await g.options.onResponseError(g),await x(g)):g.response},s=async function(o,u){return(await v(o,u))._data};return s.raw=v,s.native=(...c)=>d(...c),s.create=(c={})=>yf({...r,defaults:{...r.defaults,...c}}),s}const ul=function(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global;throw new Error("unable to locate global object")}(),$y=ul.fetch||(()=>Promise.reject(new Error("[ofetch] global.fetch is not supported!"))),Ky=ul.Headers,Zy=ul.AbortController,Qy=yf({fetch:$y,Headers:Ky,AbortController:Zy}),Jy=Qy,eg=()=>{var r;return((r=window==null?void 0:window.__NUXT__)==null?void 0:r.config)||{}},Js=eg().app,tg=()=>Js.baseURL,rg=()=>Js.buildAssetsDir,cl=(...r)=>pf(gf(),rg(),...r),gf=(...r)=>{const d=Js.cdnURL||Js.baseURL;return r.length?pf(d,...r):d};globalThis.__buildAssetsURL=cl,globalThis.__publicAssetsURL=gf;globalThis.$fetch||(globalThis.$fetch=Jy.create({baseURL:tg()}));function ja(r,d={},w){for(const t in r){const x=r[t],v=w?`${w}:${t}`:t;typeof x=="object"&&x!==null?ja(x,d,v):typeof x=="function"&&(d[v]=x)}return d}const ng={run:r=>r()},og=()=>ng,vf=typeof console.createTask<"u"?console.createTask:og;function sg(r,d){const w=d.shift(),t=vf(w);return r.reduce((x,v)=>x.then(()=>t.run(()=>v(...d))),Promise.resolve())}function ig(r,d){const w=d.shift(),t=vf(w);return Promise.all(r.map(x=>t.run(()=>x(...d))))}function zi(r,d){for(const w of[...r])w(d)}class ag{constructor(){this._hooks={},this._before=void 0,this._after=void 0,this._deprecatedMessages=void 0,this._deprecatedHooks={},this.hook=this.hook.bind(this),this.callHook=this.callHook.bind(this),this.callHookWith=this.callHookWith.bind(this)}hook(d,w,t={}){if(!d||typeof w!="function")return()=>{};const x=d;let v;for(;this._deprecatedHooks[d];)v=this._deprecatedHooks[d],d=v.to;if(v&&!t.allowDeprecated){let s=v.message;s||(s=`${x} hook has been deprecated`+(v.to?`, please use ${v.to}`:"")),this._deprecatedMessages||(this._deprecatedMessages=new Set),this._deprecatedMessages.has(s)||(console.warn(s),this._deprecatedMessages.add(s))}if(!w.name)try{Object.defineProperty(w,"name",{get:()=>"_"+d.replace(/\W+/g,"_")+"_hook_cb",configurable:!0})}catch{}return this._hooks[d]=this._hooks[d]||[],this._hooks[d].push(w),()=>{w&&(this.removeHook(d,w),w=void 0)}}hookOnce(d,w){let t,x=(...v)=>(typeof t=="function"&&t(),t=void 0,x=void 0,w(...v));return t=this.hook(d,x),t}removeHook(d,w){if(this._hooks[d]){const t=this._hooks[d].indexOf(w);t!==-1&&this._hooks[d].splice(t,1),this._hooks[d].length===0&&delete this._hooks[d]}}deprecateHook(d,w){this._deprecatedHooks[d]=typeof w=="string"?{to:w}:w;const t=this._hooks[d]||[];delete this._hooks[d];for(const x of t)this.hook(d,x)}deprecateHooks(d){Object.assign(this._deprecatedHooks,d);for(const w in d)this.deprecateHook(w,d[w])}addHooks(d){const w=ja(d),t=Object.keys(w).map(x=>this.hook(x,w[x]));return()=>{for(const x of t.splice(0,t.length))x()}}removeHooks(d){const w=ja(d);for(const t in w)this.removeHook(t,w[t])}removeAllHooks(){for(const d in this._hooks)delete this._hooks[d]}callHook(d,...w){return w.unshift(d),this.callHookWith(sg,d,...w)}callHookParallel(d,...w){return w.unshift(d),this.callHookWith(ig,d,...w)}callHookWith(d,w,...t){const x=this._before||this._after?{name:w,args:t,context:{}}:void 0;this._before&&zi(this._before,x);const v=d(w in this._hooks?[...this._hooks[w]]:[],t);return v instanceof Promise?v.finally(()=>{this._after&&x&&zi(this._after,x)}):(this._after&&x&&zi(this._after,x),v)}beforeEach(d){return this._before=this._before||[],this._before.push(d),()=>{if(this._before!==void 0){const w=this._before.indexOf(d);w!==-1&&this._before.splice(w,1)}}}afterEach(d){return this._after=this._after||[],this._after.push(d),()=>{if(this._after!==void 0){const w=this._after.indexOf(d);w!==-1&&this._after.splice(w,1)}}}}function bf(){return new ag}function lg(r={}){let d,w=!1;const t=s=>{if(d&&d!==s)throw new Error("Context conflict")};let x;if(r.asyncContext){const s=r.AsyncLocalStorage||globalThis.AsyncLocalStorage;s?x=new s:console.warn("[unctx] `AsyncLocalStorage` is not provided.")}const v=()=>{if(x&&d===void 0){const s=x.getStore();if(s!==void 0)return s}return d};return{use:()=>{const s=v();if(s===void 0)throw new Error("Context is not available");return s},tryUse:()=>v(),set:(s,c)=>{c||t(s),d=s,w=!0},unset:()=>{d=void 0,w=!1},call:(s,c)=>{t(s),d=s;try{return x?x.run(s,c):c()}finally{w||(d=void 0)}},async callAsync(s,c){d=s;const o=()=>{d=s},u=()=>d===s?o:void 0;Sa.add(u);try{const g=x?x.run(s,c):c();return w||(d=void 0),await g}finally{Sa.delete(u)}}}}function ug(r={}){const d={};return{get(w,t={}){return d[w]||(d[w]=lg({...r,...t})),d[w],d[w]}}}const ei=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof global<"u"?global:typeof window<"u"?window:{},tc="__unctx__",cg=ei[tc]||(ei[tc]=ug()),dg=(r,d={})=>cg.get(r,d),rc="__unctx_async_handlers__",Sa=ei[rc]||(ei[rc]=new Set);function rs(r){const d=[];for(const x of Sa){const v=x();v&&d.push(v)}const w=()=>{for(const x of d)x()};let t=r();return t&&typeof t=="object"&&"catch"in t&&(t=t.catch(x=>{throw w(),x})),[t,w]}const _f=dg("nuxt-app",{asyncContext:!1}),fg="__nuxt_plugin";function hg(r){let d=0;const w={_scope:Kh(),provide:void 0,globalName:"nuxt",versions:{get nuxt(){return"3.11.2"},get vue(){return w.vueApp.version}},payload:Bn({data:{},state:{},once:new Set,_errors:{},...window.__NUXT__??{}}),static:{data:{}},runWithContext:x=>w._scope.run(()=>yg(w,x)),isHydrating:!0,deferHydration(){if(!w.isHydrating)return()=>{};d++;let x=!1;return()=>{if(!x&&(x=!0,d--,d===0))return w.isHydrating=!1,w.callHook("app:suspense:resolve")}},_asyncDataPromises:{},_asyncData:{},_payloadRevivers:{},...r};w.hooks=bf(),w.hook=w.hooks.hook,w.callHook=w.hooks.callHook,w.provide=(x,v)=>{const s="$"+x;Ps(w,s,v),Ps(w.vueApp.config.globalProperties,s,v)},Ps(w.vueApp,"$nuxt",w),Ps(w.vueApp.config.globalProperties,"$nuxt",w);{window.addEventListener("nuxt.preloadError",v=>{w.callHook("app:chunkError",{error:v.payload})}),window.useNuxtApp=window.useNuxtApp||It;const x=w.hook("app:error",(...v)=>{console.error("[nuxt] error caught during app initialization",...v)});w.hook("app:mounted",x)}const t=w.payload.config;return w.provide("config",t),w}async function pg(r,d){if(d.hooks&&r.hooks.addHooks(d.hooks),typeof d=="function"){const{provide:w}=await r.runWithContext(()=>d(r))||{};if(w&&typeof w=="object")for(const t in w)r.provide(t,w[t])}}async function mg(r,d){const w=[],t=[],x=[],v=[];let s=0;async function c(o){var g;const u=((g=o.dependsOn)==null?void 0:g.filter(p=>d.some(n=>n._name===p)&&!w.includes(p)))??[];if(u.length>0)t.push([new Set(u),o]);else{const p=pg(r,o).then(async()=>{o._name&&(w.push(o._name),await Promise.all(t.map(async([n,i])=>{n.has(o._name)&&(n.delete(o._name),n.size===0&&(s++,await c(i)))})))});o.parallel?x.push(p.catch(n=>v.push(n))):await p}}for(const o of d)await c(o);if(await Promise.all(x),s)for(let o=0;o{}),r,{[fg]:!0,_name:d})}function yg(r,d,w){const t=()=>d();return _f.set(r),r.vueApp.runWithContext(t)}function gg(){var d;let r;return Pd()&&(r=(d=Eo())==null?void 0:d.appContext.app.$nuxt),r=r||_f.tryUse(),r||null}function It(){const r=gg();if(!r)throw new Error("[nuxt] instance unavailable");return r}function pi(r){return It().$config}function Ps(r,d,w){Object.defineProperty(r,d,{get:()=>w})}function vg(r,d){return{ctx:{table:r},matchAll:w=>xf(w,r)}}function wf(r){const d={};for(const w in r)d[w]=w==="dynamic"?new Map(Object.entries(r[w]).map(([t,x])=>[t,wf(x)])):new Map(Object.entries(r[w]));return d}function bg(r){return vg(wf(r))}function xf(r,d,w){r.endsWith("/")&&(r=r.slice(0,-1)||"/");const t=[];for(const[v,s]of nc(d.wildcard))(r===v||r.startsWith(v+"/"))&&t.push(s);for(const[v,s]of nc(d.dynamic))if(r.startsWith(v+"/")){const c="/"+r.slice(v.length).split("/").splice(2).join("/");t.push(...xf(c,s))}const x=d.static.get(r);return x&&t.push(x),t.filter(Boolean)}function nc(r){return[...r.entries()].sort((d,w)=>d[0].length-w[0].length)}function Wi(r){if(r===null||typeof r!="object")return!1;const d=Object.getPrototypeOf(r);return d!==null&&d!==Object.prototype&&Object.getPrototypeOf(d)!==null||Symbol.iterator in r?!1:Symbol.toStringTag in r?Object.prototype.toString.call(r)==="[object Module]":!0}function Ea(r,d,w=".",t){if(!Wi(d))return Ea(r,{},w,t);const x=Object.assign({},d);for(const v in r){if(v==="__proto__"||v==="constructor")continue;const s=r[v];s!=null&&(t&&t(x,v,s,w)||(Array.isArray(s)&&Array.isArray(x[v])?x[v]=[...s,...x[v]]:Wi(s)&&Wi(x[v])?x[v]=Ea(s,x[v],(w?`${w}.`:"")+v.toString(),t):x[v]=s))}return x}function jf(r){return(...d)=>d.reduce((w,t)=>Ea(w,t,"",r),{})}const Sf=jf(),_g=jf((r,d,w)=>{if(r[d]!==void 0&&typeof w=="function")return r[d]=w(r[d]),!0});function wg(r,d){try{return d in r}catch{return!1}}var xg=Object.defineProperty,jg=(r,d,w)=>d in r?xg(r,d,{enumerable:!0,configurable:!0,writable:!0,value:w}):r[d]=w,Wn=(r,d,w)=>(jg(r,typeof d!="symbol"?d+"":d,w),w);class Ta extends Error{constructor(d,w={}){super(d,w),Wn(this,"statusCode",500),Wn(this,"fatal",!1),Wn(this,"unhandled",!1),Wn(this,"statusMessage"),Wn(this,"data"),Wn(this,"cause"),w.cause&&!this.cause&&(this.cause=w.cause)}toJSON(){const d={message:this.message,statusCode:Ma(this.statusCode,500)};return this.statusMessage&&(d.statusMessage=Ef(this.statusMessage)),this.data!==void 0&&(d.data=this.data),d}}Wn(Ta,"__h3_error__",!0);function ka(r){if(typeof r=="string")return new Ta(r);if(Sg(r))return r;const d=new Ta(r.message??r.statusMessage??"",{cause:r.cause||r});if(wg(r,"stack"))try{Object.defineProperty(d,"stack",{get(){return r.stack}})}catch{try{d.stack=r.stack}catch{}}if(r.data&&(d.data=r.data),r.statusCode?d.statusCode=Ma(r.statusCode,d.statusCode):r.status&&(d.statusCode=Ma(r.status,d.statusCode)),r.statusMessage?d.statusMessage=r.statusMessage:r.statusText&&(d.statusMessage=r.statusText),d.statusMessage){const w=d.statusMessage;Ef(d.statusMessage)!==w&&console.warn("[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default.")}return r.fatal!==void 0&&(d.fatal=r.fatal),r.unhandled!==void 0&&(d.unhandled=r.unhandled),d}function Sg(r){var d;return((d=r==null?void 0:r.constructor)==null?void 0:d.__h3_error__)===!0}const Eg=/[^\u0009\u0020-\u007E]/g;function Ef(r=""){return r.replace(Eg,"")}function Ma(r,d=200){return!r||(typeof r=="string"&&(r=Number.parseInt(r,10)),r<100||r>999)?d:r}const Tf=Symbol("layout-meta"),ps=Symbol("route"),qr=()=>{var r;return(r=It())==null?void 0:r.$router},mi=()=>Pd()?Ht(ps,It()._route):It()._route;const Tg=()=>{try{if(It()._processingMiddleware)return!0}catch{return!1}return!1},kg=(r,d)=>{r||(r="/");const w=typeof r=="string"?r:ff(r.path||"/",r.query||{})+(r.hash||"");if(d!=null&&d.open){const{target:c="_blank",windowFeatures:o={}}=d.open,u=Object.entries(o).filter(([g,p])=>p!==void 0).map(([g,p])=>`${g.toLowerCase()}=${p}`).join(", ");return open(w,c,u),Promise.resolve()}const t=(d==null?void 0:d.external)||gn(w,{acceptRelative:!0});if(t){if(!(d!=null&&d.external))throw new Error("Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`.");const c=hs(w).protocol;if(c&&Ry(c))throw new Error(`Cannot navigate to a URL with '${c}' protocol.`)}const x=Tg();if(!t&&x)return r;const v=qr(),s=It();return t?(s._scope.stop(),d!=null&&d.replace?location.replace(w):location.href=w,x?s.isHydrating?new Promise(()=>{}):!1:Promise.resolve()):d!=null&&d.replace?v.replace(r):v.push(r)},kf="__nuxt_error",yi=()=>Tp(It().payload,"error"),lo=r=>{const d=gi(r);try{const w=It(),t=yi();w.hooks.callHook("app:error",d),t.value=t.value||d}catch{throw d}return d},Mg=async(r={})=>{const d=It(),w=yi();d.callHook("app:error:cleared",r),r.redirect&&await qr().replace(r.redirect),w.value=null},Cg=r=>!!r&&typeof r=="object"&&kf in r,gi=r=>{const d=ka(r);return Object.defineProperty(d,kf,{value:!0,configurable:!1,writable:!1}),d},Og=-1,Pg=-2,Ag=-3,Rg=-4,Lg=-5,Ig=-6;function Dg(r,d){return Fg(JSON.parse(r),d)}function Fg(r,d){if(typeof r=="number")return x(r,!0);if(!Array.isArray(r)||r.length===0)throw new Error("Invalid input");const w=r,t=Array(w.length);function x(v,s=!1){if(v===Og)return;if(v===Ag)return NaN;if(v===Rg)return 1/0;if(v===Lg)return-1/0;if(v===Ig)return-0;if(s)throw new Error("Invalid input");if(v in t)return t[v];const c=w[v];if(!c||typeof c!="object")t[v]=c;else if(Array.isArray(c))if(typeof c[0]=="string"){const o=c[0],u=d==null?void 0:d[o];if(u)return t[v]=u(x(c[1]));switch(o){case"Date":t[v]=new Date(c[1]);break;case"Set":const g=new Set;t[v]=g;for(let i=1;i>>9)+65536).toString(16).substring(1,8).toLowerCase()}function oc(r){return r._h||dl(r._d?r._d:`${r.tag}:${r.textContent||r.innerHTML||""}:${Object.entries(r.props).map(([d,w])=>`${d}:${String(w)}`).join(",")}`)}function Cf(r,d){const{props:w,tag:t}=r;if(Gg.includes(t))return t;if(t==="link"&&w.rel==="canonical")return"canonical";if(w.charset)return"charset";const x=["id"];t==="meta"&&x.push("name","property","http-equiv");for(const v of x)if(typeof w[v]<"u"){const s=String(w[v]);return`${t}:${v}:${s}`}return!1}function sc(r,d){return r==null?d||null:typeof r=="function"?r(d):r}function Of(r,d){const w=[],t=d.resolveKeyData||(v=>v.key),x=d.resolveValueData||(v=>v.value);for(const[v,s]of Object.entries(r))w.push(...(Array.isArray(s)?s:[s]).map(c=>{const o={key:v,value:c},u=x(o);return typeof u=="object"?Of(u,d):Array.isArray(u)?u:{[typeof d.key=="function"?d.key(o):d.key]:t(o),[typeof d.value=="function"?d.value(o):d.value]:u}}).flat());return w}function Pf(r,d){return Object.entries(r).map(([w,t])=>{if(typeof t=="object"&&(t=Pf(t,d)),d.resolve){const x=d.resolve({key:w,value:t});if(typeof x<"u")return x}return typeof t=="number"&&(t=t.toString()),typeof t=="string"&&d.wrapValue&&(t=t.replace(new RegExp(d.wrapValue,"g"),`\\${d.wrapValue}`),t=`${d.wrapValue}${t}${d.wrapValue}`),`${w}${d.keyValueSeparator||""}${t}`}).join(d.entrySeparator||"")}const mr=r=>({keyValue:r,metaKey:"property"}),qi=r=>({keyValue:r}),fl={appleItunesApp:{unpack:{entrySeparator:", ",resolve({key:r,value:d}){return`${pn(r)}=${d}`}}},articleExpirationTime:mr("article:expiration_time"),articleModifiedTime:mr("article:modified_time"),articlePublishedTime:mr("article:published_time"),bookReleaseDate:mr("book:release_date"),charset:{metaKey:"charset"},contentSecurityPolicy:{unpack:{entrySeparator:"; ",resolve({key:r,value:d}){return`${pn(r)} ${d}`}},metaKey:"http-equiv"},contentType:{metaKey:"http-equiv"},defaultStyle:{metaKey:"http-equiv"},fbAppId:mr("fb:app_id"),msapplicationConfig:qi("msapplication-Config"),msapplicationTileColor:qi("msapplication-TileColor"),msapplicationTileImage:qi("msapplication-TileImage"),ogAudioSecureUrl:mr("og:audio:secure_url"),ogAudioUrl:mr("og:audio"),ogImageSecureUrl:mr("og:image:secure_url"),ogImageUrl:mr("og:image"),ogSiteName:mr("og:site_name"),ogVideoSecureUrl:mr("og:video:secure_url"),ogVideoUrl:mr("og:video"),profileFirstName:mr("profile:first_name"),profileLastName:mr("profile:last_name"),profileUsername:mr("profile:username"),refresh:{metaKey:"http-equiv",unpack:{entrySeparator:";",resolve({key:r,value:d}){if(r==="seconds")return`${d}`}}},robots:{unpack:{entrySeparator:", ",resolve({key:r,value:d}){return typeof d=="boolean"?`${pn(r)}`:`${pn(r)}:${d}`}}},xUaCompatible:{metaKey:"http-equiv"}},Af=["og","book","article","profile"];function Rf(r){var w;const d=pn(r).split(":")[0];return Af.includes(d)?"property":((w=fl[r])==null?void 0:w.metaKey)||"name"}function Hg(r){var d;return((d=fl[r])==null?void 0:d.keyValue)||pn(r)}function pn(r){const d=r.replace(/([A-Z])/g,"-$1").toLowerCase(),w=d.split("-")[0];return Af.includes(w)||w==="twitter"?r.replace(/([A-Z])/g,":$1").toLowerCase():d}function Ca(r){if(Array.isArray(r))return r.map(w=>Ca(w));if(typeof r!="object"||Array.isArray(r))return r;const d={};for(const[w,t]of Object.entries(r))d[pn(w)]=Ca(t);return d}function zg(r,d){const w=fl[d];return d==="refresh"?`${r.seconds};url=${r.url}`:Pf(Ca(r),{keyValueSeparator:"=",entrySeparator:", ",resolve({value:t,key:x}){if(t===null)return"";if(typeof t=="boolean")return`${x}`},...w==null?void 0:w.unpack})}const Lf=["og:image","og:video","og:audio","twitter:image"];function If(r){const d={};return Object.entries(r).forEach(([w,t])=>{String(t)!=="false"&&w&&(d[w]=t)}),d}function ic(r,d){const w=If(d),t=pn(r),x=Rf(t);if(Lf.includes(t)){const v={};return Object.entries(w).forEach(([s,c])=>{v[`${r}${s==="url"?"":`${s.charAt(0).toUpperCase()}${s.slice(1)}`}`]=c}),hl(v).sort((s,c)=>{var o,u;return(((o=s[x])==null?void 0:o.length)||0)-(((u=c[x])==null?void 0:u.length)||0)})}return[{[x]:t,...w}]}function hl(r){const d=[],w={};Object.entries(r).forEach(([x,v])=>{if(!Array.isArray(v)){if(typeof v=="object"&&v){if(Lf.includes(pn(x))){d.push(...ic(x,v));return}w[x]=If(v)}else w[x]=v;return}v.forEach(s=>{d.push(...typeof s=="string"?hl({[x]:s}):ic(x,s))})});const t=Of(w,{key({key:x}){return Rf(x)},value({key:x}){return x==="charset"?"charset":"content"},resolveKeyData({key:x}){return Hg(x)},resolveValueData({value:x,key:v}){return x===null?"_null":typeof x=="object"?zg(x,v):typeof x=="number"?x.toString():x}});return[...d,...t].map(x=>(x.content==="_null"&&(x.content=null),x))}async function Wg(r,d,w){const t={tag:r,props:await Df(typeof d=="object"&&typeof d!="function"&&!(d instanceof Promise)?{...d}:{[["script","noscript","style"].includes(r)?"innerHTML":"textContent"]:d},["templateParams","titleTemplate"].includes(r))};return Mf.forEach(x=>{const v=typeof t.props[x]<"u"?t.props[x]:w[x];typeof v<"u"&&((!["innerHTML","textContent","children"].includes(x)||Ug.includes(t.tag))&&(t[x==="children"?"innerHTML":x]=v),delete t.props[x])}),t.props.body&&(t.tagPosition="bodyClose",delete t.props.body),t.tag==="script"&&typeof t.innerHTML=="object"&&(t.innerHTML=JSON.stringify(t.innerHTML),t.props.type=t.props.type||"application/json"),Array.isArray(t.props.content)?t.props.content.map(x=>({...t,props:{...t.props,content:x}})):t}function qg(r,d){var t;const w=r==="class"?" ":";";return typeof d=="object"&&!Array.isArray(d)&&(d=Object.entries(d).filter(([,x])=>x).map(([x,v])=>r==="style"?`${x}:${v}`:x)),(t=String(Array.isArray(d)?d.join(w):d))==null?void 0:t.split(w).filter(x=>x.trim()).filter(Boolean).join(w)}async function Df(r,d){for(const w of Object.keys(r)){if(["class","style"].includes(w)){r[w]=qg(w,r[w]);continue}if(r[w]instanceof Promise&&(r[w]=await r[w]),!d&&!Mf.includes(w)){const t=String(r[w]),x=w.startsWith("data-");t==="true"||t===""?r[w]=x?"true":!0:r[w]||(x&&t==="false"?r[w]="false":delete r[w])}}return r}const Xg=10;async function Yg(r){const d=[];return Object.entries(r.resolvedInput).filter(([w,t])=>typeof t<"u"&&Bg.includes(w)).forEach(([w,t])=>{const x=Ng(t);d.push(...x.map(v=>Wg(w,v,r)).flat())}),(await Promise.all(d)).flat().filter(Boolean).map((w,t)=>(w._e=r._i,r.mode&&(w._m=r.mode),w._p=(r._i<o&&o[u]||void 0,d):c=d[s],typeof c<"u"?(c||"").replace(/"/g,'\\"'):!1}let x=r;try{x=decodeURI(r)}catch{}return(x.match(/%(\w+\.+\w+)|%(\w+)/g)||[]).sort().reverse().forEach(s=>{const c=t(s.slice(1));typeof c=="string"&&(r=r.replace(new RegExp(`\\${s}(\\W|$)`,"g"),(o,u)=>`${c}${u}`).trim())}),r.includes(En)&&(r.endsWith(En)&&(r=r.slice(0,-En.length).trim()),r.startsWith(En)&&(r=r.slice(En.length).trim()),r=r.replace(new RegExp(`\\${En}\\s*\\${En}`,"g"),En),r=Bs(r,{separator:w},w)),r}async function Ff(r,d={}){var g;const w=d.document||r.resolvedOptions.document;if(!w||!r.dirty)return;const t={shouldRender:!0,tags:[]};if(await r.hooks.callHook("dom:beforeRender",t),!t.shouldRender)return;const x=(await r.resolveTags()).map(p=>({tag:p,id:Us.includes(p.tag)?oc(p):p.tag,shouldRender:!0}));let v=r._dom;if(!v){v={elMap:{htmlAttrs:w.documentElement,bodyAttrs:w.body}};for(const p of["body","head"]){const n=(g=w[p])==null?void 0:g.children,i=[];for(const a of[...n].filter(h=>Us.includes(h.tagName.toLowerCase()))){const h={tag:a.tagName.toLowerCase(),props:await Df(a.getAttributeNames().reduce((f,m)=>({...f,[m]:a.getAttribute(m)}),{})),innerHTML:a.innerHTML};let y=1,l=Cf(h);for(;l&&i.find(f=>f._d===l);)l=`${l}:${y++}`;h._d=l||void 0,i.push(h),v.elMap[a.getAttribute("data-hid")||oc(h)]=a}}}v.pendingSideEffects={...v.sideEffects||{}},v.sideEffects={};function s(p,n,i){const a=`${p}:${n}`;v.sideEffects[a]=i,delete v.pendingSideEffects[a]}function c({id:p,$el:n,tag:i}){const a=i.tag.endsWith("Attrs");v.elMap[p]=n,a||(["textContent","innerHTML"].forEach(h=>{i[h]&&i[h]!==n[h]&&(n[h]=i[h])}),s(p,"el",()=>{var h;(h=v.elMap[p])==null||h.remove(),delete v.elMap[p]}));for(const[h,y]of Object.entries(i._eventHandlers||{}))n.getAttribute(`data-${h}`)!==""&&((i.tag==="bodyAttrs"?w.defaultView:n).addEventListener(h.replace("on",""),y.bind(n)),n.setAttribute(`data-${h}`,""));Object.entries(i.props).forEach(([h,y])=>{const l=`attr:${h}`;if(h==="class")for(const f of(y||"").split(" ").filter(Boolean))a&&s(p,`${l}:${f}`,()=>n.classList.remove(f)),!n.classList.contains(f)&&n.classList.add(f);else if(h==="style")for(const f of(y||"").split(";").filter(Boolean)){const[m,...b]=f.split(":").map(j=>j.trim());s(p,`${l}:${m}`,()=>{n.style.removeProperty(m)}),n.style.setProperty(m,b.join(":"))}else n.getAttribute(h)!==y&&n.setAttribute(h,y===!0?"":String(y)),a&&s(p,l,()=>n.removeAttribute(h))})}const o=[],u={bodyClose:void 0,bodyOpen:void 0,head:void 0};for(const p of x){const{tag:n,shouldRender:i,id:a}=p;if(i){if(n.tag==="title"){w.title=n.textContent;continue}p.$el=p.$el||v.elMap[a],p.$el?c(p):Us.includes(n.tag)&&o.push(p)}}for(const p of o){const n=p.tag.tagPosition||"head";p.$el=w.createElement(p.tag.tag),c(p),u[n]=u[n]||w.createDocumentFragment(),u[n].appendChild(p.$el)}for(const p of x)await r.hooks.callHook("dom:renderTag",p,w,s);u.head&&w.head.appendChild(u.head),u.bodyOpen&&w.body.insertBefore(u.bodyOpen,w.body.firstChild),u.bodyClose&&w.body.appendChild(u.bodyClose),Object.values(v.pendingSideEffects).forEach(p=>p()),r._dom=v,r.dirty=!1,await r.hooks.callHook("dom:rendered",{renders:x})}async function Kg(r,d={}){const w=d.delayFn||(t=>setTimeout(t,10));return r._domUpdatePromise=r._domUpdatePromise||new Promise(t=>w(async()=>{await Ff(r,d),delete r._domUpdatePromise,t()}))}function Zg(r){return d=>{var t,x;const w=((x=(t=d.resolvedOptions.document)==null?void 0:t.head.querySelector('script[id="unhead:payload"]'))==null?void 0:x.innerHTML)||!1;return w&&d.push(JSON.parse(w)),{mode:"client",hooks:{"entries:updated":function(v){Kg(v,r)}}}}}const Qg=["templateParams","htmlAttrs","bodyAttrs"],Jg={hooks:{"tag:normalise":function({tag:r}){["hid","vmid","key"].forEach(t=>{r.props[t]&&(r.key=r.props[t],delete r.props[t])});const w=Cf(r)||(r.key?`${r.tag}:${r.key}`:!1);w&&(r._d=w)},"tags:resolve":function(r){const d={};r.tags.forEach(t=>{const x=(t.key?`${t.tag}:${t.key}`:t._d)||t._p,v=d[x];if(v){let c=t==null?void 0:t.tagDuplicateStrategy;if(!c&&Qg.includes(t.tag)&&(c="merge"),c==="merge"){const o=v.props;["class","style"].forEach(u=>{o[u]&&(t.props[u]?(u==="style"&&!o[u].endsWith(";")&&(o[u]+=";"),t.props[u]=`${o[u]} ${t.props[u]}`):t.props[u]=o[u])}),d[x].props={...o,...t.props};return}else if(t._e===v._e){v._duped=v._duped||[],t._d=`${v._d}:${v._duped.length+1}`,v._duped.push(t);return}else if(ti(t)>ti(v))return}const s=Object.keys(t.props).length+(t.innerHTML?1:0)+(t.textContent?1:0);if(Us.includes(t.tag)&&s===0){delete d[x];return}d[x]=t});const w=[];Object.values(d).forEach(t=>{const x=t._duped;delete t._duped,w.push(t),x&&w.push(...x)}),r.tags=w,r.tags=r.tags.filter(t=>!(t.tag==="meta"&&(t.props.name||t.props.property)&&!t.props.content))}}},ev={mode:"server",hooks:{"tags:resolve":function(r){const d={};r.tags.filter(w=>["titleTemplate","templateParams","title"].includes(w.tag)&&w._m==="server").forEach(w=>{d[w.tag]=w.tag.startsWith("title")?w.textContent:w.props}),Object.keys(d).length&&r.tags.push({tag:"script",innerHTML:JSON.stringify(d),props:{id:"unhead:payload",type:"application/json"}})}}},tv=["script","link","bodyAttrs"],rv=r=>({hooks:{"tags:resolve":function(d){for(const w of d.tags.filter(t=>tv.includes(t.tag)))Object.entries(w.props).forEach(([t,x])=>{t.startsWith("on")&&typeof x=="function"&&(r.ssr&&uc.includes(t)?w.props[t]=`this.dataset.${t}fired = true`:delete w.props[t],w._eventHandlers=w._eventHandlers||{},w._eventHandlers[t]=x)}),r.ssr&&w._eventHandlers&&(w.props.src||w.props.href)&&(w.key=w.key||dl(w.props.src||w.props.href))},"dom:renderTag":function({$el:d,tag:w}){var t,x;for(const v of Object.keys((d==null?void 0:d.dataset)||{}).filter(s=>uc.some(c=>`${c}fired`===s))){const s=v.replace("fired","");(x=(t=w._eventHandlers)==null?void 0:t[s])==null||x.call(d,new Event(s.replace("on","")))}}}}),nv=["link","style","script","noscript"],ov={hooks:{"tag:normalise":({tag:r})=>{r.key&&nv.includes(r.tag)&&(r.props["data-hid"]=r._h=dl(r.key))}}},sv={hooks:{"tags:resolve":r=>{const d=w=>{var t;return(t=r.tags.find(x=>x._d===w))==null?void 0:t._p};for(const{prefix:w,offset:t}of $g)for(const x of r.tags.filter(v=>typeof v.tagPriority=="string"&&v.tagPriority.startsWith(w))){const v=d(x.tagPriority.replace(w,""));typeof v<"u"&&(x._p=v+t)}r.tags.sort((w,t)=>w._p-t._p).sort((w,t)=>ti(w)-ti(t))}}},iv={meta:"content",link:"href",htmlAttrs:"lang"},av=r=>({hooks:{"tags:resolve":d=>{var c;const{tags:w}=d,t=(c=w.find(o=>o.tag==="title"))==null?void 0:c.textContent,x=w.findIndex(o=>o.tag==="templateParams"),v=x!==-1?w[x].props:{},s=v.separator||"|";delete v.separator,v.pageTitle=Bs(v.pageTitle||t||"",v,s);for(const o of w.filter(u=>u.processTemplateParams!==!1)){const u=iv[o.tag];u&&typeof o.props[u]=="string"?o.props[u]=Bs(o.props[u],v,s):(o.processTemplateParams===!0||["titleTemplate","title"].includes(o.tag))&&["innerHTML","textContent"].forEach(g=>{typeof o[g]=="string"&&(o[g]=Bs(o[g],v,s))})}r._templateParams=v,r._separator=s,d.tags=w.filter(o=>o.tag!=="templateParams")}}}),lv={hooks:{"tags:resolve":r=>{const{tags:d}=r;let w=d.findIndex(x=>x.tag==="titleTemplate");const t=d.findIndex(x=>x.tag==="title");if(t!==-1&&w!==-1){const x=sc(d[w].textContent,d[t].textContent);x!==null?d[t].textContent=x||d[t].textContent:delete d[t]}else if(w!==-1){const x=sc(d[w].textContent);x!==null&&(d[w].textContent=x,d[w].tag="title",w=-1)}w!==-1&&delete d[w],r.tags=d.filter(Boolean)}}},uv={hooks:{"tags:afterResolve":function(r){for(const d of r.tags)typeof d.innerHTML=="string"&&(d.innerHTML&&["application/ld+json","application/json"].includes(d.props.type)?d.innerHTML=d.innerHTML.replace(/{c.dirty=!0,d.callHook("entries:updated",c)};let x=0,v=[];const s=[],c={plugins:s,dirty:!1,resolvedOptions:r,hooks:d,headEntries(){return v},use(o){const u=typeof o=="function"?o(c):o;(!u.key||!s.some(g=>g.key===u.key))&&(s.push(u),cc(u.mode,w)&&d.addHooks(u.hooks||{}))},push(o,u){u==null||delete u.head;const g={_i:x++,input:o,...u};return cc(g.mode,w)&&(v.push(g),t()),{dispose(){v=v.filter(p=>p._i!==g._i),d.callHook("entries:updated",c),t()},patch(p){v=v.map(n=>(n._i===g._i&&(n.input=g.input=p),n)),t()}}},async resolveTags(){const o={tags:[],entries:[...v]};await d.callHook("entries:resolve",o);for(const u of o.entries){const g=u.resolvedInput||u.input;if(u.resolvedInput=await(u.transform?u.transform(g):g),u.resolvedInput)for(const p of await Yg(u)){const n={tag:p,entry:u,resolvedOptions:c.resolvedOptions};await d.callHook("tag:normalise",n),o.tags.push(n.tag)}}return await d.callHook("tags:beforeResolve",o),await d.callHook("tags:resolve",o),await d.callHook("tags:afterResolve",o),o.tags},ssr:w};return[Jg,ev,rv,ov,sv,av,lv,uv,...(r==null?void 0:r.plugins)||[]].forEach(o=>c.use(o)),c.hooks.callHook("init",c),c}function fv(){return Nf}const hv=sf.startsWith("3");function pv(r){return typeof r=="function"?r():Bt(r)}function ri(r,d=""){if(r instanceof Promise)return r;const w=pv(r);return!r||!w?w:Array.isArray(w)?w.map(t=>ri(t,d)):typeof w=="object"?Object.fromEntries(Object.entries(w).map(([t,x])=>t==="titleTemplate"||t.startsWith("on")?[t,Bt(x)]:[t,ri(x,t)])):w}const mv={hooks:{"entries:resolve":function(r){for(const d of r.entries)d.resolvedInput=ri(d.input)}}},Uf="usehead";function yv(r){return{install(w){hv&&(w.config.globalProperties.$unhead=r,w.config.globalProperties.$head=r,w.provide(Uf,r))}}.install}function gv(r={}){r.domDelayFn=r.domDelayFn||(w=>Fr(()=>setTimeout(()=>w(),0)));const d=cv(r);return d.use(mv),d.install=yv(d),d}const Oa=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},Pa="__unhead_injection_handler__";function vv(r){Oa[Pa]=r}function bv(){if(Pa in Oa)return Oa[Pa]();const r=Ht(Uf);return r||fv()}function _v(r,d={}){const w=d.head||bv();if(w)return w.ssr?w.push(r,d):wv(w,r,d)}function wv(r,d,w={}){const t=mt(!1),x=mt({});ln(()=>{x.value=t.value?{}:ri(d)});const v=r.push(x.value,w);return In(x,c=>{v.patch(c)}),Eo()&&(ls(()=>{v.dispose()}),qd(()=>{t.value=!0}),Wd(()=>{t.value=!1})),v}function xv(r,d){const{title:w,titleTemplate:t,...x}=r;return _v({title:w,titleTemplate:t,_flatMeta:x},{...d,transform(v){const s=hl({...v._flatMeta});return delete v._flatMeta,{...v,meta:s}}})}const jv={nuxt:{buildId:"ec692c5a-cbf0-4ead-bb7d-a040a1fc0357"}},Sv=_g(jv);function Bf(){const r=It();return r._appConfig||(r._appConfig=Bn(Sv)),r._appConfig}const Ev=!1,Aa=!1,Tv=!1,kv={componentName:"NuxtLink"},O_={deep:!0},P_={},Mv="#__nuxt";let Gs,Gf;function Cv(){var d;const r=(d=Bf().nuxt)==null?void 0:d.buildId;return Gs=$fetch(cl(`builds/meta/${r}.json`)),Gs.then(w=>{Gf=bg(w.matcher)}),Gs}function vi(){return Gs||Cv()}async function pl(r){return await vi(),Sf({},...Gf.matchAll(r).reverse())}function dc(r,d={}){const w=Pv(r,d),t=It(),x=t._payloadCache=t._payloadCache||{};return w in x||(x[w]=Av(r).then(v=>v?Vf(w).then(s=>s||(delete x[w],null)):(x[w]=null,null))),x[w]}const Ov="_payload.json";function Pv(r,d={}){var x;const w=new URL(r,"http://localhost");if(w.host!=="localhost"||gn(w.pathname,{acceptRelative:!0}))throw new Error("Payload URL must not include hostname: "+r);const t=d.hash||(d.fresh?Date.now():(x=Bf().nuxt)==null?void 0:x.buildId);return hi(pi().app.baseURL,w.pathname,Ov+(t?`?${t}`:""))}async function Vf(r){const d=fetch(r).then(w=>w.text().then(Hf));try{return await d}catch(w){console.warn("[nuxt] Cannot load payload ",r,w)}return null}async function Av(r=mi().path){if(r=fi(r),(await vi()).prerendered.includes(r))return!0;const w=await pl(r);return!!w.prerender&&!w.redirect}let As=null;async function Rv(){if(As)return As;const r=document.getElementById("__NUXT_DATA__");if(!r)return{};const d=await Hf(r.textContent||""),w=r.dataset.src?await Vf(r.dataset.src):void 0;return As={...d,...w,...window.__NUXT__},As}async function Hf(r){return await Dg(r,It()._payloadRevivers)}function Lv(r,d){It()._payloadRevivers[r]=d}const fc={NuxtError:r=>gi(r),EmptyShallowRef:r=>Ko(r==="_"?void 0:r==="0n"?BigInt(0):Ks(r)),EmptyRef:r=>mt(r==="_"?void 0:r==="0n"?BigInt(0):Ks(r)),ShallowRef:r=>Ko(r),ShallowReactive:r=>as(r),Ref:r=>mt(r),Reactive:r=>Bn(r)},Iv=vn({name:"nuxt:revive-payload:client",order:-30,async setup(r){let d,w;for(const t in fc)Lv(t,fc[t]);Object.assign(r.payload,([d,w]=rs(()=>r.runWithContext(Rv)),d=await d,w(),d)),window.__NUXT__=r.payload}}),Dv=[],Fv=vn({name:"nuxt:head",enforce:"pre",setup(r){const d=gv({plugins:Dv});vv(()=>It().vueApp._context.provides.usehead),r.vueApp.use(d);{let w=!0;const t=async()=>{w=!1,await Ff(d)};d.hooks.hook("dom:beforeRender",x=>{x.shouldRender=!w}),r.hooks.hook("page:start",()=>{w=!0}),r.hooks.hook("page:finish",()=>{r.isHydrating||t()}),r.hooks.hook("app:error",t),r.hooks.hook("app:suspense:resolve",t)}}});/*! + * vue-router v4.4.0 * (c) 2024 Eduardo San Martin Morote * @license MIT - */const io=typeof document<"u";function Dv(r){return r.__esModule||r[Symbol.toStringTag]==="Module"}const xt=Object.assign;function Xi(r,d){const w={};for(const t in d){const x=d[t];w[t]=Jr(x)?x.map(r):r(x)}return w}const qo=()=>{},Jr=Array.isArray,Hf=/#/g,Fv=/&/g,Nv=/\//g,Uv=/=/g,Bv=/\?/g,zf=/\+/g,Gv=/%5B/g,Vv=/%5D/g,Wf=/%5E/g,Hv=/%60/g,qf=/%7B/g,zv=/%7C/g,Xf=/%7D/g,Wv=/%20/g;function yl(r){return encodeURI(""+r).replace(zv,"|").replace(Gv,"[").replace(Vv,"]")}function qv(r){return yl(r).replace(qf,"{").replace(Xf,"}").replace(Wf,"^")}function Ra(r){return yl(r).replace(zf,"%2B").replace(Wv,"+").replace(Hf,"%23").replace(Fv,"%26").replace(Hv,"`").replace(qf,"{").replace(Xf,"}").replace(Wf,"^")}function Xv(r){return Ra(r).replace(Uv,"%3D")}function Yv(r){return yl(r).replace(Hf,"%23").replace(Bv,"%3F")}function $v(r){return r==null?"":Yv(r).replace(Nv,"%2F")}function ns(r){try{return decodeURIComponent(""+r)}catch{}return""+r}const Kv=/\/$/,Zv=r=>r.replace(Kv,"");function Yi(r,d,w="/"){let t,x={},v="",s="";const c=d.indexOf("#");let o=d.indexOf("?");return c=0&&(o=-1),o>-1&&(t=d.slice(0,o),v=d.slice(o+1,c>-1?c:d.length),x=r(v)),c>-1&&(t=t||d.slice(0,c),s=d.slice(c,d.length)),t=t0(t??d,w),{fullPath:t+(v&&"?")+v+s,path:t,query:x,hash:ns(s)}}function Qv(r,d){const w=d.query?r(d.query):"";return d.path+(w&&"?")+w+(d.hash||"")}function pc(r,d){return!d||!r.toLowerCase().startsWith(d.toLowerCase())?r:r.slice(d.length)||"/"}function Jv(r,d,w){const t=d.matched.length-1,x=w.matched.length-1;return t>-1&&t===x&&wo(d.matched[t],w.matched[x])&&Yf(d.params,w.params)&&r(d.query)===r(w.query)&&d.hash===w.hash}function wo(r,d){return(r.aliasOf||r)===(d.aliasOf||d)}function Yf(r,d){if(Object.keys(r).length!==Object.keys(d).length)return!1;for(const w in r)if(!e0(r[w],d[w]))return!1;return!0}function e0(r,d){return Jr(r)?mc(r,d):Jr(d)?mc(d,r):r===d}function mc(r,d){return Jr(d)?r.length===d.length&&r.every((w,t)=>w===d[t]):r.length===1&&r[0]===d}function t0(r,d){if(r.startsWith("/"))return r;if(!r)return d;const w=d.split("/"),t=r.split("/"),x=t[t.length-1];(x===".."||x===".")&&t.push("");let v=w.length-1,s,c;for(s=0;s1&&v--;else break;return w.slice(0,v).join("/")+"/"+t.slice(s).join("/")}var os;(function(r){r.pop="pop",r.push="push"})(os||(os={}));var Xo;(function(r){r.back="back",r.forward="forward",r.unknown=""})(Xo||(Xo={}));function r0(r){if(!r)if(io){const d=document.querySelector("base");r=d&&d.getAttribute("href")||"/",r=r.replace(/^\w+:\/\/[^\/]+/,"")}else r="/";return r[0]!=="/"&&r[0]!=="#"&&(r="/"+r),Zv(r)}const n0=/^[^#]+#/;function o0(r,d){return r.replace(n0,"#")+d}function s0(r,d){const w=document.documentElement.getBoundingClientRect(),t=r.getBoundingClientRect();return{behavior:d.behavior,left:t.left-w.left-(d.left||0),top:t.top-w.top-(d.top||0)}}const bi=()=>({left:window.scrollX,top:window.scrollY});function i0(r){let d;if("el"in r){const w=r.el,t=typeof w=="string"&&w.startsWith("#"),x=typeof w=="string"?t?document.getElementById(w.slice(1)):document.querySelector(w):w;if(!x)return;d=s0(x,r)}else d=r;"scrollBehavior"in document.documentElement.style?window.scrollTo(d):window.scrollTo(d.left!=null?d.left:window.scrollX,d.top!=null?d.top:window.scrollY)}function yc(r,d){return(history.state?history.state.position-d:-1)+r}const La=new Map;function a0(r,d){La.set(r,d)}function l0(r){const d=La.get(r);return La.delete(r),d}let u0=()=>location.protocol+"//"+location.host;function $f(r,d){const{pathname:w,search:t,hash:x}=d,v=r.indexOf("#");if(v>-1){let c=x.includes(r.slice(v))?r.slice(v).length:1,o=x.slice(c);return o[0]!=="/"&&(o="/"+o),pc(o,"")}return pc(w,r)+t+x}function c0(r,d,w,t){let x=[],v=[],s=null;const c=({state:n})=>{const i=$f(r,location),a=w.value,h=d.value;let m=0;if(n){if(w.value=i,d.value=n,s&&s===a){s=null;return}m=h?n.position-h.position:0}else t(i);x.forEach(l=>{l(w.value,a,{delta:m,type:os.pop,direction:m?m>0?Xo.forward:Xo.back:Xo.unknown})})};function o(){s=w.value}function u(n){x.push(n);const i=()=>{const a=x.indexOf(n);a>-1&&x.splice(a,1)};return v.push(i),i}function g(){const{history:n}=window;n.state&&n.replaceState(xt({},n.state,{scroll:bi()}),"")}function p(){for(const n of v)n();v=[],window.removeEventListener("popstate",c),window.removeEventListener("beforeunload",g)}return window.addEventListener("popstate",c),window.addEventListener("beforeunload",g,{passive:!0}),{pauseListeners:o,listen:u,destroy:p}}function gc(r,d,w,t=!1,x=!1){return{back:r,current:d,forward:w,replaced:t,position:window.history.length,scroll:x?bi():null}}function d0(r){const{history:d,location:w}=window,t={value:$f(r,w)},x={value:d.state};x.value||v(t.value,{back:null,current:t.value,forward:null,position:d.length-1,replaced:!0,scroll:null},!0);function v(o,u,g){const p=r.indexOf("#"),n=p>-1?(w.host&&document.querySelector("base")?r:r.slice(p))+o:u0()+r+o;try{d[g?"replaceState":"pushState"](u,"",n),x.value=u}catch(i){console.error(i),w[g?"replace":"assign"](n)}}function s(o,u){const g=xt({},d.state,gc(x.value.back,o,x.value.forward,!0),u,{position:x.value.position});v(o,g,!0),t.value=o}function c(o,u){const g=xt({},x.value,d.state,{forward:o,scroll:bi()});v(g.current,g,!0);const p=xt({},gc(t.value,o,null),{position:g.position+1},u);v(o,p,!1),t.value=o}return{location:t,state:x,push:c,replace:s}}function Kf(r){r=r0(r);const d=d0(r),w=c0(r,d.state,d.location,d.replace);function t(v,s=!0){s||w.pauseListeners(),history.go(v)}const x=xt({location:"",base:r,go:t,createHref:o0.bind(null,r)},d,w);return Object.defineProperty(x,"location",{enumerable:!0,get:()=>d.location.value}),Object.defineProperty(x,"state",{enumerable:!0,get:()=>d.state.value}),x}function f0(r){return r=location.host?r||location.pathname+location.search:"",r.includes("#")||(r+="#"),Kf(r)}function h0(r){return typeof r=="string"||r&&typeof r=="object"}function Zf(r){return typeof r=="string"||typeof r=="symbol"}const Kr={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Qf=Symbol("");var vc;(function(r){r[r.aborted=4]="aborted",r[r.cancelled=8]="cancelled",r[r.duplicated=16]="duplicated"})(vc||(vc={}));function xo(r,d){return xt(new Error,{type:r,[Qf]:!0},d)}function fn(r,d){return r instanceof Error&&Qf in r&&(d==null||!!(r.type&d))}const bc="[^/]+?",p0={sensitive:!1,strict:!1,start:!0,end:!0},m0=/[.+*?^${}()[\]/\\]/g;function y0(r,d){const w=xt({},p0,d),t=[];let x=w.start?"^":"";const v=[];for(const u of r){const g=u.length?[]:[90];w.strict&&!u.length&&(x+="/");for(let p=0;pd.length?d.length===1&&d[0]===80?1:-1:0}function Jf(r,d){let w=0;const t=r.score,x=d.score;for(;w0&&d[d.length-1]<0}const v0={type:0,value:""},b0=/[a-zA-Z0-9_]/;function _0(r){if(!r)return[[]];if(r==="/")return[[v0]];if(!r.startsWith("/"))throw new Error(`Invalid path "${r}"`);function d(i){throw new Error(`ERR (${w})/"${u}": ${i}`)}let w=0,t=w;const x=[];let v;function s(){v&&x.push(v),v=[]}let c=0,o,u="",g="";function p(){u&&(w===0?v.push({type:0,value:u}):w===1||w===2||w===3?(v.length>1&&(o==="*"||o==="+")&&d(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),v.push({type:1,value:u,regexp:g,repeatable:o==="*"||o==="+",optional:o==="*"||o==="?"})):d("Invalid state to consume buffer"),u="")}function n(){u+=o}for(;c{s(f)}:qo}function s(g){if(Zf(g)){const p=t.get(g);p&&(t.delete(g),w.splice(w.indexOf(p),1),p.children.forEach(s),p.alias.forEach(s))}else{const p=w.indexOf(g);p>-1&&(w.splice(p,1),g.record.name&&t.delete(g.record.name),g.children.forEach(s),g.alias.forEach(s))}}function c(){return w}function o(g){const p=T0(g,w);w.splice(p,0,g),g.record.name&&!xc(g)&&t.set(g.record.name,g)}function u(g,p){let n,i={},a,h;if("name"in g&&g.name){if(n=t.get(g.name),!n)throw xo(1,{location:g});h=n.record.name,i=xt(wc(p.params,n.keys.filter(f=>!f.optional).concat(n.parent?n.parent.keys.filter(f=>f.optional):[]).map(f=>f.name)),g.params&&wc(g.params,n.keys.map(f=>f.name))),a=n.stringify(i)}else if(g.path!=null)a=g.path,n=w.find(f=>f.re.test(a)),n&&(i=n.parse(a),h=n.record.name);else{if(n=p.name?t.get(p.name):w.find(f=>f.re.test(p.path)),!n)throw xo(1,{location:g,currentLocation:p});h=n.record.name,i=xt({},p.params,g.params),a=n.stringify(i)}const m=[];let l=n;for(;l;)m.unshift(l.record),l=l.parent;return{name:h,path:a,params:i,matched:m,meta:E0(m)}}return r.forEach(g=>v(g)),{addRoute:v,resolve:u,removeRoute:s,getRoutes:c,getRecordMatcher:x}}function wc(r,d){const w={};for(const t of d)t in r&&(w[t]=r[t]);return w}function j0(r){return{path:r.path,redirect:r.redirect,name:r.name,meta:r.meta||{},aliasOf:void 0,beforeEnter:r.beforeEnter,props:S0(r),children:r.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in r?r.components||null:r.component&&{default:r.component}}}function S0(r){const d={},w=r.props||!1;if("component"in r)d.default=w;else for(const t in r.components)d[t]=typeof w=="object"?w[t]:w;return d}function xc(r){for(;r;){if(r.record.aliasOf)return!0;r=r.parent}return!1}function E0(r){return r.reduce((d,w)=>xt(d,w.meta),{})}function jc(r,d){const w={};for(const t in r)w[t]=t in d?d[t]:r[t];return w}function T0(r,d){let w=0,t=d.length;for(;w!==t;){const v=w+t>>1;Jf(r,d[v])<0?t=v:w=v+1}const x=k0(r);return x&&(t=d.lastIndexOf(x,t-1)),t}function k0(r){let d=r;for(;d=d.parent;)if(eh(d)&&Jf(r,d)===0)return d}function eh({record:r}){return!!(r.name||r.components&&Object.keys(r.components).length||r.redirect)}function M0(r){const d={};if(r===""||r==="?")return d;const t=(r[0]==="?"?r.slice(1):r).split("&");for(let x=0;xv&&Ra(v)):[t&&Ra(t)]).forEach(v=>{v!==void 0&&(d+=(d.length?"&":"")+w,v!=null&&(d+="="+v))})}return d}function C0(r){const d={};for(const w in r){const t=r[w];t!==void 0&&(d[w]=Jr(t)?t.map(x=>x==null?null:""+x):t==null?t:""+t)}return d}const O0=Symbol(""),Ec=Symbol(""),gl=Symbol(""),vl=Symbol(""),Ia=Symbol("");function Fo(){let r=[];function d(t){return r.push(t),()=>{const x=r.indexOf(t);x>-1&&r.splice(x,1)}}function w(){r=[]}return{add:d,list:()=>r.slice(),reset:w}}function Cn(r,d,w,t,x,v=s=>s()){const s=t&&(t.enterCallbacks[x]=t.enterCallbacks[x]||[]);return()=>new Promise((c,o)=>{const u=n=>{n===!1?o(xo(4,{from:w,to:d})):n instanceof Error?o(n):h0(n)?o(xo(2,{from:d,to:n})):(s&&t.enterCallbacks[x]===s&&typeof n=="function"&&s.push(n),c())},g=v(()=>r.call(t&&t.instances[x],d,w,u));let p=Promise.resolve(g);r.length<3&&(p=p.then(u)),p.catch(n=>o(n))})}function $i(r,d,w,t,x=v=>v()){const v=[];for(const s of r)for(const c in s.components){let o=s.components[c];if(!(d!=="beforeRouteEnter"&&!s.instances[c]))if(P0(o)){const g=(o.__vccOpts||o)[d];g&&v.push(Cn(g,w,t,s,c,x))}else{let u=o();v.push(()=>u.then(g=>{if(!g)return Promise.reject(new Error(`Couldn't resolve component "${c}" at "${s.path}"`));const p=Dv(g)?g.default:g;s.components[c]=p;const i=(p.__vccOpts||p)[d];return i&&Cn(i,w,t,s,c,x)()}))}}return v}function P0(r){return typeof r=="object"||"displayName"in r||"props"in r||"__vccOpts"in r}function Tc(r){const d=Ht(gl),w=Ht(vl),t=jt(()=>{const o=Bt(r.to);return d.resolve(o)}),x=jt(()=>{const{matched:o}=t.value,{length:u}=o,g=o[u-1],p=w.matched;if(!g||!p.length)return-1;const n=p.findIndex(wo.bind(null,g));if(n>-1)return n;const i=kc(o[u-2]);return u>1&&kc(g)===i&&p[p.length-1].path!==i?p.findIndex(wo.bind(null,o[u-2])):n}),v=jt(()=>x.value>-1&&I0(w.params,t.value.params)),s=jt(()=>x.value>-1&&x.value===w.matched.length-1&&Yf(w.params,t.value.params));function c(o={}){return L0(o)?d[Bt(r.replace)?"replace":"push"](Bt(r.to)).catch(qo):Promise.resolve()}return{route:t,href:jt(()=>t.value.href),isActive:v,isExactActive:s,navigate:c}}const A0=pr({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Tc,setup(r,{slots:d}){const w=Un(Tc(r)),{options:t}=Ht(gl),x=jt(()=>({[Mc(r.activeClass,t.linkActiveClass,"router-link-active")]:w.isActive,[Mc(r.exactActiveClass,t.linkExactActiveClass,"router-link-exact-active")]:w.isExactActive}));return()=>{const v=d.default&&d.default(w);return r.custom?v:rr("a",{"aria-current":w.isExactActive?r.ariaCurrentValue:null,href:w.href,onClick:w.navigate,class:x.value},v)}}}),R0=A0;function L0(r){if(!(r.metaKey||r.altKey||r.ctrlKey||r.shiftKey)&&!r.defaultPrevented&&!(r.button!==void 0&&r.button!==0)){if(r.currentTarget&&r.currentTarget.getAttribute){const d=r.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(d))return}return r.preventDefault&&r.preventDefault(),!0}}function I0(r,d){for(const w in d){const t=d[w],x=r[w];if(typeof t=="string"){if(t!==x)return!1}else if(!Jr(x)||x.length!==t.length||t.some((v,s)=>v!==x[s]))return!1}return!0}function kc(r){return r?r.aliasOf?r.aliasOf.path:r.path:""}const Mc=(r,d,w)=>r??d??w,D0=pr({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(r,{attrs:d,slots:w}){const t=Ht(Ia),x=jt(()=>r.route||t.value),v=Ht(Ec,0),s=jt(()=>{let u=Bt(v);const{matched:g}=x.value;let p;for(;(p=g[u])&&!p.components;)u++;return u}),c=jt(()=>x.value.matched[s.value]);Wr(Ec,jt(()=>s.value+1)),Wr(O0,c),Wr(Ia,x);const o=mt();return In(()=>[o.value,c.value,r.name],([u,g,p],[n,i,a])=>{g&&(g.instances[p]=u,i&&i!==g&&u&&u===n&&(g.leaveGuards.size||(g.leaveGuards=i.leaveGuards),g.updateGuards.size||(g.updateGuards=i.updateGuards))),u&&g&&(!i||!wo(g,i)||!n)&&(g.enterCallbacks[p]||[]).forEach(h=>h(u))},{flush:"post"}),()=>{const u=x.value,g=r.name,p=c.value,n=p&&p.components[g];if(!n)return Cc(w.default,{Component:n,route:u});const i=p.props[g],a=i?i===!0?u.params:typeof i=="function"?i(u):i:null,m=rr(n,xt({},a,d,{onVnodeUnmounted:l=>{l.component.isUnmounted&&(p.instances[g]=null)},ref:o}));return Cc(w.default,{Component:m,route:u})||m}}});function Cc(r,d){if(!r)return null;const w=r(d);return w.length===1?w[0]:w}const th=D0;function F0(r){const d=x0(r.routes,r),w=r.parseQuery||M0,t=r.stringifyQuery||Sc,x=r.history,v=Fo(),s=Fo(),c=Fo(),o=Ko(Kr);let u=Kr;io&&r.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const g=Xi.bind(null,$=>""+$),p=Xi.bind(null,$v),n=Xi.bind(null,ns);function i($,J){let ne,ce;return Zf($)?(ne=d.getRecordMatcher($),ce=J):ce=$,d.addRoute(ce,ne)}function a($){const J=d.getRecordMatcher($);J&&d.removeRoute(J)}function h(){return d.getRoutes().map($=>$.record)}function m($){return!!d.getRecordMatcher($)}function l($,J){if(J=xt({},J||o.value),typeof $=="string"){const z=Yi(w,$,J.path),te=d.resolve({path:z.path},J),le=x.createHref(z.fullPath);return xt(z,te,{params:n(te.params),hash:ns(z.hash),redirectedFrom:void 0,href:le})}let ne;if($.path!=null)ne=xt({},$,{path:Yi(w,$.path,J.path).path});else{const z=xt({},$.params);for(const te in z)z[te]==null&&delete z[te];ne=xt({},$,{params:p(z)}),J.params=p(J.params)}const ce=d.resolve(ne,J),ie=$.hash||"";ce.params=g(n(ce.params));const pe=Qv(t,xt({},$,{hash:qv(ie),path:ce.path})),K=x.createHref(pe);return xt({fullPath:pe,hash:ie,query:t===Sc?C0($.query):$.query||{}},ce,{redirectedFrom:void 0,href:K})}function f($){return typeof $=="string"?Yi(w,$,o.value.path):xt({},$)}function y($,J){if(u!==$)return xo(8,{from:J,to:$})}function b($){return E($)}function j($){return b(xt(f($),{replace:!0}))}function k($){const J=$.matched[$.matched.length-1];if(J&&J.redirect){const{redirect:ne}=J;let ce=typeof ne=="function"?ne($):ne;return typeof ce=="string"&&(ce=ce.includes("?")||ce.includes("#")?ce=f(ce):{path:ce},ce.params={}),xt({query:$.query,hash:$.hash,params:ce.path!=null?{}:$.params},ce)}}function E($,J){const ne=u=l($),ce=o.value,ie=$.state,pe=$.force,K=$.replace===!0,z=k(ne);if(z)return E(xt(f(z),{state:typeof z=="object"?xt({},ie,z.state):ie,force:pe,replace:K}),J||ne);const te=ne;te.redirectedFrom=J;let le;return!pe&&Jv(t,ce,ne)&&(le=xo(16,{to:te,from:ce}),ee(ce,ce,!0,!1)),(le?Promise.resolve(le):L(te,ce)).catch(me=>fn(me)?fn(me,2)?me:Z(me):V(me,te,ce)).then(me=>{if(me){if(fn(me,2))return E(xt({replace:K},f(me.to),{state:typeof me.to=="object"?xt({},ie,me.to.state):ie,force:pe}),J||te)}else me=I(te,ce,!0,K,ie);return C(te,ce,me),me})}function M($,J){const ne=y($,J);return ne?Promise.reject(ne):Promise.resolve()}function P($){const J=D.values().next().value;return J&&typeof J.runWithContext=="function"?J.runWithContext($):$()}function L($,J){let ne;const[ce,ie,pe]=N0($,J);ne=$i(ce.reverse(),"beforeRouteLeave",$,J);for(const z of ce)z.leaveGuards.forEach(te=>{ne.push(Cn(te,$,J))});const K=M.bind(null,$,J);return ne.push(K),W(ne).then(()=>{ne=[];for(const z of v.list())ne.push(Cn(z,$,J));return ne.push(K),W(ne)}).then(()=>{ne=$i(ie,"beforeRouteUpdate",$,J);for(const z of ie)z.updateGuards.forEach(te=>{ne.push(Cn(te,$,J))});return ne.push(K),W(ne)}).then(()=>{ne=[];for(const z of pe)if(z.beforeEnter)if(Jr(z.beforeEnter))for(const te of z.beforeEnter)ne.push(Cn(te,$,J));else ne.push(Cn(z.beforeEnter,$,J));return ne.push(K),W(ne)}).then(()=>($.matched.forEach(z=>z.enterCallbacks={}),ne=$i(pe,"beforeRouteEnter",$,J,P),ne.push(K),W(ne))).then(()=>{ne=[];for(const z of s.list())ne.push(Cn(z,$,J));return ne.push(K),W(ne)}).catch(z=>fn(z,8)?z:Promise.reject(z))}function C($,J,ne){c.list().forEach(ce=>P(()=>ce($,J,ne)))}function I($,J,ne,ce,ie){const pe=y($,J);if(pe)return pe;const K=J===Kr,z=io?history.state:{};ne&&(ce||K?x.replace($.fullPath,xt({scroll:K&&z&&z.scroll},ie)):x.push($.fullPath,ie)),o.value=$,ee($,J,ne,K),Z()}let A;function N(){A||(A=x.listen(($,J,ne)=>{if(!G.listening)return;const ce=l($),ie=k(ce);if(ie){E(xt(ie,{replace:!0}),ce).catch(qo);return}u=ce;const pe=o.value;io&&a0(yc(pe.fullPath,ne.delta),bi()),L(ce,pe).catch(K=>fn(K,12)?K:fn(K,2)?(E(K.to,ce).then(z=>{fn(z,20)&&!ne.delta&&ne.type===os.pop&&x.go(-1,!1)}).catch(qo),Promise.reject()):(ne.delta&&x.go(-ne.delta,!1),V(K,ce,pe))).then(K=>{K=K||I(ce,pe,!1),K&&(ne.delta&&!fn(K,8)?x.go(-ne.delta,!1):ne.type===os.pop&&fn(K,20)&&x.go(-1,!1)),C(ce,pe,K)}).catch(qo)}))}let F=Fo(),B=Fo(),q;function V($,J,ne){Z($);const ce=B.list();return ce.length?ce.forEach(ie=>ie($,J,ne)):console.error($),Promise.reject($)}function H(){return q&&o.value!==Kr?Promise.resolve():new Promise(($,J)=>{F.add([$,J])})}function Z($){return q||(q=!$,N(),F.list().forEach(([J,ne])=>$?ne($):J()),F.reset()),$}function ee($,J,ne,ce){const{scrollBehavior:ie}=r;if(!io||!ie)return Promise.resolve();const pe=!ne&&l0(yc($.fullPath,0))||(ce||!ne)&&history.state&&history.state.scroll||null;return Fr().then(()=>ie($,J,pe)).then(K=>K&&i0(K)).catch(K=>V(K,$,J))}const ue=$=>x.go($);let T;const D=new Set,G={currentRoute:o,listening:!0,addRoute:i,removeRoute:a,hasRoute:m,getRoutes:h,resolve:l,options:r,push:b,replace:j,go:ue,back:()=>ue(-1),forward:()=>ue(1),beforeEach:v.add,beforeResolve:s.add,afterEach:c.add,onError:B.add,isReady:H,install($){const J=this;$.component("RouterLink",R0),$.component("RouterView",th),$.config.globalProperties.$router=J,Object.defineProperty($.config.globalProperties,"$route",{enumerable:!0,get:()=>Bt(o)}),io&&!T&&o.value===Kr&&(T=!0,b(x.location).catch(ie=>{}));const ne={};for(const ie in Kr)Object.defineProperty(ne,ie,{get:()=>o.value[ie],enumerable:!0});$.provide(gl,J),$.provide(vl,as(ne)),$.provide(Ia,o);const ce=$.unmount;D.add($),$.unmount=function(){D.delete($),D.size<1&&(u=Kr,A&&A(),A=null,o.value=Kr,T=!1,q=!1),ce()}}};function W($){return $.reduce((J,ne)=>J.then(()=>P(ne)),Promise.resolve())}return G}function N0(r,d){const w=[],t=[],x=[],v=Math.max(d.matched.length,r.matched.length);for(let s=0;swo(u,c))?t.push(c):w.push(c));const o=r.matched[s];o&&(d.matched.find(u=>wo(u,o))||x.push(o))}return[w,t,x]}function U0(){return Ht(vl)}const B0=(r,d)=>d.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,w=>{var t;return((t=r.params[w.slice(1)])==null?void 0:t.toString())||""}),Da=(r,d)=>{const w=r.route.matched.find(x=>{var v;return((v=x.components)==null?void 0:v.default)===r.Component.type}),t=d??(w==null?void 0:w.meta.key)??(w&&B0(r.route,w));return typeof t=="function"?t(r.route):t},G0=(r,d)=>({default:()=>r?rr(gm,r===!0?{}:r,d):d});function bl(r){return Array.isArray(r)?r:[r]}const V0="modulepreload",H0=function(r,d){return r[0]==="."?new URL(r,d).href:r},Oc={},z0=function(d,w,t){let x=Promise.resolve();if(w&&w.length>0){const v=document.getElementsByTagName("link"),s=document.querySelector("meta[property=csp-nonce]"),c=(s==null?void 0:s.nonce)||(s==null?void 0:s.getAttribute("nonce"));x=Promise.all(w.map(o=>{if(o=H0(o,t),o in Oc)return;Oc[o]=!0;const u=o.endsWith(".css"),g=u?'[rel="stylesheet"]':"";if(!!t)for(let i=v.length-1;i>=0;i--){const a=v[i];if(a.href===o&&(!u||a.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${o}"]${g}`))return;const n=document.createElement("link");if(n.rel=u?"stylesheet":V0,u||(n.as="script",n.crossOrigin=""),n.href=o,c&&n.setAttribute("nonce",c),document.head.appendChild(n),u)return new Promise((i,a)=>{n.addEventListener("load",i),n.addEventListener("error",()=>a(new Error(`Unable to preload CSS for ${o}`)))})}))}return x.then(()=>d()).catch(v=>{const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=v,window.dispatchEvent(s),!s.defaultPrevented)throw v})},rt=(...r)=>z0(...r).catch(d=>{const w=new Event("nuxt.preloadError");throw w.payload=d,window.dispatchEvent(w),d}),Ki=null,Zi=null,wr={layout:"empty"},Qi=null,Ji=null,ea=null,xr={layout:"light"},jr={layout:"light"},Sr={layout:"light"},ta=null,Er={layout:"light"},Tr={layout:"light"},kr={layout:"light"},Mr={layout:"light"},Cr={layout:"light"},Or={layout:"light"},Pr={layout:"light"},Ar={layout:"light"},Pc=[{name:"articles-slug",path:"/articles/:slug(.*)*",meta:{},alias:[],redirect:Ki==null?void 0:Ki.redirect,component:()=>rt(()=>import("./3-SVqsS-.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8]),import.meta.url).then(r=>r.default||r)},{name:"articles",path:"/articles",meta:{},alias:[],redirect:Zi==null?void 0:Zi.redirect,component:()=>rt(()=>import("./CkwidRNk.js"),__vite__mapDeps([9,1,2,3,4,5,7]),import.meta.url).then(r=>r.default||r)},{name:(wr==null?void 0:wr.name)??"card",path:(wr==null?void 0:wr.path)??"/card",meta:wr||{},alias:(wr==null?void 0:wr.alias)||[],redirect:wr==null?void 0:wr.redirect,component:()=>rt(()=>import("./tdBs6IZL.js"),[],import.meta.url).then(r=>r.default||r)},{name:"examples-nested_transitions",path:"/examples/nested_transitions",meta:{},alias:[],redirect:Qi==null?void 0:Qi.redirect,component:()=>rt(()=>import("./B3vgOLG7.js"),[],import.meta.url).then(r=>r.default||r)},{name:"index",path:"/",meta:{},alias:[],redirect:Ji==null?void 0:Ji.redirect,component:()=>rt(()=>import("./DQRguPdo.js"),__vite__mapDeps([10,11,7,4,3]),import.meta.url).then(r=>r.default||r)},{name:"playground-audio",path:"/playground/audio",meta:{},alias:[],redirect:ea==null?void 0:ea.redirect,component:()=>rt(()=>import("./DbZb_TqQ.js"),[],import.meta.url).then(r=>r.default||r)},{name:(xr==null?void 0:xr.name)??"playground-chords",path:(xr==null?void 0:xr.path)??"/playground/chords",meta:xr||{},alias:(xr==null?void 0:xr.alias)||[],redirect:xr==null?void 0:xr.redirect,component:()=>rt(()=>import("./CeNIwOQb.js"),[],import.meta.url).then(r=>r.default||r)},{name:(jr==null?void 0:jr.name)??"playground-conway",path:(jr==null?void 0:jr.path)??"/playground/conway",meta:jr||{},alias:(jr==null?void 0:jr.alias)||[],redirect:jr==null?void 0:jr.redirect,component:()=>rt(()=>import("./C8Cf_uay.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Sr==null?void 0:Sr.name)??"playground-french",path:(Sr==null?void 0:Sr.path)??"/playground/french",meta:Sr||{},alias:(Sr==null?void 0:Sr.alias)||[],redirect:Sr==null?void 0:Sr.redirect,component:()=>rt(()=>import("./wZXg-9-z.js"),__vite__mapDeps([12,4,6]),import.meta.url).then(r=>r.default||r)},{name:"playground",path:"/playground",meta:{},alias:[],redirect:ta==null?void 0:ta.redirect,component:()=>rt(()=>import("./Drhxu60M.js"),__vite__mapDeps([13,11]),import.meta.url).then(r=>r.default||r)},{name:(Er==null?void 0:Er.name)??"playground-matrix",path:(Er==null?void 0:Er.path)??"/playground/matrix",meta:Er||{},alias:(Er==null?void 0:Er.alias)||[],redirect:Er==null?void 0:Er.redirect,component:()=>rt(()=>import("./C8bARUYD.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Tr==null?void 0:Tr.name)??"playground-metronome",path:(Tr==null?void 0:Tr.path)??"/playground/metronome",meta:Tr||{},alias:(Tr==null?void 0:Tr.alias)||[],redirect:Tr==null?void 0:Tr.redirect,component:()=>rt(()=>import("./EoZQkp_H.js"),[],import.meta.url).then(r=>r.default||r)},{name:(kr==null?void 0:kr.name)??"playground-midi",path:(kr==null?void 0:kr.path)??"/playground/midi",meta:kr||{},alias:(kr==null?void 0:kr.alias)||[],redirect:kr==null?void 0:kr.redirect,component:()=>rt(()=>import("./CwYjkwfo.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Mr==null?void 0:Mr.name)??"playground-palettes-mountains",path:(Mr==null?void 0:Mr.path)??"/playground/palettes/mountains",meta:Mr||{},alias:(Mr==null?void 0:Mr.alias)||[],redirect:Mr==null?void 0:Mr.redirect,component:()=>rt(()=>import("./C9mKha9k.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Cr==null?void 0:Cr.name)??"playground-palettes-variance",path:(Cr==null?void 0:Cr.path)??"/playground/palettes/variance",meta:Cr||{},alias:(Cr==null?void 0:Cr.alias)||[],redirect:Cr==null?void 0:Cr.redirect,component:()=>rt(()=>import("./avmke64t.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Or==null?void 0:Or.name)??"playground-plotter",path:(Or==null?void 0:Or.path)??"/playground/plotter",meta:Or||{},alias:(Or==null?void 0:Or.alias)||[],redirect:Or==null?void 0:Or.redirect,component:()=>rt(()=>import("./DxVn7wJS.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Pr==null?void 0:Pr.name)??"playground-tiling",path:(Pr==null?void 0:Pr.path)??"/playground/tiling",meta:Pr||{},alias:(Pr==null?void 0:Pr.alias)||[],redirect:Pr==null?void 0:Pr.redirect,component:()=>rt(()=>import("./oGJ4KIAb.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Ar==null?void 0:Ar.name)??"playground-waves",path:(Ar==null?void 0:Ar.path)??"/playground/waves",meta:Ar||{},alias:(Ar==null?void 0:Ar.alias)||[],redirect:Ar==null?void 0:Ar.redirect,component:()=>rt(()=>import("./CCipQ263.js"),[],import.meta.url).then(r=>r.default||r)}],rh=(r,d,w)=>(d=d===!0?{}:d,{default:()=>{var t;return d?rr(r,d,w):(t=w.default)==null?void 0:t.call(w)}});function Ac(r){const d=(r==null?void 0:r.meta.key)??r.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,w=>{var t;return((t=r.params[w.slice(1)])==null?void 0:t.toString())||""});return typeof d=="function"?d(r):d}function W0(r,d){return r===d||d===Kr?!1:Ac(r)!==Ac(d)?!0:!r.matched.every((t,x)=>{var v,s;return t.components&&t.components.default===((s=(v=d.matched[x])==null?void 0:v.components)==null?void 0:s.default)})}const q0={scrollBehavior(r,d,w){var u;const t=It(),x=((u=qr().options)==null?void 0:u.scrollBehaviorType)??"auto";let v=w||void 0;const s=typeof r.meta.scrollToTop=="function"?r.meta.scrollToTop(r,d):r.meta.scrollToTop;if(!v&&d&&r&&s!==!1&&W0(r,d)&&(v={left:0,top:0}),r.path===d.path)return d.hash&&!r.hash?{left:0,top:0}:r.hash?{el:r.hash,top:Rc(r.hash),behavior:x}:!1;const c=g=>!!(g.meta.pageTransition??Aa),o=c(d)&&c(r)?"page:transition:finish":"page:finish";return new Promise(g=>{t.hooks.hookOnce(o,async()=>{await new Promise(p=>setTimeout(p,0)),r.hash&&(v={el:r.hash,top:Rc(r.hash),behavior:x}),g(v)})})}};function Rc(r){try{const d=document.querySelector(r);if(d)return parseFloat(getComputedStyle(d).scrollMarginTop)}catch{}return 0}const X0={hashMode:!1,scrollBehaviorType:"auto"},Rr={...X0,...q0},Y0=async r=>{var o;let d,w;if(!((o=r.meta)!=null&&o.validate))return;const t=It(),x=qr();if(([d,w]=rs(()=>Promise.resolve(r.meta.validate(r))),d=await d,w(),d)===!0)return;const s=gi({statusCode:404,statusMessage:`Page Not Found: ${r.fullPath}`,data:{path:r.fullPath}}),c=x.beforeResolve(u=>{if(c(),u===r){const g=x.afterEach(async()=>{g(),await t.runWithContext(()=>lo(s)),window.history.pushState({},"",r.fullPath)});return!1}})},$0=async r=>{let d,w;const t=([d,w]=rs(()=>ml(r.path)),d=await d,w(),d);if(t.redirect)return gn(t.redirect,{acceptRelative:!0})?(window.location.href=t.redirect,!1):t.redirect},K0=[Y0,$0],Yo={};function Z0(r,d,w){const{pathname:t,search:x,hash:v}=d,s=r.indexOf("#");if(s>-1){const u=v.includes(r.slice(s))?r.slice(s).length:1;let g=v.slice(u);return g[0]!=="/"&&(g="/"+g),Ju(g,"")}const c=Ju(t,r),o=!w||Iy(c,w,{trailingSlash:!0})?c:w;return o+(o.includes("?")?"":x)+v}const Q0=vn({name:"nuxt:router",enforce:"pre",async setup(r){var m,l;let d,w,t=pi().app.baseURL;Rr.hashMode&&!t.includes("#")&&(t+="#");const x=((m=Rr.history)==null?void 0:m.call(Rr,t))??(Rr.hashMode?f0(t):Kf(t)),v=((l=Rr.routes)==null?void 0:l.call(Rr,Pc))??Pc;let s;const c=F0({...Rr,scrollBehavior:(f,y,b)=>{if(y===Kr){s=b;return}if(Rr.scrollBehavior){if(c.options.scrollBehavior=Rr.scrollBehavior,"scrollRestoration"in window.history){const j=c.beforeEach(()=>{j(),window.history.scrollRestoration="manual"})}return Rr.scrollBehavior(f,Kr,s||b)}},history:x,routes:v});"scrollRestoration"in window.history&&(window.history.scrollRestoration="auto"),r.vueApp.use(c);const o=Ko(c.currentRoute.value);c.afterEach((f,y)=>{o.value=y}),Object.defineProperty(r.vueApp.config.globalProperties,"previousRoute",{get:()=>o.value});const u=Z0(t,window.location,r.payload.path),g=Ko(c.currentRoute.value),p=()=>{g.value=c.currentRoute.value};r.hook("page:finish",p),c.afterEach((f,y)=>{var b,j,k,E;((j=(b=f.matched[0])==null?void 0:b.components)==null?void 0:j.default)===((E=(k=y.matched[0])==null?void 0:k.components)==null?void 0:E.default)&&p()});const n={};for(const f in g.value)Object.defineProperty(n,f,{get:()=>g.value[f]});r._route=as(n),r._middleware=r._middleware||{global:[],named:{}};try{[d,w]=rs(()=>c.isReady()),await d,w()}catch(f){[d,w]=rs(()=>r.runWithContext(()=>lo(f))),await d,w()}const i=u!==c.currentRoute.value.fullPath?c.resolve(u):c.currentRoute.value;p();const a=r.payload.state._layout;c.beforeEach(async(f,y)=>{var b;await r.callHook("page:loading:start"),f.meta=Un(f.meta),r.isHydrating&&a&&!go(f.meta.layout)&&(f.meta.layout=a),r._processingMiddleware=!0;{const j=new Set([...K0,...r._middleware.global]);for(const k of f.matched){const E=k.meta.middleware;if(E)for(const M of bl(E))j.add(M)}{const k=await r.runWithContext(()=>ml(f.path));if(k.appMiddleware)for(const E in k.appMiddleware)k.appMiddleware[E]?j.add(E):j.delete(E)}for(const k of j){const E=typeof k=="string"?r._middleware.named[k]||await((b=Yo[k])==null?void 0:b.call(Yo).then(P=>P.default||P)):k;if(!E)throw new Error(`Unknown route middleware: '${k}'.`);const M=await r.runWithContext(()=>E(f,y));if(!r.payload.serverRendered&&r.isHydrating&&(M===!1||M instanceof Error)){const P=M||ka({statusCode:404,statusMessage:`Page Not Found: ${u}`});return await r.runWithContext(()=>lo(P)),!1}if(M!==!0&&(M||M===!1))return M}}}),c.onError(async()=>{delete r._processingMiddleware,await r.callHook("page:loading:end")});const h=yi();return c.afterEach(async(f,y,b)=>{delete r._processingMiddleware,!r.isHydrating&&h.value&&await r.runWithContext(Tg),b&&await r.callHook("page:loading:end"),f.matched.length===0&&await r.runWithContext(()=>lo(ka({statusCode:404,fatal:!1,statusMessage:`Page not found: ${f.fullPath}`,data:{path:f.fullPath}})))}),r.hooks.hookOnce("app:created",async()=>{try{"name"in i&&(i.name=void 0),await c.replace({...i,force:!0}),c.options.scrollBehavior=Rr.scrollBehavior}catch(f){await r.runWithContext(()=>lo(f))}}),{provide:{router:c}}}}),Fa=globalThis.requestIdleCallback||(r=>{const d=Date.now(),w={didTimeout:!1,timeRemaining:()=>Math.max(0,50-(Date.now()-d))};return setTimeout(()=>{r(w)},1)}),J0=globalThis.cancelIdleCallback||(r=>{clearTimeout(r)}),_l=r=>{const d=It();d.isHydrating?d.hooks.hookOnce("app:suspense:resolve",()=>{Fa(r)}):Fa(r)},eb=vn({name:"nuxt:payload",setup(r){qr().beforeResolve(async(d,w)=>{if(d.path===w.path)return;const t=await fc(d.path);t&&Object.assign(r.static.data,t.data)}),_l(()=>{var d;r.hooks.hook("link:prefetch",async w=>{hs(w).protocol||await fc(w)}),((d=navigator.connection)==null?void 0:d.effectiveType)!=="slow-2g"&&setTimeout(vi,1e3)})}}),tb=vn(r=>{let d;async function w(){const t=await vi();d&&clearTimeout(d),d=setTimeout(w,1e3*60*60);try{const x=await $fetch(dl("builds/latest.json")+`?${Date.now()}`);x.id!==t.id&&r.hooks.callHook("app:manifest:update",x)}catch{}}_l(()=>{d=setTimeout(w,1e3*60*60)})}),rb=ft(()=>rt(()=>import("./DGUXyVWA.js"),__vite__mapDeps([14,5,1,2,3,4,15,6,7]),import.meta.url).then(r=>r.default||r.default||r)),nb=ft(()=>rt(()=>import("./B_2hsy3K.js"),__vite__mapDeps([16,15,6,7,4,3]),import.meta.url).then(r=>r.default||r.default||r)),ob=ft(()=>rt(()=>import("./CzWl7KmD.js"),__vite__mapDeps([17,6,4,7,3]),import.meta.url).then(r=>r.default||r.default||r)),sb=ft(()=>rt(()=>import("./BTH0oiOj.js"),__vite__mapDeps([15,6,7,4,3]),import.meta.url).then(r=>r.default||r.default||r)),ib=ft(()=>rt(()=>import("./BLy52rwp.js"),__vite__mapDeps([5,1,2,3,4]),import.meta.url).then(r=>r.default||r.default||r)),ab=ft(()=>rt(()=>import("./qnKzmL5n.js"),__vite__mapDeps([18,1,2,3,4]),import.meta.url).then(r=>r.default||r.default||r)),lb=ft(()=>rt(()=>import("./DHgolSFm.js"),[],import.meta.url).then(r=>r.default||r.default||r)),ub=ft(()=>rt(()=>import("./KkmkYs8s.js"),[],import.meta.url).then(r=>r.default||r.default||r)),cb=ft(()=>rt(()=>import("./BNjek0E5.js"),[],import.meta.url).then(r=>r.default||r.default||r)),db=ft(()=>rt(()=>import("./DZjQgdbh.js"),__vite__mapDeps([19,20]),import.meta.url).then(r=>r.default||r.default||r)),fb=ft(()=>rt(()=>import("./DQnJMeWU.js"),__vite__mapDeps([21,22,23]),import.meta.url).then(r=>r.default||r.default||r)),hb=ft(()=>rt(()=>import("./CsmMkizg.js"),[],import.meta.url).then(r=>r.default||r.default||r)),pb=ft(()=>rt(()=>import("./Da1yACaU.js"),__vite__mapDeps([24,22,23]),import.meta.url).then(r=>r.default||r.default||r)),mb=ft(()=>rt(()=>import("./C97JLsMV.js"),[],import.meta.url).then(r=>r.default||r.default||r)),yb=ft(()=>rt(()=>import("./B7vccJE6.js"),[],import.meta.url).then(r=>r.default||r.default||r)),gb=ft(()=>rt(()=>import("./Cw7Lqm3I.js"),[],import.meta.url).then(r=>r.default||r.default||r)),vb=ft(()=>rt(()=>import("./DmPqpNC_.js"),[],import.meta.url).then(r=>r.default||r.default||r)),bb=ft(()=>rt(()=>import("./D23fXkMy.js"),[],import.meta.url).then(r=>r.default||r.default||r)),_b=ft(()=>rt(()=>import("./DyabY-Dr.js"),[],import.meta.url).then(r=>r.default||r.default||r)),wb=ft(()=>rt(()=>import("./OhHb1YIJ.js"),[],import.meta.url).then(r=>r.default||r.default||r)),xb=ft(()=>rt(()=>import("./B4L3tEQJ.js"),[],import.meta.url).then(r=>r.default||r.default||r)),jb=ft(()=>rt(()=>import("./BKNGoZSq.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Sb=ft(()=>rt(()=>import("./Clp480GU.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Eb=ft(()=>rt(()=>import("./CcZdBpHY.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Tb=ft(()=>rt(()=>import("./mVZnioK0.js"),[],import.meta.url).then(r=>r.default||r.default||r)),kb=ft(()=>rt(()=>import("./CN6FzLjO.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Mb=ft(()=>rt(()=>import("./B_oFiJGZ.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Cb=ft(()=>rt(()=>import("./igSZO63y.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ob=ft(()=>rt(()=>import("./BzUOsEDD.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Pb=ft(()=>rt(()=>import("./DC0DmFcz.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ab=ft(()=>rt(()=>import("./C1UWh-7Q.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Rb=ft(()=>rt(()=>import("./BQ_EhnmX.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Lb=ft(()=>rt(()=>import("./CUFuiolx.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ib=ft(()=>rt(()=>import("./DyDTWd_r.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Db=ft(()=>rt(()=>import("./ChVNnOb8.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Fb=ft(()=>rt(()=>import("./CZMejQjK.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Nb=[["ContentDoc",rb],["ContentList",nb],["ContentNavigation",ob],["ContentQuery",sb],["ContentRenderer",ib],["ContentRendererMarkdown",ab],["MDCSlot",lb],["DocumentDrivenEmpty",ub],["DocumentDrivenNotFound",cb],["Markdown",db],["ProseCode",fb],["ProseCodeInline",hb],["ProsePre",pb],["ProseA",mb],["ProseBlockquote",yb],["ProseEm",gb],["ProseH1",vb],["ProseH2",bb],["ProseH3",_b],["ProseH4",wb],["ProseH5",xb],["ProseH6",jb],["ProseHr",Sb],["ProseImg",Eb],["ProseLi",Tb],["ProseOl",kb],["ProseP",Mb],["ProseScript",Cb],["ProseStrong",Ob],["ProseTable",Pb],["ProseTbody",Ab],["ProseTd",Rb],["ProseTh",Lb],["ProseThead",Ib],["ProseTr",Db],["ProseUl",Fb]],Ub=vn({name:"nuxt:global-components",setup(r){for(const[d,w]of Nb)r.vueApp.component(d,w),r.vueApp.component("Lazy"+d,w)}}),Pn={default:()=>rt(()=>import("./TpgFGTwW.js"),[],import.meta.url).then(r=>r.default||r),empty:()=>rt(()=>import("./DFlUAqO6.js"),[],import.meta.url).then(r=>r.default||r),light:()=>rt(()=>import("./CjCPfpaE.js"),[],import.meta.url).then(r=>r.default||r)},Bb=vn({name:"nuxt:prefetch",setup(r){const d=qr();r.hooks.hook("app:mounted",()=>{d.beforeEach(async w=>{var x;const t=(x=w==null?void 0:w.meta)==null?void 0:x.layout;t&&typeof Pn[t]=="function"&&await Pn[t]()})}),r.hooks.hook("link:prefetch",w=>{if(gn(w))return;const t=d.resolve(w);if(!t)return;const x=t.meta.layout;let v=bl(t.meta.middleware);v=v.filter(s=>typeof s=="string");for(const s of v)typeof Yo[s]=="function"&&Yo[s]();x&&typeof Pn[x]=="function"&&Pn[x]()})}});function Gb(r={}){const d=r.path||window.location.pathname;let w={};try{w=Ks(sessionStorage.getItem("nuxt:reload")||"{}")}catch{}if(r.force||(w==null?void 0:w.path)!==d||(w==null?void 0:w.expires){t.clear()}),r.hook("app:chunkError",({error:v})=>{t.add(v)});function x(v){const c="href"in v&&v.href[0]==="#"?w.app.baseURL+v.href:hi(w.app.baseURL,v.fullPath);Gb({path:c,persistState:!0})}r.hook("app:manifest:update",()=>{d.beforeResolve(x)}),d.onError((v,s)=>{t.has(v)&&x(s)})}});var Rs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Hb(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function Ls(r){throw new Error('Could not dynamically require "'+r+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var nh={exports:{}};/*! p5.js v1.9.4 May 21, 2024 */(function(r,d){(function(w){r.exports=w()})(function(){var w;return function t(x,v,s){function c(g,p){if(!v[g]){if(!x[g]){var n=typeof Ls=="function"&&Ls;if(!p&&n)return n(g,!0);if(o)return o(g,!0);throw(p=new Error("Cannot find module '"+g+"'")).code="MODULE_NOT_FOUND",p}n=v[g]={exports:{}},x[g][0].call(n.exports,function(i){return c(x[g][1][i]||i)},n,n.exports,t,x,v,s)}return v[g].exports}for(var o=typeof Ls=="function"&&Ls,u=0;u>16&255,f[y++]=a>>8&255,f[y++]=255&a;return l===2&&(a=c[i.charCodeAt(h)]<<2|c[i.charCodeAt(h+1)]>>4,f[y++]=255&a),l===1&&(a=c[i.charCodeAt(h)]<<10|c[i.charCodeAt(h+1)]<<4|c[i.charCodeAt(h+2)]>>2,f[y++]=a>>8&255,f[y++]=255&a),f},v.fromByteArray=function(i){for(var a,h=i.length,m=h%3,l=[],f=0,y=h-m;f>18&63]+s[L>>12&63]+s[L>>6&63]+s[63&L]}(E));return M.join("")}(i,f,y>2]+s[a<<4&63]+"==")):m==2&&(a=(i[h-2]<<8)+i[h-1],l.push(s[a>>10]+s[a>>4&63]+s[a<<2&63]+"=")),l.join("")};for(var s=[],c=[],o=typeof Uint8Array<"u"?Uint8Array:Array,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g=0,p=u.length;g>>1;case"base64":return V(T).length;default:if($)return W?-1:q(T).length;D=(""+D).toLowerCase(),$=!0}}function y(T,D,G){var W,$=!1;if((D=D===void 0||D<0?0:D)>this.length||(G=G===void 0||G>this.length?this.length:G)<=0||(G>>>=0)<=(D>>>=0))return"";for(T=T||"utf8";;)switch(T){case"hex":var J=this,de=D,ne=G,K=J.length;(!ne||ne<0||K=T.length){if($)return-1;G=T.length-1}else if(G<0){if(!$)return-1;G=0}if(typeof D=="string"&&(D=n.from(D,W)),n.isBuffer(D))return D.length===0?-1:k(T,D,G,W,$);if(typeof D=="number")return D&=255,typeof Uint8Array.prototype.indexOf=="function"?($?Uint8Array.prototype.indexOf:Uint8Array.prototype.lastIndexOf).call(T,D,G):k(T,[D],G,W,$);throw new TypeError("val must be string, number or Buffer")}function k(T,D,G,W,$){var J=1,ne=T.length,ce=D.length;if(W!==void 0&&((W=String(W).toLowerCase())==="ucs2"||W==="ucs-2"||W==="utf16le"||W==="utf-16le")){if(T.length<2||D.length<2)return-1;ne/=J=2,ce/=2,G/=2}function ie(le,me){return J===1?le[me]:le.readUInt16BE(me*J)}if($)for(var pe=-1,K=G;K>8,ce=ce%256,ie.push(ce),ie.push(ne);return ie}(D,T.length-G),T,G,W)}function P(T,D,G){G=Math.min(T.length,G);for(var W=[],$=D;$>>10&1023|55296),K=56320|1023&K),W.push(K),$+=z}var te=W,le=te.length;if(le<=L)return String.fromCharCode.apply(String,te);for(var me="",de=0;de"u"||typeof console.error!="function"||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(n.prototype,"parent",{enumerable:!0,get:function(){if(n.isBuffer(this))return this.buffer}}),Object.defineProperty(n.prototype,"offset",{enumerable:!0,get:function(){if(n.isBuffer(this))return this.byteOffset}}),typeof Symbol<"u"&&Symbol.species!=null&&n[Symbol.species]===n&&Object.defineProperty(n,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),n.poolSize=8192,n.from=i,Object.setPrototypeOf(n.prototype,Uint8Array.prototype),Object.setPrototypeOf(n,Uint8Array),n.alloc=function(T,D,G){return D=D,G=G,a(T=T),!(T<=0)&&D!==void 0?typeof G=="string"?p(T).fill(D,G):p(T).fill(D):p(T)},n.allocUnsafe=h,n.allocUnsafeSlow=h,n.isBuffer=function(T){return T!=null&&T._isBuffer===!0&&T!==n.prototype},n.compare=function(T,D){if(Z(T,Uint8Array)&&(T=n.from(T,T.offset,T.byteLength)),Z(D,Uint8Array)&&(D=n.from(D,D.offset,D.byteLength)),!n.isBuffer(T)||!n.isBuffer(D))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(T===D)return 0;for(var G=T.length,W=D.length,$=0,J=Math.min(G,W);$T&&(D+=" ... "),""},u&&(n.prototype[u]=n.prototype.inspect),n.prototype.compare=function(T,D,G,W,$){if(Z(T,Uint8Array)&&(T=n.from(T,T.offset,T.byteLength)),!n.isBuffer(T))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof T);if(G===void 0&&(G=T?T.length:0),W===void 0&&(W=0),$===void 0&&($=this.length),(D=D===void 0?0:D)<0||G>T.length||W<0||$>this.length)throw new RangeError("out of range index");if($<=W&&G<=D)return 0;if($<=W)return-1;if(G<=D)return 1;if(this===T)return 0;for(var J=($>>>=0)-(W>>>=0),ne=(G>>>=0)-(D>>>=0),ce=Math.min(J,ne),ie=this.slice(W,$),pe=T.slice(D,G),K=0;K>>=0,isFinite(G)?(G>>>=0,W===void 0&&(W="utf8")):(W=G,G=void 0)}var $=this.length-D;if((G===void 0||$this.length)throw new RangeError("Attempt to write outside buffer bounds");W=W||"utf8";for(var J,ne,ce,ie=!1;;)switch(W){case"hex":var pe=this,K=T,z=D,te=G,le=(z=Number(z)||0,pe.length-z);(!te||le<(te=Number(te)))&&(te=le),(le=K.length)/2T.length)throw new RangeError("Index out of range")}function A(T,D,G,W){if(G+W>T.length)throw new RangeError("Index out of range");if(G<0)throw new RangeError("Index out of range")}function N(T,D,G,W,$){return D=+D,G>>>=0,$||A(T,0,G,4),o.write(T,D,G,W,23,4),G+4}function F(T,D,G,W,$){return D=+D,G>>>=0,$||A(T,0,G,8),o.write(T,D,G,W,52,8),G+8}n.prototype.slice=function(T,D){var G=this.length,G=((T=~~T)<0?(T+=G)<0&&(T=0):G>>=0,D>>>=0,G||C(T,D,this.length);for(var W=this[T],$=1,J=0;++J>>=0,D>>>=0,G||C(T,D,this.length);for(var W=this[T+--D],$=1;0>>=0,D||C(T,1,this.length),this[T]},n.prototype.readUInt16LE=function(T,D){return T>>>=0,D||C(T,2,this.length),this[T]|this[T+1]<<8},n.prototype.readUInt16BE=function(T,D){return T>>>=0,D||C(T,2,this.length),this[T]<<8|this[T+1]},n.prototype.readUInt32LE=function(T,D){return T>>>=0,D||C(T,4,this.length),(this[T]|this[T+1]<<8|this[T+2]<<16)+16777216*this[T+3]},n.prototype.readUInt32BE=function(T,D){return T>>>=0,D||C(T,4,this.length),16777216*this[T]+(this[T+1]<<16|this[T+2]<<8|this[T+3])},n.prototype.readIntLE=function(T,D,G){T>>>=0,D>>>=0,G||C(T,D,this.length);for(var W=this[T],$=1,J=0;++J>>=0,D>>>=0,G||C(T,D,this.length);for(var W=D,$=1,J=this[T+--W];0>>=0,D||C(T,1,this.length),128&this[T]?-1*(255-this[T]+1):this[T]},n.prototype.readInt16LE=function(T,D){return T>>>=0,D||C(T,2,this.length),D=this[T]|this[T+1]<<8,32768&D?4294901760|D:D},n.prototype.readInt16BE=function(T,D){return T>>>=0,D||C(T,2,this.length),D=this[T+1]|this[T]<<8,32768&D?4294901760|D:D},n.prototype.readInt32LE=function(T,D){return T>>>=0,D||C(T,4,this.length),this[T]|this[T+1]<<8|this[T+2]<<16|this[T+3]<<24},n.prototype.readInt32BE=function(T,D){return T>>>=0,D||C(T,4,this.length),this[T]<<24|this[T+1]<<16|this[T+2]<<8|this[T+3]},n.prototype.readFloatLE=function(T,D){return T>>>=0,D||C(T,4,this.length),o.read(this,T,!0,23,4)},n.prototype.readFloatBE=function(T,D){return T>>>=0,D||C(T,4,this.length),o.read(this,T,!1,23,4)},n.prototype.readDoubleLE=function(T,D){return T>>>=0,D||C(T,8,this.length),o.read(this,T,!0,52,8)},n.prototype.readDoubleBE=function(T,D){return T>>>=0,D||C(T,8,this.length),o.read(this,T,!1,52,8)},n.prototype.writeUIntLE=function(T,D,G,W){T=+T,D>>>=0,G>>>=0,W||I(this,T,D,G,Math.pow(2,8*G)-1,0);var $=1,J=0;for(this[D]=255&T;++J>>=0,G>>>=0,W||I(this,T,D,G,Math.pow(2,8*G)-1,0);var $=G-1,J=1;for(this[D+$]=255&T;0<=--$&&(J*=256);)this[D+$]=T/J&255;return D+G},n.prototype.writeUInt8=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,1,255,0),this[D]=255&T,D+1},n.prototype.writeUInt16LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,65535,0),this[D]=255&T,this[D+1]=T>>>8,D+2},n.prototype.writeUInt16BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,65535,0),this[D]=T>>>8,this[D+1]=255&T,D+2},n.prototype.writeUInt32LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,4294967295,0),this[D+3]=T>>>24,this[D+2]=T>>>16,this[D+1]=T>>>8,this[D]=255&T,D+4},n.prototype.writeUInt32BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,4294967295,0),this[D]=T>>>24,this[D+1]=T>>>16,this[D+2]=T>>>8,this[D+3]=255&T,D+4},n.prototype.writeIntLE=function(T,D,G,W){T=+T,D>>>=0,W||I(this,T,D,G,(W=Math.pow(2,8*G-1))-1,-W);var $=0,J=1,ne=0;for(this[D]=255&T;++$>0)-ne&255;return D+G},n.prototype.writeIntBE=function(T,D,G,W){T=+T,D>>>=0,W||I(this,T,D,G,(W=Math.pow(2,8*G-1))-1,-W);var $=G-1,J=1,ne=0;for(this[D+$]=255&T;0<=--$&&(J*=256);)T<0&&ne===0&&this[D+$+1]!==0&&(ne=1),this[D+$]=(T/J>>0)-ne&255;return D+G},n.prototype.writeInt8=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,1,127,-128),this[D]=255&(T=T<0?255+T+1:T),D+1},n.prototype.writeInt16LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,32767,-32768),this[D]=255&T,this[D+1]=T>>>8,D+2},n.prototype.writeInt16BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,32767,-32768),this[D]=T>>>8,this[D+1]=255&T,D+2},n.prototype.writeInt32LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,2147483647,-2147483648),this[D]=255&T,this[D+1]=T>>>8,this[D+2]=T>>>16,this[D+3]=T>>>24,D+4},n.prototype.writeInt32BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,2147483647,-2147483648),this[D]=(T=T<0?4294967295+T+1:T)>>>24,this[D+1]=T>>>16,this[D+2]=T>>>8,this[D+3]=255&T,D+4},n.prototype.writeFloatLE=function(T,D,G){return N(this,T,D,!0,G)},n.prototype.writeFloatBE=function(T,D,G){return N(this,T,D,!1,G)},n.prototype.writeDoubleLE=function(T,D,G){return F(this,T,D,!0,G)},n.prototype.writeDoubleBE=function(T,D,G){return F(this,T,D,!1,G)},n.prototype.copy=function(T,D,G,W){if(!n.isBuffer(T))throw new TypeError("argument should be a Buffer");if(G=G||0,W||W===0||(W=this.length),D>=T.length&&(D=T.length),(W=0=this.length)throw new RangeError("Index out of range");if(W<0)throw new RangeError("sourceEnd out of bounds");W>this.length&&(W=this.length);var $=(W=T.length-D>>=0,G=G===void 0?this.length:G>>>0,typeof(T=T||0)=="number")for(J=D;J>6|192,63&G|128)}else if(G<65536){if((D-=3)<0)break;J.push(G>>12|224,G>>6&63|128,63&G|128)}else{if(!(G<1114112))throw new Error("Invalid code point");if((D-=4)<0)break;J.push(G>>18|240,G>>12&63|128,G>>6&63|128,63&G|128)}}return J}function V(T){return c.toByteArray(function(D){if((D=(D=D.split("=")[0]).trim().replace(B,"")).length<2)return"";for(;D.length%4!=0;)D+="=";return D}(T))}function H(T,D,G,W){for(var $=0;$=D.length||$>=T.length);++$)D[$+G]=T[$];return $}function Z(T,D){return T instanceof D||T!=null&&T.constructor!=null&&T.constructor.name!=null&&T.constructor.name===D.name}function ee(T){return T!=T}var ue=function(){for(var T="0123456789abcdef",D=new Array(256),G=0;G<16;++G)for(var W=16*G,$=0;$<16;++$)D[W+$]=T[G]+T[$];return D}()}).call(this,t("buffer").Buffer)},{"base64-js":1,buffer:4,ieee754:251}],5:[function(t,x,v){x.exports=function(s){if(typeof s!="function")throw TypeError(String(s)+" is not a function");return s}},{}],6:[function(t,x,v){var s=t("../internals/is-object");x.exports=function(c){if(s(c)||c===null)return c;throw TypeError("Can't set "+String(c)+" as a prototype")}},{"../internals/is-object":75}],7:[function(o,x,v){var s=o("../internals/well-known-symbol"),c=o("../internals/object-create"),o=o("../internals/object-define-property"),u=s("unscopables"),g=Array.prototype;g[u]==null&&o.f(g,u,{configurable:!0,value:c(null)}),x.exports=function(p){g[u][p]=!0}},{"../internals/object-create":91,"../internals/object-define-property":93,"../internals/well-known-symbol":149}],8:[function(t,x,v){var s=t("../internals/string-multibyte").charAt;x.exports=function(c,o,u){return o+(u?s(c,o).length:1)}},{"../internals/string-multibyte":124}],9:[function(t,x,v){x.exports=function(s,c,o){if(s instanceof c)return s;throw TypeError("Incorrect "+(o?o+" ":"")+"invocation")}},{}],10:[function(t,x,v){var s=t("../internals/is-object");x.exports=function(c){if(s(c))return c;throw TypeError(String(c)+" is not an object")}},{"../internals/is-object":75}],11:[function(t,x,v){x.exports=typeof ArrayBuffer<"u"&&typeof DataView<"u"},{}],12:[function(A,x,v){function s(F){return p(F)&&n(N,i(F))}var c,o=A("../internals/array-buffer-native"),u=A("../internals/descriptors"),g=A("../internals/global"),p=A("../internals/is-object"),n=A("../internals/has"),i=A("../internals/classof"),a=A("../internals/create-non-enumerable-property"),h=A("../internals/redefine"),m=A("../internals/object-define-property").f,l=A("../internals/object-get-prototype-of"),f=A("../internals/object-set-prototype-of"),L=A("../internals/well-known-symbol"),A=A("../internals/uid"),y=g.Int8Array,b=y&&y.prototype,j=g.Uint8ClampedArray,j=j&&j.prototype,k=y&&l(y),E=b&&l(b),M=Object.prototype,P=M.isPrototypeOf,L=L("toStringTag"),C=A("TYPED_ARRAY_TAG"),I=o&&!!f&&i(g.opera)!=="Opera",A=!1,N={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8};for(c in N)g[c]||(I=!1);if((!I||typeof k!="function"||k===Function.prototype)&&(k=function(){throw TypeError("Incorrect invocation")},I))for(c in N)g[c]&&f(g[c],k);if((!I||!E||E===M)&&(E=k.prototype,I))for(c in N)g[c]&&f(g[c].prototype,E);if(I&&l(j)!==E&&f(j,E),u&&!n(E,L))for(c in A=!0,m(E,L,{get:function(){return p(this)?this[C]:void 0}}),N)g[c]&&a(g[c],C,c);x.exports={NATIVE_ARRAY_BUFFER_VIEWS:I,TYPED_ARRAY_TAG:A&&C,aTypedArray:function(F){if(s(F))return F;throw TypeError("Target is not a typed array")},aTypedArrayConstructor:function(F){if(f){if(P.call(k,F))return F}else for(var B in N)if(n(N,c)&&(B=g[B],B&&(F===B||P.call(B,F))))return F;throw TypeError("Target is not a typed array constructor")},exportTypedArrayMethod:function(F,B,q){if(u){if(q)for(var V in N)V=g[V],V&&n(V.prototype,F)&&delete V.prototype[F];E[F]&&!q||h(E,F,!q&&I&&b[F]||B)}},exportTypedArrayStaticMethod:function(F,B,q){var V,H;if(u){if(f){if(q)for(V in N)(H=g[V])&&n(H,F)&&delete H[F];if(k[F]&&!q)return;try{return h(k,F,!q&&I&&y[F]||B)}catch{}}for(V in N)!(H=g[V])||H[F]&&!q||h(H,F,B)}},isView:function(F){return F=i(F),F==="DataView"||n(N,F)},isTypedArray:s,TypedArray:k,TypedArrayPrototype:E}},{"../internals/array-buffer-native":11,"../internals/classof":29,"../internals/create-non-enumerable-property":38,"../internals/descriptors":43,"../internals/global":60,"../internals/has":61,"../internals/is-object":75,"../internals/object-define-property":93,"../internals/object-get-prototype-of":98,"../internals/object-set-prototype-of":102,"../internals/redefine":109,"../internals/uid":146,"../internals/well-known-symbol":149}],13:[function(G,x,v){function s(z){return[255&z]}function c(z){return[255&z,z>>8&255]}function o(z){return[255&z,z>>8&255,z>>16&255,z>>24&255]}function u(z){return z[3]<<24|z[2]<<16|z[1]<<8|z[0]}function g(z){return J(z,23,4)}function p(z){return J(z,52,8)}function n(z,te){A(z[Z],te,{get:function(){return B(this)[te]}})}function i(ge,te,ye,me){if(ye=M(ye),ge=B(ge),ye+te>ge.byteLength)throw $(ee);var de=B(ge.buffer).bytes,ye=ye+ge.byteOffset,ge=de.slice(ye,ye+te);return me?ge:ge.reverse()}function a(z,te,le,me,de,ye){if(le=M(le),z=B(z),le+te>z.byteLength)throw $(ee);for(var ge=B(z.buffer).bytes,ke=le+z.byteOffset,ve=me(+de),Ie=0;Iepe;)(ce=ie[pe++])in T||f(T,ce,ue[ce]);h.constructor=T}C&&L(G)!==W&&C(G,W);var P=new D(new T(2)),K=G.setInt8;P.setInt8(0,2147483648),P.setInt8(1,2147483649),!P.getInt8(0)&&P.getInt8(1)||y(G,{setInt8:function(te,le){K.call(this,te,le<<24>>24)},setUint8:function(te,le){K.call(this,te,le<<24>>24)}},{unsafe:!0})}else T=function(z){j(this,T,V),z=M(z),q(this,{bytes:N.call(new Array(z),0),byteLength:z}),m||(this.byteLength=z)},D=function(z,de,le){j(this,D,H),j(z,T,H);var me=B(z).byteLength,de=k(de);if(de<0||me>24},getUint8:function(z){return i(this,1,z)[0]},getInt16:function(z){return z=i(this,2,z,1>16},getUint16:function(z){return z=i(this,2,z,1>>0},getFloat32:function(z){return ne(i(this,4,z,1"+n+""}},{"../internals/require-object-coercible":114}],37:[function(t,x,v){function s(){return this}var c=t("../internals/iterators-core").IteratorPrototype,o=t("../internals/object-create"),u=t("../internals/create-property-descriptor"),g=t("../internals/set-to-string-tag"),p=t("../internals/iterators");x.exports=function(n,i,a){return i+=" Iterator",n.prototype=o(c,{next:u(1,a)}),g(n,i,!1,!0),p[i]=s,n}},{"../internals/create-property-descriptor":39,"../internals/iterators":80,"../internals/iterators-core":79,"../internals/object-create":91,"../internals/set-to-string-tag":118}],38:[function(t,x,v){var s=t("../internals/descriptors"),c=t("../internals/object-define-property"),o=t("../internals/create-property-descriptor");x.exports=s?function(u,g,p){return c.f(u,g,o(1,p))}:function(u,g,p){return u[g]=p,u}},{"../internals/create-property-descriptor":39,"../internals/descriptors":43,"../internals/object-define-property":93}],39:[function(t,x,v){x.exports=function(s,c){return{enumerable:!(1&s),configurable:!(2&s),writable:!(4&s),value:c}}},{}],40:[function(t,x,v){var s=t("../internals/to-primitive"),c=t("../internals/object-define-property"),o=t("../internals/create-property-descriptor");x.exports=function(u,g,p){g=s(g),g in u?c.f(u,g,o(0,p)):u[g]=p}},{"../internals/create-property-descriptor":39,"../internals/object-define-property":93,"../internals/to-primitive":141}],41:[function(l,x,v){function s(){return this}var c=l("../internals/export"),o=l("../internals/create-iterator-constructor"),u=l("../internals/object-get-prototype-of"),g=l("../internals/object-set-prototype-of"),p=l("../internals/set-to-string-tag"),n=l("../internals/create-non-enumerable-property"),i=l("../internals/redefine"),a=l("../internals/well-known-symbol"),h=l("../internals/is-pure"),m=l("../internals/iterators"),l=l("../internals/iterators-core"),f=l.IteratorPrototype,y=l.BUGGY_SAFARI_ITERATORS,b=a("iterator"),j="values",k="entries";x.exports=function(E,M,P,q,C,I,A){o(P,M,q);function N(T){if(T===C&&ee)return ee;if(!y&&T in H)return H[T];switch(T){case"keys":case j:case k:return function(){return new P(this,T)}}return function(){return new P(this)}}var F,B,q=M+" Iterator",V=!1,H=E.prototype,Z=H[b]||H["@@iterator"]||C&&H[C],ee=!y&&Z||N(C),ue=M=="Array"&&H.entries||Z;if(ue&&(ue=u(ue.call(new E)),f!==Object.prototype&&ue.next&&(h||u(ue)===f||(g?g(ue,f):typeof ue[b]!="function"&&n(ue,b,s)),p(ue,q,!0,!0),h&&(m[q]=s))),C==j&&Z&&Z.name!==j&&(V=!0,ee=function(){return Z.call(this)}),h&&!A||H[b]===ee||n(H,b,ee),m[M]=ee,C)if(F={values:N(j),keys:I?ee:N("keys"),entries:N(k)},A)for(B in F)!y&&!V&&B in H||i(H,B,F[B]);else c({target:M,proto:!0,forced:y||V},F);return F}},{"../internals/create-iterator-constructor":37,"../internals/create-non-enumerable-property":38,"../internals/export":50,"../internals/is-pure":76,"../internals/iterators":80,"../internals/iterators-core":79,"../internals/object-get-prototype-of":98,"../internals/object-set-prototype-of":102,"../internals/redefine":109,"../internals/set-to-string-tag":118,"../internals/well-known-symbol":149}],42:[function(t,x,v){var s=t("../internals/path"),c=t("../internals/has"),o=t("../internals/well-known-symbol-wrapped"),u=t("../internals/object-define-property").f;x.exports=function(g){var p=s.Symbol||(s.Symbol={});c(p,g)||u(p,g,{value:o.f(g)})}},{"../internals/has":61,"../internals/object-define-property":93,"../internals/path":105,"../internals/well-known-symbol-wrapped":148}],43:[function(t,x,v){t=t("../internals/fails"),x.exports=!t(function(){return Object.defineProperty({},1,{get:function(){return 7}})[1]!=7})},{"../internals/fails":51}],44:[function(c,x,v){var s=c("../internals/global"),c=c("../internals/is-object"),o=s.document,u=c(o)&&c(o.createElement);x.exports=function(g){return u?o.createElement(g):{}}},{"../internals/global":60,"../internals/is-object":75}],45:[function(t,x,v){x.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},{}],46:[function(t,x,v){t=t("../internals/engine-user-agent"),x.exports=/(iphone|ipod|ipad).*applewebkit/i.test(t)},{"../internals/engine-user-agent":47}],47:[function(t,x,v){t=t("../internals/get-built-in"),x.exports=t("navigator","userAgent")||""},{"../internals/get-built-in":57}],48:[function(o,x,v){var s,c,u=o("../internals/global"),o=o("../internals/engine-user-agent"),u=u.process,u=u&&u.versions,u=u&&u.v8;u?c=(s=u.split("."))[0]+s[1]:o&&(!(s=o.match(/Edge\/(\d+)/))||74<=s[1])&&(s=o.match(/Chrome\/(\d+)/))&&(c=s[1]),x.exports=c&&+c},{"../internals/engine-user-agent":47,"../internals/global":60}],49:[function(t,x,v){x.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},{}],50:[function(t,x,v){var s=t("../internals/global"),c=t("../internals/object-get-own-property-descriptor").f,o=t("../internals/create-non-enumerable-property"),u=t("../internals/redefine"),g=t("../internals/set-global"),p=t("../internals/copy-constructor-properties"),n=t("../internals/is-forced");x.exports=function(i,a){var h,m,l,f=i.target,y=i.global,b=i.stat,j=y?s:b?s[f]||g(f,{}):(s[f]||{}).prototype;if(j)for(h in a){if(m=a[h],l=i.noTargetGet?(l=c(j,h))&&l.value:j[h],!n(y?h:f+(b?".":"#")+h,i.forced)&&l!==void 0){if(typeof m==typeof l)continue;p(m,l)}(i.sham||l&&l.sham)&&o(m,"sham",!0),u(j,h,m,i)}}},{"../internals/copy-constructor-properties":33,"../internals/create-non-enumerable-property":38,"../internals/global":60,"../internals/is-forced":74,"../internals/object-get-own-property-descriptor":94,"../internals/redefine":109,"../internals/set-global":116}],51:[function(t,x,v){x.exports=function(s){try{return!!s()}catch{return!0}}},{}],52:[function(a,x,v){a("../modules/es.regexp.exec");var s=a("../internals/redefine"),c=a("../internals/fails"),o=a("../internals/well-known-symbol"),u=a("../internals/regexp-exec"),g=a("../internals/create-non-enumerable-property"),p=o("species"),n=!c(function(){var l=/./;return l.exec=function(){var f=[];return f.groups={a:"7"},f},"".replace(l,"$")!=="7"}),i="a".replace(/./,"$0")==="$0",a=o("replace"),h=!!/./[a]&&/./[a]("a","$0")==="",m=!c(function(){var f=/(?:)/,l=f.exec,f=(f.exec=function(){return l.apply(this,arguments)},"ab".split(f));return f.length!==2||f[0]!=="a"||f[1]!=="b"});x.exports=function(l,f,y,b){var j,k,E=o(l),M=!c(function(){var L={};return L[E]=function(){return 7},""[l](L)!=7}),P=M&&!c(function(){var L=!1,C=/a/;return l==="split"&&((C={constructor:{}}).constructor[p]=function(){return C},C.flags="",C[E]=/./[E]),C.exec=function(){return L=!0,null},C[E](""),!L});M&&P&&(l!=="replace"||n&&i&&!h)&&(l!=="split"||m)||(j=/./[E],y=(P=y(E,""[l],function(L,C,I,A,N){return C.exec===u?M&&!N?{done:!0,value:j.call(C,I,A)}:{done:!0,value:L.call(I,C,A)}:{done:!1}},{REPLACE_KEEPS_$0:i,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:h}))[0],k=P[1],s(String.prototype,l,y),s(RegExp.prototype,E,f==2?function(L,C){return k.call(L,this,C)}:function(L){return k.call(L,this)})),b&&g(RegExp.prototype[E],"sham",!0)}},{"../internals/create-non-enumerable-property":38,"../internals/fails":51,"../internals/redefine":109,"../internals/regexp-exec":111,"../internals/well-known-symbol":149,"../modules/es.regexp.exec":192}],53:[function(t,x,v){function s(g,p,n,i,a,h,m,l){for(var f,y=a,b=0,j=!!m&&u(m,l,3);b>1,j=n===23?c(2,-24)-c(2,-77):0,k=p<0||p===0&&1/p<0?1:0,E=0;for((p=s(p))!=p||p===1/0?(h=p!=p?1:0,a=y):(a=o(u(p)/g),p*(m=c(2,-a))<1&&(a--,m*=2),2<=(p+=1<=a+b?j/m:j*c(2,1-b))*m&&(a++,m/=2),y<=a+b?(h=0,a=y):1<=a+b?(h=(p*m-1)*c(2,n),a+=b):(h=p*c(2,b-1)*c(2,n),a=0));8<=n;l[E++]=255&h,h/=256,n-=8);for(a=a<>1,l=y-7,f=a-1,y=p[f--],b=127&y;for(y>>=7;0>=-l,l+=n;0"+b+""},y=function(){try{c=document.domain&&new ActiveXObject("htmlfile")}catch{}y=c?((b=c).write(f("")),b.close(),j=b.parentWindow.Object,b=null,j):(b=i("iframe"),j="java"+m+":",b.style.display="none",n.appendChild(b),b.src=String(j),(j=b.contentWindow.document).open(),j.write(f("document.F=Object")),j.close(),j.F);for(var b,j,k=g.length;k--;)delete y[h][g[k]];return y()};p[l]=!0,x.exports=Object.create||function(b,j){var k;return b!==null?(s[h]=o(b),k=new s,s[h]=null,k[l]=b):k=y(),j===void 0?k:u(k,j)}},{"../internals/an-object":10,"../internals/document-create-element":44,"../internals/enum-bug-keys":49,"../internals/hidden-keys":62,"../internals/html":64,"../internals/object-define-properties":92,"../internals/shared-key":119}],92:[function(t,x,v){var s=t("../internals/descriptors"),c=t("../internals/object-define-property"),o=t("../internals/an-object"),u=t("../internals/object-keys");x.exports=s?Object.defineProperties:function(g,p){o(g);for(var n,i=u(p),a=i.length,h=0;ha;)!s(i,n=p[a++])||~o(h,n)||h.push(n);return h}},{"../internals/array-includes":18,"../internals/has":61,"../internals/hidden-keys":62,"../internals/to-indexed-object":135}],100:[function(t,x,v){var s=t("../internals/object-keys-internal"),c=t("../internals/enum-bug-keys");x.exports=Object.keys||function(o){return s(o,c)}},{"../internals/enum-bug-keys":49,"../internals/object-keys-internal":99}],101:[function(t,x,v){var s={}.propertyIsEnumerable,c=Object.getOwnPropertyDescriptor,o=c&&!s.call({1:2},1);v.f=o?function(u){return u=c(this,u),!!u&&u.enumerable}:s},{}],102:[function(t,x,v){var s=t("../internals/an-object"),c=t("../internals/a-possible-prototype");x.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var o,u=!1,g={};try{(o=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set).call(g,[]),u=g instanceof Array}catch{}return function(p,n){return s(p),c(n),u?o.call(p,n):p.__proto__=n,p}}():void 0)},{"../internals/a-possible-prototype":6,"../internals/an-object":10}],103:[function(t,x,v){var s=t("../internals/to-string-tag-support"),c=t("../internals/classof");x.exports=s?{}.toString:function(){return"[object "+c(this)+"]"}},{"../internals/classof":29,"../internals/to-string-tag-support":142}],104:[function(t,x,v){var s=t("../internals/get-built-in"),c=t("../internals/object-get-own-property-names"),o=t("../internals/object-get-own-property-symbols"),u=t("../internals/an-object");x.exports=s("Reflect","ownKeys")||function(g){var p=c.f(u(g)),n=o.f;return n?p.concat(n(g)):p}},{"../internals/an-object":10,"../internals/get-built-in":57,"../internals/object-get-own-property-names":96,"../internals/object-get-own-property-symbols":97}],105:[function(t,x,v){t=t("../internals/global"),x.exports=t},{"../internals/global":60}],106:[function(t,x,v){x.exports=function(s){try{return{error:!1,value:s()}}catch(c){return{error:!0,value:c}}}},{}],107:[function(t,x,v){var s=t("../internals/an-object"),c=t("../internals/is-object"),o=t("../internals/new-promise-capability");x.exports=function(u,g){return s(u),c(g)&&g.constructor===u?g:((0,(u=o.f(u)).resolve)(g),u.promise)}},{"../internals/an-object":10,"../internals/is-object":75,"../internals/new-promise-capability":87}],108:[function(t,x,v){var s=t("../internals/redefine");x.exports=function(c,o,u){for(var g in o)s(c,g,o[g],u);return c}},{"../internals/redefine":109}],109:[function(p,x,v){var s=p("../internals/global"),c=p("../internals/create-non-enumerable-property"),o=p("../internals/has"),u=p("../internals/set-global"),g=p("../internals/inspect-source"),p=p("../internals/internal-state"),n=p.get,i=p.enforce,a=String(String).split("String");(x.exports=function(h,m,l,j){var y=!!j&&!!j.unsafe,b=!!j&&!!j.enumerable,j=!!j&&!!j.noTargetGet;typeof l=="function"&&(typeof m!="string"||o(l,"name")||c(l,"name",m),i(l).source=a.join(typeof m=="string"?m:"")),h===s?b?h[m]=l:u(m,l):(y?!j&&h[m]&&(b=!0):delete h[m],b?h[m]=l:c(h,m,l))})(Function.prototype,"toString",function(){return typeof this=="function"&&n(this).source||g(this)})},{"../internals/create-non-enumerable-property":38,"../internals/global":60,"../internals/has":61,"../internals/inspect-source":69,"../internals/internal-state":71,"../internals/set-global":116}],110:[function(t,x,v){var s=t("./classof-raw"),c=t("./regexp-exec");x.exports=function(o,u){var g=o.exec;if(typeof g=="function"){if(g=g.call(o,u),typeof g!="object")throw TypeError("RegExp exec method returned something other than an Object or null");return g}if(s(o)!=="RegExp")throw TypeError("RegExp#exec called on incompatible receiver");return c.call(o,u)}},{"./classof-raw":28,"./regexp-exec":111}],111:[function(u,x,v){var s,c,o=u("./regexp-flags"),u=u("./regexp-sticky-helpers"),g=RegExp.prototype.exec,p=String.prototype.replace,n=g,i=(s=/a/,c=/b*/g,g.call(s,"a"),g.call(c,"a"),s.lastIndex!==0||c.lastIndex!==0),a=u.UNSUPPORTED_Y||u.BROKEN_CARET,h=/()??/.exec("")[1]!==void 0;x.exports=n=i||h||a?function(m){var l,f,y,b,j=this,k=a&&j.sticky,E=o.call(j),M=j.source,P=0,L=m;return k&&((E=E.replace("y","")).indexOf("g")===-1&&(E+="g"),L=String(m).slice(j.lastIndex),0f&&(m=m.slice(0,f)),p?h+m:m+h)}}var c=t("../internals/to-length"),o=t("../internals/string-repeat"),u=t("../internals/require-object-coercible"),g=Math.ceil;x.exports={start:s(!1),end:s(!0)}},{"../internals/require-object-coercible":114,"../internals/string-repeat":128,"../internals/to-length":137}],127:[function(t,x,v){function s(y){return y+22+75*(y<26)}function c(y){var b,j=[],k=(y=function(Z){for(var ee=[],ue=0,T=Z.length;uel((o-M)/N))throw RangeError(h);for(M+=(I-E)*N,E=I,A=0;Ao)throw RangeError(h);if(b==E){for(var F=M,B=u;;B+=u){var q=B<=P?1:P+g<=B?g:B-P;if(F>1,Z+=l(Z/ee);m*g>>1>>=1)&&(u+=u))1&p&&(g+=u);return g}},{"../internals/require-object-coercible":114,"../internals/to-integer":136}],129:[function(t,x,v){var s=t("../internals/fails"),c=t("../internals/whitespaces");x.exports=function(o){return s(function(){return!!c[o]()||"​…᠎"[o]()!="​…᠎"||c[o].name!==o})}},{"../internals/fails":51,"../internals/whitespaces":150}],130:[function(o,x,v){function s(p){return function(n){return n=String(c(n)),1&p&&(n=n.replace(u,"")),n=2&p?n.replace(g,""):n}}var c=o("../internals/require-object-coercible"),o="["+o("../internals/whitespaces")+"]",u=RegExp("^"+o+o+"*"),g=RegExp(o+o+"*$");x.exports={start:s(1),end:s(2),trim:s(3)}},{"../internals/require-object-coercible":114,"../internals/whitespaces":150}],131:[function(m,x,v){function s(C){return function(){L(C)}}function c(C){L(C.data)}function o(C){g.postMessage(C+"",l.protocol+"//"+l.host)}var u,g=m("../internals/global"),p=m("../internals/fails"),n=m("../internals/classof-raw"),i=m("../internals/function-bind-context"),a=m("../internals/html"),h=m("../internals/document-create-element"),m=m("../internals/engine-is-ios"),l=g.location,f=g.setImmediate,y=g.clearImmediate,b=g.process,j=g.MessageChannel,k=g.Dispatch,E=0,M={},P="onreadystatechange",L=function(C){var I;M.hasOwnProperty(C)&&(I=M[C],delete M[C],I())};f&&y||(f=function(C){for(var I=[],A=1;A=h.length?{value:a.target=void 0,done:!0}:m=="keys"?{value:l,done:!1}:m=="values"?{value:h[l],done:!1}:{value:[l,h[l]],done:!1}},"values"),o.Arguments=o.Array,c("keys"),c("values"),c("entries")},{"../internals/add-to-unscopables":7,"../internals/define-iterator":41,"../internals/internal-state":71,"../internals/iterators":80,"../internals/to-indexed-object":135}],165:[function(g,x,v){var s=g("../internals/export"),u=g("../internals/indexed-object"),c=g("../internals/to-indexed-object"),g=g("../internals/array-method-is-strict"),o=[].join,u=u!=Object,g=g("join",",");s({target:"Array",proto:!0,forced:u||!g},{join:function(p){return o.call(c(this),p===void 0?",":p)}})},{"../internals/array-method-is-strict":22,"../internals/export":50,"../internals/indexed-object":67,"../internals/to-indexed-object":135}],166:[function(c,x,v){var s=c("../internals/export"),c=c("../internals/array-last-index-of");s({target:"Array",proto:!0,forced:c!==[].lastIndexOf},{lastIndexOf:c})},{"../internals/array-last-index-of":20,"../internals/export":50}],167:[function(u,x,v){var s=u("../internals/export"),c=u("../internals/array-iteration").map,o=u("../internals/array-method-has-species-support"),u=u("../internals/array-method-uses-to-length"),o=o("map"),u=u("map");s({target:"Array",proto:!0,forced:!o||!u},{map:function(g){return c(this,g,1I;I++)p(k,P=C[I])&&!p(L,P)&&y(L,P,f(k,P));(L.prototype=E).constructor=L,g(o,j,L)}},{"../internals/classof-raw":28,"../internals/descriptors":43,"../internals/fails":51,"../internals/global":60,"../internals/has":61,"../internals/inherit-if-required":68,"../internals/is-forced":74,"../internals/object-create":91,"../internals/object-define-property":93,"../internals/object-get-own-property-descriptor":94,"../internals/object-get-own-property-names":96,"../internals/redefine":109,"../internals/string-trim":130,"../internals/to-primitive":141}],179:[function(t,x,v){t("../internals/export")({target:"Number",stat:!0},{isFinite:t("../internals/number-is-finite")})},{"../internals/export":50,"../internals/number-is-finite":89}],180:[function(p,x,v){function s(a,h,m){return h===0?m:h%2==1?s(a,h-1,m*a):s(a*a,h/2,m)}var c=p("../internals/export"),o=p("../internals/to-integer"),u=p("../internals/this-number-value"),g=p("../internals/string-repeat"),p=p("../internals/fails"),n=1 .toFixed,i=Math.floor;c({target:"Number",proto:!0,forced:n&&(8e-5.toFixed(3)!=="0.000"||.9.toFixed(0)!=="1"||1.255.toFixed(2)!=="1.25"||0xde0b6b3a7640080.toFixed(0)!=="1000000000000000128")||!p(function(){n.call({})})},{toFixed:function(j){function h(P,L){for(var C=-1,I=L;++C<6;)I+=P*k[C],k[C]=I%1e7,I=i(I/1e7)}function m(P){for(var L=6,C=0;0<=--L;)C+=k[L],k[L]=i(C/P),C=C%P*1e7}function l(){for(var P,L=6,C="";0<=--L;)C===""&&L!==0&&k[L]===0||(P=String(k[L]),C=C===""?P:C+g.call("0",7-P.length)+P);return C}var f,y,b=u(this),j=o(j),k=[0,0,0,0,0,0],E="",M="0";if(j<0||20Pe;){var He,We,qe,Ye=se[Pe++],lt=Se?Ye.ok:Ye.fail,ot=Ye.resolve,Ze=Ye.reject,it=Ye.domain;try{lt?(Se||(Ee.rejection===ye&&function(nt,kt){C.call(n,function(){pe?J.emit("rejectionHandled",nt):De(te,nt,kt.value)})}(Re,Ee),Ee.rejection=de),lt===!0?He=we:(it&&it.enter(),He=lt(we),it&&(it.exit(),qe=!0)),He===Ye.promise?Ze(W("Promise-chain cycle")):(We=ve(He))?We.call(He,ot,Ze):ot(He)):Ze(we)}catch(nt){it&&!qe&&it.exit(),Ze(nt)}}Ee.reactions=[],Ee.notified=!1,re&&!Ee.rejection&&(Q=Re,ae=Ee,C.call(n,function(){var nt=ae.value,kt=Le(ae);if(kt&&(kt=B(function(){pe?J.emit("unhandledRejection",nt,Q):De(z,Q,nt)}),ae.rejection=pe||Le(ae)?ye:de,kt.error))throw kt.value}))}))},De=function(Re,Ee,re){var se;K?((se=$.createEvent("Event")).promise=Ee,se.reason=re,se.initEvent(Re,!1,!0),n.dispatchEvent(se)):se={promise:Ee,reason:re},(Ee=n["on"+Re])?Ee(se):Re===z&&N("Unhandled promise rejection",re)},Le=function(Re){return Re.rejection!==de&&!Re.parent},Ne=function(Re,Ee,re,se){return function(Q){Re(Ee,re,Q,se)}},Be=function(Re,Ee,re,se){Ee.done||(Ee.done=!0,(Ee=se||Ee).value=re,Ee.state=me,Ie(Re,Ee,!0))},xe=function(Re,Ee,re,se){if(!Ee.done){Ee.done=!0,se&&(Ee=se);try{if(Re===re)throw W("Promise can't be resolved itself");var Q=ve(re);Q?I(function(){var ae={done:!1};try{Q.call(re,Ne(xe,Re,ae,Ee),Ne(Be,Re,ae,Ee))}catch(we){Be(Re,ae,we,Ee)}}):(Ee.value=re,Ee.state=le,Ie(Re,Ee,!1))}catch(ae){Be(Re,{done:!1},ae,Ee)}}};ge&&(G=function(Re){j(this,G,ee),b(Re),s.call(this);var Ee=ue(this);try{Re(Ne(xe,this,Ee),Ne(Be,this,Ee))}catch(re){Be(this,Ee,re)}},(s=function(Re){T(this,{type:ee,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:void 0})}).prototype=m(G.prototype,{then:function(Re,Ee){var re=D(this),se=ce(L(this,G));return se.ok=typeof Re!="function"||Re,se.fail=typeof Ee=="function"&&Ee,se.domain=pe?J.domain:void 0,re.parent=!0,re.reactions.push(se),re.state!=0&&Ie(this,re,!1),se.promise},catch:function(Re){return this.then(void 0,Re)}}),c=function(){var Re=new s,Ee=ue(Re);this.promise=Re,this.resolve=Ne(xe,Re,Ee),this.reject=Ne(Be,Re,Ee)},F.f=ce=function(Re){return Re===G||Re===o?new c:ie(Re)},p||typeof a!="function"||(u=a.prototype.then,h(a.prototype,"then",function(Re,Ee){var re=this;return new G(function(se,Q){u.call(re,se,Q)}).then(Re,Ee)},{unsafe:!0}),typeof ne=="function"&&g({global:!0,enumerable:!0,forced:!0},{fetch:function(Re){return A(G,ne.apply(n,arguments))}}))),g({global:!0,wrap:!0,forced:ge},{Promise:G}),l(G,ee,!1,!0),f(ee),o=i(ee),g({target:ee,stat:!0,forced:ge},{reject:function(Re){var Ee=ce(this);return Ee.reject.call(void 0,Re),Ee.promise}}),g({target:ee,stat:!0,forced:p||ge},{resolve:function(Re){return A(p&&this===o?G:this,Re)}}),g({target:ee,stat:!0,forced:ke},{all:function(Re){var Ee=this,re=ce(Ee),se=re.resolve,Q=re.reject,ae=B(function(){var we=b(Ee.resolve),Se=[],Pe=0,He=1;M(Re,function(We){var qe=Pe++,Ye=!1;Se.push(void 0),He++,we.call(Ee,We).then(function(lt){Ye||(Ye=!0,Se[qe]=lt,--He||se(Se))},Q)}),--He||se(Se)});return ae.error&&Q(ae.value),re.promise},race:function(Re){var Ee=this,re=ce(Ee),se=re.reject,Q=B(function(){var ae=b(Ee.resolve);M(Re,function(we){ae.call(Ee,we).then(re.resolve,se)})});return Q.error&&se(Q.value),re.promise}})},{"../internals/a-function":5,"../internals/an-instance":9,"../internals/check-correctness-of-iteration":27,"../internals/classof-raw":28,"../internals/engine-v8-version":48,"../internals/export":50,"../internals/get-built-in":57,"../internals/global":60,"../internals/host-report-errors":63,"../internals/inspect-source":69,"../internals/internal-state":71,"../internals/is-forced":74,"../internals/is-object":75,"../internals/is-pure":76,"../internals/iterate":78,"../internals/microtask":82,"../internals/native-promise-constructor":83,"../internals/new-promise-capability":87,"../internals/perform":106,"../internals/promise-resolve":107,"../internals/redefine":109,"../internals/redefine-all":108,"../internals/set-species":117,"../internals/set-to-string-tag":118,"../internals/species-constructor":122,"../internals/task":131,"../internals/well-known-symbol":149}],189:[function(n,x,v){var s=n("../internals/export"),m=n("../internals/get-built-in"),c=n("../internals/a-function"),o=n("../internals/an-object"),u=n("../internals/is-object"),g=n("../internals/object-create"),p=n("../internals/function-bind"),n=n("../internals/fails"),i=m("Reflect","construct"),a=n(function(){function l(){}return!(i(function(){},[],l)instanceof l)}),h=!n(function(){i(function(){})}),m=a||h;s({target:"Reflect",stat:!0,forced:m,sham:m},{construct:function(l,f){c(l),o(f);var y=arguments.length<3?l:c(arguments[2]);if(h&&!a)return i(l,f,y);if(l==y){switch(f.length){case 0:return new l;case 1:return new l(f[0]);case 2:return new l(f[0],f[1]);case 3:return new l(f[0],f[1],f[2]);case 4:return new l(f[0],f[1],f[2],f[3])}var b=[null];return b.push.apply(b,f),new(p.apply(l,b))}return b=y.prototype,y=g(u(b)?b:Object.prototype),b=Function.apply.call(l,y,f),u(b)?b:y}})},{"../internals/a-function":5,"../internals/an-object":10,"../internals/export":50,"../internals/fails":51,"../internals/function-bind":56,"../internals/get-built-in":57,"../internals/is-object":75,"../internals/object-create":91}],190:[function(t,x,v){var s=t("../internals/export"),c=t("../internals/is-object"),o=t("../internals/an-object"),u=t("../internals/has"),g=t("../internals/object-get-own-property-descriptor"),p=t("../internals/object-get-prototype-of");s({target:"Reflect",stat:!0},{get:function n(i,a){var h,m=arguments.length<3?i:arguments[2];return o(i)===m?i[a]:(h=g.f(i,a))?u(h,"value")?h.value:h.get===void 0?void 0:h.get.call(m):c(h=p(i))?n(h,a,m):void 0}})},{"../internals/an-object":10,"../internals/export":50,"../internals/has":61,"../internals/is-object":75,"../internals/object-get-own-property-descriptor":94,"../internals/object-get-prototype-of":98}],191:[function(t,x,v){var s=t("../internals/descriptors"),c=t("../internals/global"),o=t("../internals/is-forced"),u=t("../internals/inherit-if-required"),g=t("../internals/object-define-property").f,p=t("../internals/object-get-own-property-names").f,n=t("../internals/is-regexp"),i=t("../internals/regexp-flags"),a=t("../internals/regexp-sticky-helpers"),h=t("../internals/redefine"),m=t("../internals/fails"),l=t("../internals/internal-state").set,f=t("../internals/set-species"),y=t("../internals/well-known-symbol")("match"),b=c.RegExp,j=b.prototype,k=/a/g,E=/a/g,M=new b(k)!==k,P=a.UNSUPPORTED_Y;if(s&&o("RegExp",!M||P||m(function(){return E[y]=!1,b(k)!=k||b(E)==E||b(k,"i")!="/a/i"}))){for(var L=function(A,N){var F,B=this instanceof L,q=n(A),V=N===void 0;return!B&&q&&A.constructor===L&&V?A:(M?q&&!V&&(A=A.source):A instanceof L&&(V&&(N=i.call(A)),A=A.source),P&&(F=!!N&&-1I;)(function(A){A in L||g(L,A,{configurable:!0,get:function(){return b[A]},set:function(N){b[A]=N}})})(C[I++]);(j.constructor=L).prototype=j,h(c,"RegExp",L)}f("RegExp")},{"../internals/descriptors":43,"../internals/fails":51,"../internals/global":60,"../internals/inherit-if-required":68,"../internals/internal-state":71,"../internals/is-forced":74,"../internals/is-regexp":77,"../internals/object-define-property":93,"../internals/object-get-own-property-names":96,"../internals/redefine":109,"../internals/regexp-flags":112,"../internals/regexp-sticky-helpers":113,"../internals/set-species":117,"../internals/well-known-symbol":149}],192:[function(c,x,v){var s=c("../internals/export"),c=c("../internals/regexp-exec");s({target:"RegExp",proto:!0,forced:/./.exec!==c},{exec:c})},{"../internals/export":50,"../internals/regexp-exec":111}],193:[function(u,x,v){var s=u("../internals/redefine"),c=u("../internals/an-object"),n=u("../internals/fails"),o=u("../internals/regexp-flags"),u="toString",g=RegExp.prototype,p=g[u],n=n(function(){return p.call({source:"a",flags:"b"})!="/a/b"}),i=p.name!=u;(n||i)&&s(RegExp.prototype,u,function(){var a=c(this),h=String(a.source),m=a.flags;return"/"+h+"/"+String(m===void 0&&a instanceof RegExp&&!("flags"in g)?o.call(a):m)},{unsafe:!0})},{"../internals/an-object":10,"../internals/fails":51,"../internals/redefine":109,"../internals/regexp-flags":112}],194:[function(c,x,v){var s=c("../internals/collection"),c=c("../internals/collection-strong");x.exports=s("Set",function(o){return function(){return o(this,arguments.length?arguments[0]:void 0)}},c)},{"../internals/collection":32,"../internals/collection-strong":30}],195:[function(p,x,v){var s=p("../internals/export"),c=p("../internals/object-get-own-property-descriptor").f,o=p("../internals/to-length"),u=p("../internals/not-a-regexp"),g=p("../internals/require-object-coercible"),a=p("../internals/correct-is-regexp-logic"),p=p("../internals/is-pure"),n="".endsWith,i=Math.min,a=a("endsWith");s({target:"String",proto:!0,forced:!!(p||a||!(s=c(String.prototype,"endsWith"))||s.writable)&&!a},{endsWith:function(h){var m=String(g(this)),l=(u(h),1=i.length?{value:void 0,done:!0}:(i=s(i,a),n.index+=i.length,{value:i,done:!1})})},{"../internals/define-iterator":41,"../internals/internal-state":71,"../internals/string-multibyte":124}],198:[function(t,x,v){var s=t("../internals/fix-regexp-well-known-symbol-logic"),c=t("../internals/an-object"),o=t("../internals/to-length"),u=t("../internals/require-object-coercible"),g=t("../internals/advance-string-index"),p=t("../internals/regexp-exec-abstract");s("match",1,function(n,i,a){return[function(h){var m=u(this),l=h==null?void 0:h[n];return l!==void 0?l.call(h,m):new RegExp(h)[n](String(m))},function(h){var m=a(i,h,this);if(m.done)return m.value;var l=c(h),f=String(this);if(!l.global)return p(l,f);for(var y=l.unicode,b=[],j=l.lastIndex=0;(k=p(l,f))!==null;){var k=String(k[0]);(b[j]=k)===""&&(l.lastIndex=g(f,o(l.lastIndex),y)),j++}return j===0?null:b}]})},{"../internals/advance-string-index":8,"../internals/an-object":10,"../internals/fix-regexp-well-known-symbol-logic":52,"../internals/regexp-exec-abstract":110,"../internals/require-object-coercible":114,"../internals/to-length":137}],199:[function(t,x,v){var s=t("../internals/export"),c=t("../internals/string-pad").start;s({target:"String",proto:!0,forced:t("../internals/string-pad-webkit-bug")},{padStart:function(o){return c(this,o,1]*>)/g,f=/\$([$&'`]|\d\d?)/g;s("replace",2,function(y,b,j,k){var E=k.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,M=k.REPLACE_KEEPS_$0,P=E?"$":"$0";return[function(L,C){var I=p(this),A=L==null?void 0:L[y];return A!==void 0?A.call(L,I,C):b.call(String(I),L,C)},function(L,C){if(!E&&M||typeof C=="string"&&C.indexOf(P)===-1){var I=j(b,L,this,C);if(I.done)return I.value}for(var A,N=c(L),F=String(this),B=typeof C=="function",q=(B||(C=String(C)),N.global),V=(q&&(A=N.unicode,N.lastIndex=0),[]);(T=i(N,F))!==null&&(V.push(T),q);)String(T[0])===""&&(N.lastIndex=n(F,u(N.lastIndex),A));for(var H,Z="",ee=0,ue=0;ue>>0;if(C==0)return[];if(M===void 0)return[L];if(!c(M))return j.call(L,M,C);for(var I,A,N,F=[],P=(M.ignoreCase?"i":"")+(M.multiline?"m":"")+(M.unicode?"u":"")+(M.sticky?"y":""),B=0,q=new RegExp(M.source,P+"g");(I=a.call(q,L))&&!(B<(A=q.lastIndex)&&(F.push(L.slice(B,I.index)),1=C));)q.lastIndex===I.index&&q.lastIndex++;return B===L.length?!N&&q.test("")||F.push(""):F.push(L.slice(B)),F.length>C?F.slice(0,C):F}:"0".split(void 0,0).length?function(M,P){return M===void 0&&P===0?[]:j.call(this,M,P)}:j;return[function(M,P){var L=u(this),C=M==null?void 0:M[b];return C!==void 0?C.call(M,L,P):E.call(String(L),M,P)},function(I,P){var L=k(E,I,this,P,E!==j);if(L.done)return L.value;var L=o(I),C=String(this),I=g(L,RegExp),A=L.unicode,N=(L.ignoreCase?"i":"")+(L.multiline?"m":"")+(L.unicode?"u":"")+(y?"y":"g"),F=new I(y?L:"^(?:"+L.source+")",N),B=P===void 0?f:P>>>0;if(B==0)return[];if(C.length===0)return i(F,C)===null?[C]:[];for(var q=0,V=0,H=[];Vne.key){pe.splice(ce,0,ne);break}ce===z&&pe.push(ne)}ie.updateURL()},forEach:function(ne){for(var ce,ie=H(this).entries,pe=j(ne,16))return;for(Nt=0;Jt();){if(Qt=null,Nt>0)if(Jt()=="."&&Nt<4)$e++;else return;if(!G.test(Jt()))return;for(;G.test(Jt());){if(en=parseInt(Jt(),10),Qt===null)Qt=en;else{if(Qt==0)return;Qt=Qt*10+en}if(Qt>255)return;$e++}gt[Xe]=gt[Xe]*256+Qt,Nt++,(Nt==2||Nt==4)&&Xe++}if(Nt!=4)return;break}else if(Jt()==":"){if($e++,!Jt())return}else if(Jt())return;gt[Xe++]=Vt}if(ht!==null)for(_r=Xe-ht,Xe=7;Xe!=0&&_r>0;)tn=gt[Xe],gt[Xe--]=gt[ht+_r-1],gt[ht+--_r]=tn;else if(Xe!=8)return;return gt}(ze.slice(1,-1)))?void(_e.host=Ke):ee;if(ve(_e))return ze=M(ze),ce.test(ze)||(Ke=function(Ge){var gt=Ge.split("."),Xe,ht,$e,Vt,Yt,Nt,Qt;if(gt.length&>[gt.length-1]==""&>.pop(),(Xe=gt.length)>4)return Ge;for(ht=[],$e=0;$e1&&Vt.charAt(0)=="0"&&(Yt=W.test(Vt)?16:8,Vt=Vt.slice(Yt==8?1:2)),Vt==="")Nt=0;else{if(!(Yt==10?J:Yt==8?$:ne).test(Vt))return Ge;Nt=parseInt(Vt,Yt)}ht.push(Nt)}for($e=0;$e=V(256,5-Xe))return null}else if(Nt>255)return null;for(Qt=ht.pop(),$e=0;$e":1,"`":1}),de=j({},me,{"#":1,"?":1,"{":1,"}":1}),ye=j({},de,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),ge=function(_e,ze){var Ke=E(_e,0);return 32"u"&&s!==void 0&&{}.toString.call(s)==="[object process]",y=typeof Uint8ClampedArray<"u"&&typeof importScripts<"u"&&typeof MessageChannel<"u";function b(){var z=setTimeout;return function(){return z(k,1)}}var j=new Array(1e3);function k(){for(var z=0;zL,applyPalette:()=>function(B,q,V="rgb565"){if(!B||!B.buffer)throw new Error("quantize() expected RGBA Uint8Array data");if(!(B instanceof Uint8Array||B instanceof Uint8ClampedArray))throw new Error("quantize() expected RGBA Uint8Array data");if(256>24&255,G=$>>16&255,W=$>>8&255,$=255&$,J=h($,W,G,D),J=J in T?T[J]:T[J]=function(z,te,le,me,de){let ye=0,ge=1e100;for(let De=0;Dege||(ke=ve[0],(Ie+=E(ke-z))>ge||(ke=ve[1],(Ie+=E(ke-te))>ge||(ke=ve[2],(Ie+=E(ke-le))>ge||(ge=Ie,ye=De))))}return ye}($,W,G,D,q);ue[K]=J}else{const K=V==="rgb444"?m:a;for(let z=0;z>16&255,ce=ie>>8&255,ie=255&ie,pe=K(ie,ce,ne),pe=pe in T?T[pe]:T[pe]=function(te,le,me,de){let ye=0,ge=1e100;for(let De=0;Dege||(ke=ve[1],(Ie+=E(ke-le))>ge||(ke=ve[2],(Ie+=E(ke-me))>ge||(ge=Ie,ye=De)))}return ye}(ie,ce,ne,q);ue[z]=pe}}return ue},default:()=>F,nearestColor:()=>function(B,q,V=j){return B[M(B,q,V)]},nearestColorIndex:()=>M,nearestColorIndexWithDistance:()=>P,prequantize:()=>function(B,{roundRGB:q=5,roundAlpha:V=10,oneBitAlpha:H=null}={}){const Z=new Uint32Array(B.buffer);for(let G=0;G>24&255;var ee,ue=D>>16&255,T=D>>8&255,D=255&D;W=k(W,V),H&&(ee=typeof H=="number"?H:127,W=W<=ee?0:255),D=k(D,q),T=k(T,q),ue=k(ue,q),Z[G]=W<<24|ue<<16|T<<8|D<<0}},quantize:()=>function(B,q,V={}){var{format:H="rgb565",clearAlpha:Z=!0,clearAlphaColor:ee=0,clearAlphaThreshold:ue=0,oneBitAlpha:T=!1}=V;if(!B||!B.buffer)throw new Error("quantize() expected RGBA Uint8Array data");if(!(B instanceof Uint8Array||B instanceof Uint8ClampedArray))throw new Error("quantize() expected RGBA Uint8Array data");B=new Uint32Array(B.buffer);let D=V.useSqrt!==!1;const G=H==="rgba4444",W=function(Le,Ne){const Be=Ne==="rgb444"?4096:65536,xe=new Array(Be),Re=Le.length;if(Ne==="rgba4444")for(let ot=0;ot>24&255,re=Q>>16&255,se=Q>>8&255,Q=255&Q,ae=h(Q,se,re,Ee);let Ze=ae in xe?xe[ae]:xe[ae]=b();Ze.rc+=Q,Ze.gc+=se,Ze.bc+=re,Ze.ac+=Ee,Ze.cnt++}else if(Ne==="rgb444")for(let ot=0;ot>16&255,Se=Pe>>8&255,Pe=255&Pe,He=m(Pe,Se,we);let Ze=He in xe?xe[He]:xe[He]=b();Ze.rc+=Pe,Ze.gc+=Se,Ze.bc+=we,Ze.cnt++}else for(let ot=0;ot>16&255,qe=Ye>>8&255,Ye=255&Ye,lt=a(Ye,qe,We);let Ze=lt in xe?xe[lt]:xe[lt]=b();Ze.rc+=Ye,Ze.gc+=qe,Ze.bc+=We,Ze.cnt++}return xe}(B,H),$=W.length,J=$-1,ne=new Uint32Array($+1);for(var ce=0,ie=0;ie<$;++ie){const Le=W[ie];Le!=null&&(ve=1/Le.cnt,G&&(Le.ac*=ve),Le.rc*=ve,Le.gc*=ve,Le.bc*=ve,W[ce++]=Le)}f(q)/ce<.022&&(D=!1);for(var pe,K,z,ie=0;ie>1,!(W[pe=ne[z]].err<=te));K=z)ne[K]=pe;ne[K]=ie}var le,me=ce-q;for(ie=0;ie=le.mtm&&W[le.nn].mtm<=le.tm)break;for(le.mtm==J?de=ne[1]=ne[ne[0]--]:(y(W,de),le.tm=ie),te=W[de].err,K=1;(z=K+K)<=ne[0]&&(zW[ne[z+1]].err&&z++,!(te<=W[pe=ne[z]].err));K=z)ne[K]=pe;ne[K]=de}var ye=W[le.nn],ge=le.cnt,ke=ye.cnt,ve=1/(ge+ke);G&&(le.ac=ve*(ge*le.ac+ke*ye.ac)),le.rc=ve*(ge*le.rc+ke*ye.rc),le.gc=ve*(ge*le.gc+ke*ye.gc),le.bc=ve*(ge*le.bc+ke*ye.bc),le.cnt+=ye.cnt,le.mtm=++ie,W[ye.bk].fw=ye.fw,W[ye.fw].bk=ye.bk,ye.mtm=J}let Ie=[];for(ie=0;;0){let Le=l(Math.round(W[ie].rc),0,255),Ne=l(Math.round(W[ie].gc),0,255),Be=l(Math.round(W[ie].bc),0,255),xe=255;G&&(xe=l(Math.round(W[ie].ac),0,255),T&&(De=typeof T=="number"?T:127,xe=xe<=De?0:255),Z&&xe<=ue&&(Le=Ne=Be=ee,xe=0));var De=G?[Le,Ne,Be,xe]:[Le,Ne,Be];if(function(Re,Ee){for(let Q=0;Qfunction(B,q,V=5){if(B.length&&q.length){var H=B.map(D=>D.slice(0,3)),Z=V*V,ee=B[0].length;for(let D=0;Dee?G.slice(0,3):G.slice();var T=P(H,G.slice(0,3),j),ue=T[0],T=T[1];0>>0),ee!=0&&(Z=Math.max(Z,256));const ue=V;V=new Uint8Array(Z),0>=8,$-=8;if((te>pe||ce)&&(ce?(ie=ne,pe=(1<>=8,$-=8;0>3}function h(B,q,V,H){return B>>4|240&q|(240&V)<<4|(240&H)<<8}function m(B,q,V){return B>>4<<8|240&q|V>>4}function l(B,q,V){return B>8&255)}function A(B,q){for(var V=0;V>1,m=-7,l=o?y-1:0,f=o?-1:1,y=s[c+l];for(l+=f,p=y&(1<<-m)-1,y>>=-m,m+=i;0>=-m,m+=u;0>1,l=g===23?Math.pow(2,-24)-Math.pow(2,-77):0,f=u?0:b-1,y=u?1:-1,b=c<0||c===0&&1/c<0?1:0;for(c=Math.abs(c),isNaN(c)||c===1/0?(i=isNaN(c)?1:0,n=h):(n=Math.floor(Math.log(c)/Math.LN2),c*(u=Math.pow(2,-n))<1&&(n--,u*=2),2<=(c+=1<=n+m?l/u:l*Math.pow(2,1-m))*u&&(n++,u/=2),h<=n+m?(i=0,n=h):1<=n+m?(i=(c*u-1)*Math.pow(2,g),n+=m):(i=c*Math.pow(2,m-1)*Math.pow(2,g),n=0));8<=g;s[o+f]=255&i,f+=y,i/=256,g-=8);for(n=n<Math.abs(re[0])&&(se=1),se=Math.abs(re[2])>Math.abs(re[se])?2:se}function I(re,se){re.f+=se.f,re.b.f+=se.b.f}function A(re,se,Q){return re=re.a,se=se.a,Q=Q.a,se.b.a===re?Q.b.a===re?o(se.a,Q.a)?g(Q.b.a,se.a,Q.a)<=0:0<=g(se.b.a,Q.a,se.a):g(Q.b.a,re,Q.a)<=0:Q.b.a===re?0<=g(se.b.a,re,se.a):(se=u(se.b.a,re,se.a),(re=u(Q.b.a,re,Q.a))<=se)}function N(re){re.a.i=null;var se=re.e;se.a.c=se.c,se.c.a=se.a,re.e=null}function F(re,se){l(re.a),re.c=!1,(re.a=se).i=re}function B(re){for(var se=re.a.a;(re=Ee(re)).a.a===se;);return re.c&&(F(re,se=y(Re(re).a.b,re.a.e)),re=Ee(re)),re}function q(re,se,Q){var ae=new xe;return ae.a=Q,ae.e=ce(re.f,se.e,ae),Q.i=ae}function V(re,se){switch(re.s){case 100130:return(1&se)!=0;case 100131:return se!==0;case 100132:return 0>1]],He[Pe[qe]])?Ne:Be)(Q,qe),He[Se]=null,We[Se]=Q.b,Q.b=Se}else for(Q.c[-(Se+1)]=null;0Math.max(Pe.a,We.a))){if(o(Se,Pe)){if(0Q.f&&(Q.f*=2,Q.c=Ie(Q.c,Q.f+1)),Q.b===0?we=ae:(we=Q.b,Q.b=Q.c[Q.b]),Q.e[we]=se,Q.c[we]=ae,Q.d[ae]=we,Q.h&&Be(Q,ae),we):(Q=re.a++,re.c[Q]=se,-(Q+1))}function ke(re){if(re.a===0)return Le(re.b);var se=re.c[re.d[re.a-1]];if(re.b.a!==0&&o(De(re.b),se))return Le(re.b);for(;--re.a,0re.a||o(ae[Pe],ae[We])){we[Q[Se]=Pe]=Se;break}we[Q[Se]=We]=Se,Se=He}}function Be(re,se){for(var Q=re.d,ae=re.e,we=re.c,Se=se,Pe=Q[Se];;){var He=Se>>1,We=Q[He];if(He==0||o(ae[We],ae[Pe])){we[Q[Se]=Pe]=Se;break}we[Q[Se]=We]=Se,Se=He}}function xe(){this.e=this.a=null,this.f=0,this.c=this.b=this.h=this.d=!1}function Re(re){return re.e.c.b}function Ee(re){return re.e.a.b}(s=pe.prototype).x=function(){K(this,0)},s.B=function(re,se){switch(re){case 100142:return;case 100140:switch(se){case 100130:case 100131:case 100132:case 100133:case 100134:return void(this.s=se)}break;case 100141:return void(this.m=!!se);default:return void z(this,100900)}z(this,100901)},s.y=function(re){switch(re){case 100142:return 0;case 100140:return this.s;case 100141:return this.m;default:z(this,100900)}return!1},s.A=function(re,se,Q){this.j[0]=re,this.j[1]=se,this.j[2]=Q},s.z=function(re,se){var Q=se||null;switch(re){case 100100:case 100106:this.h=Q;break;case 100104:case 100110:this.l=Q;break;case 100101:case 100107:this.k=Q;break;case 100102:case 100108:this.i=Q;break;case 100103:case 100109:this.p=Q;break;case 100105:case 100111:this.o=Q;break;case 100112:this.r=Q;break;default:z(this,100900)}},s.C=function(re,se){var Q=!1,ae=[0,0,0];K(this,2);for(var we=0;we<3;++we){var Se=re[we];Se<-1e150&&(Se=-1e150,Q=!0),1e150ae[qe]&&(ae[qe]=Ye,we[qe]=Q)}if(ae[1]-He[1]>ae[Q=0]-He[0]&&(Q=1),He[Q=ae[2]-He[2]>ae[Q]-He[Q]?2:Q]>=ae[Q])Pe[0]=0,Pe[1]=0,Pe[2]=1;else{for(He=We[Q],we=we[Q],We=[ae=0,0,0],He=[He.g[0]-we.g[0],He.g[1]-we.g[1],He.g[2]-we.g[2]],qe=[0,0,0],Q=Se.e;Q!==Se;Q=Q.e)qe[0]=Q.g[0]-we.g[0],qe[1]=Q.g[1]-we.g[1],qe[2]=Q.g[2]-we.g[2],We[0]=He[1]*qe[2]-He[2]*qe[1],We[1]=He[2]*qe[0]-He[0]*qe[2],We[2]=He[0]*qe[1]-He[1]*qe[0],ae<(Ye=We[0]*We[0]+We[1]*We[1]+We[2]*We[2])&&(ae=Ye,Pe[0]=We[0],Pe[1]=We[1],Pe[2]=We[2]);ae<=0&&(Pe[0]=Pe[1]=Pe[2]=0,Pe[C(He)]=1)}Se=!0}for(We=C(Pe),Q=this.b.c,ae=(We+1)%3,we=(We+2)%3,We=0>=1;)++m;if(f=1<>8&255,o[n++]=255&g,o[n++]=g>>8&255,o[n++]=(a!==null?128:0)|m,o[n++]=l,o[n++]=0,a!==null)for(var y=0,b=a.length;y>16&255,o[n++]=j>>8&255,o[n++]=255&j}if(i!==null){if(i<0||65535>8&255,o[n++]=0}var k=!1;this.addFrame=function(E,M,P,L,C,I){if(k===!0&&(--n,k=!1),I=I===void 0?{}:I,E<0||M<0||65535>=1;)++F;var B=1<>8&255,o[n++]=Z,o[n++]=0),o[n++]=44,o[n++]=255&E,o[n++]=E>>8&255,o[n++]=255&M,o[n++]=M>>8&255,o[n++]=255&P,o[n++]=P>>8&255,o[n++]=255&L,o[n++]=L>>8&255,o[n++]=A===!0?128|F-1:0,A===!0)for(var ee=0,ue=N.length;ee>16&255,o[n++]=T>>8&255,o[n++]=255&T}return n=function(D,G,W,$){D[G++]=W;var J=G++,ne=1<>=8,z-=8,G===J+256&&(D[J]=255,J=G++)}function me(Le){te|=Le<>=8,z-=8,G===J+256&&(D[J]=255,J=G++);pe===4096?(me(ne),pe=1+ie,K=W+1,ye={}):(1<>=m,f-=m,M==i)h=1+a,l=(1<<(m=n+1))-1,E=null;else{if(M==a)break;for(var P=M>8,++L;var I=C;if(p>=8;E!==null&&h<4096&&(k[h++]=E<<8|I,l+1<=h&&m<12&&(++m,l=l<<1|1)),E=M}}b!==p&&console.log("Warning, gif stream shorter than expected.")}try{v.GifWriter=s,v.GifReader=function(o){var u=0;if(o[u++]!==71||o[u++]!==73||o[u++]!==70||o[u++]!==56||(o[u++]+1&253)!=56||o[u++]!==97)throw new Error("Invalid GIF 87a/89a header.");var g=o[u++]|o[u++]<<8,p=o[u++]|o[u++]<<8,n=o[u++],i=1<<1+(7&n),a=(o[u++],o[u++],null),h=null,m=(n>>7&&(a=u,u+=3*(h=i)),!0),l=[],f=0,y=null,b=0,j=null;for(this.width=g,this.height=p;m&&u>2&7,u++;break;case 254:for(;;){if(!(0<=(E=o[u++])))throw Error("Invalid block size");if(E===0)break;u+=E}break;default:throw new Error("Unknown graphic control label: 0x"+o[u-1].toString(16))}break;case 44:var E,M=o[u++]|o[u++]<<8,P=o[u++]|o[u++]<<8,L=o[u++]|o[u++]<<8,C=o[u++]|o[u++]<<8,q=o[u++],I=q>>6&1,A=1<<1+(7&q),N=a,F=h,B=!1,q=(q>>7&&(B=!0,N=u,u+=3*(F=A)),u);for(u++;;){if(!(0<=(E=o[u++])))throw Error("Invalid block size");if(E===0)break;u+=E}l.push({x:M,y:P,width:L,height:C,has_local_palette:B,palette_offset:N,palette_size:F,data_offset:q,data_length:u-q,transparent_index:y,interlaced:!!I,delay:f,disposal:b});break;case 59:m=!1;break;default:throw new Error("Unknown gif block: 0x"+o[u-1].toString(16))}this.numFrames=function(){return l.length},this.loopCount=function(){return j},this.frameInfo=function(V){if(V<0||V>=l.length)throw new Error("Frame index out of range.");return l[V]},this.decodeAndBlitFrameBGRA=function(V,H){for(var V=this.frameInfo(V),Z=V.width*V.height,ee=new Uint8Array(Z),ue=(c(o,V.data_offset,ee,Z),V.palette_offset),T=V.transparent_index,D=(T===null&&(T=256),V.width),G=g-D,W=D,$=4*(V.y*g+V.x),J=4*((V.y+V.height)*g+V.x),ne=$,ce=4*G,ie=(V.interlaced===!0&&(ce+=4*g*7),8),pe=0,K=ee.length;pe>=1)),le===T?ne+=4:(z=o[ue+3*le],te=o[ue+3*le+1],le=o[ue+3*le+2],H[ne++]=le,H[ne++]=te,H[ne++]=z,H[ne++]=255),--W}},this.decodeAndBlitFrameRGBA=function(V,H){for(var V=this.frameInfo(V),Z=V.width*V.height,ee=new Uint8Array(Z),ue=(c(o,V.data_offset,ee,Z),V.palette_offset),T=V.transparent_index,D=(T===null&&(T=256),V.width),G=g-D,W=D,$=4*(V.y*g+V.x),J=4*((V.y+V.height)*g+V.x),ne=$,ce=4*G,ie=(V.interlaced===!0&&(ce+=4*g*7),8),pe=0,K=ee.length;pe>=1)),le===T?ne+=4:(z=o[ue+3*le],te=o[ue+3*le+1],le=o[ue+3*le+2],H[ne++]=z,H[ne++]=te,H[ne++]=le,H[ne++]=255),--W}}}}catch{}},{}],254:[function(t,x,v){(function(s){var c,o;c=this,o=function(u){function g(U){if(this==null)throw TypeError();var S,O=String(this),R=O.length,U=U?Number(U):0;if(!((U=U!=U?0:U)<0||R<=U))return 55296<=(S=O.charCodeAt(U))&&S<=56319&&U+1>>16-S;return _.tag>>>=S,_.bitcount-=S,R+O}function A(_,S){for(;_.bitcount<24;)_.tag|=_.source[_.sourceIndex++]<<_.bitcount,_.bitcount+=8;for(var O=0,R=0,U=0,X=_.tag;R=2*R+(1&X),X>>>=1,O+=S.table[++U],0<=(R-=S.table[U]););return _.tag=X,_.bitcount-=U,S.trans[O+R]}function N(_,S,O){for(;;){var R=A(_,S);if(R===256)return n;if(R<256)_.dest[_.destLen++]=R;else for(var U,X=I(_,f[R-=257],y[R]),R=A(_,O),Y=U=_.destLen-I(_,b[R],j[R]);Y>>=1,R=U,I(X,2,0)){case 0:O=function(Oe){for(var Je,ut;8this.x2&&(this.x2=_)),typeof S=="number"&&((isNaN(this.y1)||isNaN(this.y2))&&(this.y1=S,this.y2=S),Sthis.y2&&(this.y2=S))},Z.prototype.addX=function(_){this.addPoint(_,null)},Z.prototype.addY=function(_){this.addPoint(null,_)},Z.prototype.addBezier=function(_,S,O,R,U,X,Y,oe){var he=[_,S],fe=[O,R],je=[U,X],Me=[Y,oe];this.addPoint(_,S),this.addPoint(Y,oe);for(var Te=0;Te<=1;Te++){var be,Ue=6*he[Te]-12*fe[Te]+6*je[Te],Ae=-3*he[Te]+9*fe[Te]-9*je[Te]+3*Me[Te],Fe=3*fe[Te]-3*he[Te];Ae==0?Ue==0||0<(be=-Fe/Ue)&&be<1&&(Te===0&&this.addX(H(he[Te],fe[Te],je[Te],Me[Te],be)),Te===1&&this.addY(H(he[Te],fe[Te],je[Te],Me[Te],be))):(be=Math.pow(Ue,2)-4*Fe*Ae)<0||(0<(Fe=(-Ue+Math.sqrt(be))/(2*Ae))&&Fe<1&&(Te===0&&this.addX(H(he[Te],fe[Te],je[Te],Me[Te],Fe)),Te===1&&this.addY(H(he[Te],fe[Te],je[Te],Me[Te],Fe))),0<(Fe=(-Ue-Math.sqrt(be))/(2*Ae))&&Fe<1&&(Te===0&&this.addX(H(he[Te],fe[Te],je[Te],Me[Te],Fe)),Te===1&&this.addY(H(he[Te],fe[Te],je[Te],Me[Te],Fe))))}},Z.prototype.addQuad=function(_,S,O,R,U,X){O=_+2/3*(O-_),R=S+2/3*(R-S),this.addBezier(_,S,O,R,O+1/3*(U-_),R+1/3*(X-S),U,X)},ee.prototype.moveTo=function(_,S){this.commands.push({type:"M",x:_,y:S})},ee.prototype.lineTo=function(_,S){this.commands.push({type:"L",x:_,y:S})},ee.prototype.curveTo=ee.prototype.bezierCurveTo=function(_,S,O,R,U,X){this.commands.push({type:"C",x1:_,y1:S,x2:O,y2:R,x:U,y:X})},ee.prototype.quadTo=ee.prototype.quadraticCurveTo=function(_,S,O,R){this.commands.push({type:"Q",x1:_,y1:S,x:O,y:R})},ee.prototype.close=ee.prototype.closePath=function(){this.commands.push({type:"Z"})},ee.prototype.extend=function(_){var S;if(_.commands)_=_.commands;else if(_ instanceof Z)return S=_,this.moveTo(S.x1,S.y1),this.lineTo(S.x2,S.y1),this.lineTo(S.x2,S.y2),this.lineTo(S.x1,S.y2),void this.close();Array.prototype.push.apply(this.commands,_)},ee.prototype.getBoundingBox=function(){for(var _=new Z,S=0,O=0,R=0,U=0,X=0;X>8&255,255&_]},$.USHORT=J(2),W.SHORT=function(_){return[(_=32768<=_?-(65536-_):_)>>8&255,255&_]},$.SHORT=J(2),W.UINT24=function(_){return[_>>16&255,_>>8&255,255&_]},$.UINT24=J(3),W.ULONG=function(_){return[_>>24&255,_>>16&255,_>>8&255,255&_]},$.ULONG=J(4),W.LONG=function(_){return[(_=2147483648<=_?-(4294967296-_):_)>>24&255,_>>16&255,_>>8&255,255&_]},$.LONG=J(4),W.FIXED=W.ULONG,$.FIXED=$.ULONG,W.FWORD=W.SHORT,$.FWORD=$.SHORT,W.UFWORD=W.USHORT,$.UFWORD=$.USHORT,W.LONGDATETIME=function(_){return[0,0,0,0,_>>24&255,_>>16&255,_>>8&255,255&_]},$.LONGDATETIME=J(8),W.TAG=function(_){return D.argument(_.length===4,"Tag should be exactly 4 ASCII characters."),[_.charCodeAt(0),_.charCodeAt(1),_.charCodeAt(2),_.charCodeAt(3)]},$.TAG=J(4),W.Card8=W.BYTE,$.Card8=$.BYTE,W.Card16=W.USHORT,$.Card16=$.USHORT,W.OffSize=W.BYTE,$.OffSize=$.BYTE,W.SID=W.USHORT,$.SID=$.USHORT,W.NUMBER=function(_){return-107<=_&&_<=107?[_+139]:108<=_&&_<=1131?[247+((_-=108)>>8),255&_]:-1131<=_&&_<=-108?[251+((_=-_-108)>>8),255&_]:-32768<=_&&_<=32767?W.NUMBER16(_):W.NUMBER32(_)},$.NUMBER=function(_){return W.NUMBER(_).length},W.NUMBER16=function(_){return[28,_>>8&255,255&_]},$.NUMBER16=J(3),W.NUMBER32=function(_){return[29,_>>24&255,_>>16&255,_>>8&255,255&_]},$.NUMBER32=J(5),W.REAL=function(_){for(var S=_.toString(),O=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(S),R=(O&&(O=parseFloat("1e"+((O[2]?+O[2]:0)+O[1].length)),S=(Math.round(_*O)/O).toString()),""),U=0,X=S.length;U>8&255,S[S.length]=255&R}return S},$.UTF16=function(_){return 2*_.length};var ne,ce={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"},ie=(G.MACSTRING=function(_,S,O,R){var U=ce[R];if(U!==void 0){for(var X="",Y=0;Y>8&255,Te+256&255)}return fe})(_,R,S);return S},W.INDEX=function(_){for(var S=1,O=[S],R=[],U=0;U<_.length;U+=1){var X=W.OBJECT(_[U]);Array.prototype.push.apply(R,X),S+=X.length,O.push(S)}if(R.length===0)return[0,0];for(var Y=[],oe=1+Math.floor(Math.log(S)/Math.log(2))/8|0,he=[void 0,W.BYTE,W.USHORT,W.UINT24,W.ULONG][oe],fe=0;fe>8,S[je+1]=255&Me,S=S.concat(R[fe])}return S},$.TABLE=function(_){for(var S=0,O=_.fields.length,R=0;R>1,oe.skip("uShort",3),Fe.glyphIndexMap={};for(var ut,et=new Ee.Parser(Ce,Oe+Je+14),tt=new Ee.Parser(Ce,Oe+Je+16+2*ut),ct=new Ee.Parser(Ce,Oe+Je+16+4*ut),Mt=new Ee.Parser(Ce,Oe+Je+16+6*ut),Ut=Oe+Je+16+8*ut,qt=0;qt>4,Y=15&Y;if(X==15||(R+=U[X],Y==15))break;R+=U[Y]}return parseFloat(R)}if(32<=S&&S<=246)return S-139;if(247<=S&&S<=250)return 256*(S-247)+_.parseByte()+108;if(251<=S&&S<=254)return 256*-(S-251)-_.parseByte()-108;throw new Error("Invalid b0 "+S)}function lr(_,S,O){var R=new Ee.Parser(_,S=S!==void 0?S:0),U=[],X=[];for(O=O!==void 0?O:_.length;R.relativeOffset>1,be.length=0,Ae=!0}return function tt(ct){for(var Mt,Ut,qt,ur,cr,$r,Tt,Pt,wt,dr,Dt,sr,At=0;AtMath.abs(sr-Oe)?Ce=Dt+be.shift():Oe=sr+be.shift(),Te.curveTo(R,U,X,Y,Tt,Pt),Te.curveTo(wt,dr,Dt,sr,Ce,Oe);break;default:console.log("Glyph "+S.index+": unknown operator 1200"+er),be.length=0}break;case 14:0>3;break;case 21:2>16),At+=2;break;case 29:cr=be.pop()+_.gsubrsBias,($r=_.gsubrs[cr])&&tt($r);break;case 30:for(;0=O.begin&&_=we.length&&(X=R.parseChar(),O.names.push(R.parseString(X)));break;case 2.5:O.numberOfGlyphs=R.parseUShort(),O.offset=new Array(O.numberOfGlyphs);for(var oe=0;oeMe.value.tag?1:-1}),S.fields=S.fields.concat(R),S.fields=S.fields.concat(U),S}function Ll(_,S,O){for(var R=0;R 123 are reserved for internal usage");be|=1<>>1,X=_[U].tag;if(X===S)return U;X>>1,X=_[U];if(X===S)return U;X>>1,Y=(U=_[X]).start;if(Y===S)return U;Y(U=_[O-1]).end?0:U}function gs(_,S){this.font=_,this.tableName=S}function vs(_){gs.call(this,_,"gpos")}function rn(_){gs.call(this,_,"gsub")}function Fl(_,S,O){for(var R=_.subtables,U=0;US.points.length-1||R.matchedPoints[1]>U.points.length-1)throw Error("Matched points out of range in "+S.name);var Y=S.points[R.matchedPoints[0]],oe=U.points[R.matchedPoints[1]],R={xScale:R.xScale,scale01:R.scale01,scale10:R.scale10,yScale:R.yScale,dx:0,dy:0},oe=Ti([oe],R)[0];R.dx=Y.x-oe.x,R.dy=Y.y-oe.y,X=Ti(U.points,R)}S.points=S.points.concat(X)}}return Bl(S.points)}(vs.prototype=gs.prototype={searchTag:Ei,binSearch:Il,getTable:function(_){var S=this.font.tables[this.tableName];return S=!S&&_?this.font.tables[this.tableName]=this.createDefaultTable():S},getScriptNames:function(){var _=this.getTable();return _?_.scripts.map(function(S){return S.tag}):[]},getDefaultScriptName:function(){var _=this.getTable();if(_){for(var S=!1,O=0;O<_.scripts.length;O++){var R=_.scripts[O].tag;if(R==="DFLT")return R;R==="latn"&&(S=!0)}return S?"latn":void 0}},getScriptTable:function(_,S){var O,R=this.getTable(S);if(R)return O=R.scripts,0<=(R=Ei(R.scripts,_=_||"DFLT"))?O[R].script:S?(O.splice(-1-R,0,S={tag:_,script:{defaultLangSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]},langSysRecords:[]}}),S.script):void 0},getLangSysTable:function(U,S,O){var R,U=this.getScriptTable(U,O);if(U)return S&&S!=="dflt"&&S!=="DFLT"?0<=(R=Ei(U.langSysRecords,S))?U.langSysRecords[R].langSys:O?(U.langSysRecords.splice(-1-R,0,O={tag:S,langSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]}}),O.langSys):void 0:U.defaultLangSys},getFeatureTable:function(_,S,O,R){if(_=this.getLangSysTable(_,S,R),_){for(var U,X=_.featureIndexes,Y=this.font.tables[this.tableName].features,oe=0;oe=Y[S-1].tag,"Features must be added in alphabetical order."),Y.push(U={tag:O,feature:{params:0,lookupListIndexes:[]}}),X.push(S),U.feature}},getLookupTables:function(X,S,O,R,U){var X=this.getFeatureTable(X,S,O,U),Y=[];if(X){for(var oe,he=X.lookupListIndexes,fe=this.font.tables[this.tableName].lookups,je=0;je",X),S.stack.push(Math.round(64*X))}function Mi(_,S){var O=S.stack,R=O.pop(),U=S.fv,X=S.pv,Y=S.ppem,oe=S.deltaBase+16*(_-1),he=S.deltaShift,fe=S.z0;u.DEBUG&&console.log(S.step,"DELTAP["+_+"]",R,O);for(var je=0;je>4)===Y&&(0<=(Te=(15&Te)-8)&&Te++,u.DEBUG&&console.log(S.step,"DELTAPFIX",Me,"by",Te*he),Me=fe[Me],U.setRelative(Me,Me,Te*he,X))}}function _s(_,S){var O=S.stack,R=O.pop();u.DEBUG&&console.log(S.step,"ROUND[]"),O.push(64*S.round(R/64))}function Ci(_,S){var O=S.stack,R=O.pop(),U=S.ppem,X=S.deltaBase+16*(_-1),Y=S.deltaShift;u.DEBUG&&console.log(S.step,"DELTAC["+_+"]",R,O);for(var oe=0;oe>4)===U&&(0<=(fe=(15&fe)-8)&&fe++,fe=fe*Y,u.DEBUG&&console.log(S.step,"DELTACFIX",he,"by",fe),S.cvt[he]+=fe)}}function iu(_,S){var O,U=S.stack,R=U.pop(),U=U.pop(),X=S.z2[R],Y=S.z1[U];u.DEBUG&&console.log(S.step,"SDPVTL["+_+"]",R,U),R=_?(O=X.y-Y.y,Y.x-X.x):(O=Y.x-X.x,Y.y-X.y),S.dpv=Ro(O,R)}function _n(_,S){var O=S.stack,R=S.prog,U=S.ip;u.DEBUG&&console.log(S.step,"PUSHB["+_+"]");for(var X=0;X<_;X++)O.push(R[++U]);S.ip=U}function wn(_,S){var O=S.ip,R=S.prog,U=S.stack;u.DEBUG&&console.log(S.ip,"PUSHW["+_+"]");for(var X=0;X<_;X++){var Y=R[++O]<<8|R[++O];32768&Y&&(Y=-(1+(65535^Y))),U.push(Y)}S.ip=O}function Qe(_,S,O,R,U,X){var Y,oe,fe=X.stack,he=_&&fe.pop(),fe=fe.pop(),je=X.rp0,je=X.z0[je],Me=X.z1[fe],Te=X.minDis,be=X.fv,Ue=X.dpv,Ae=Y=Ue.distance(Me,je,!0,!0),Fe=0<=Ae?1:-1;Ae=Math.abs(Ae),_&&(oe=X.cvt[he],R&&Math.abs(Ae-oe)":"_")+(R?"R":"_")+(U===0?"Gr":U===1?"Bl":U===2?"Wh":"")+"]",_?he+"("+X.cvt[he]+","+oe+")":"",fe,"(d =",Y,"->",Fe*Ae,")"),X.rp1=X.rp0,X.rp2=fe,S&&(X.rp0=fe)}Vl.prototype.exec=function(_,S){if(typeof S!="number")throw new Error("Point size is not a number!");if(!(2",R),oe.interpolate(Me,X,Y,he),oe.touch(Me)}_.loop=1},ru.bind(void 0,0),ru.bind(void 0,1),function(_){for(var S=_.stack,O=_.rp0,R=_.z0[O],U=_.loop,X=_.fv,Y=_.pv,oe=_.z1;U--;){var he=S.pop(),fe=oe[he];u.DEBUG&&console.log(_.step,(1<_.loop?"loop "+(_.loop-U)+": ":"")+"ALIGNRP[]",he),X.setRelative(fe,R,0,Y),X.touch(fe)}_.loop=1},function(_){u.DEBUG&&console.log(_.step,"RTDG[]"),_.round=wh},nu.bind(void 0,0),nu.bind(void 0,1),function(_){var S=_.prog,O=_.ip,R=_.stack,U=S[++O];u.DEBUG&&console.log(_.step,"NPUSHB[]",U);for(var X=0;X"u"?Lh:Ih)(_,function(O,R){if(O)return S(O);var U;try{U=Oi(R)}catch(X){return S(X,null)}return S(null,U)})},u.loadSync=function(_){return Oi(Nl(t("fs").readFileSync(_)))},Object.defineProperty(u,"__esModule",{value:!0})},o(typeof v=="object"&&x!==void 0?v:c.opentype={})}).call(this,t("buffer").Buffer)},{buffer:4,fs:2}],255:[function(t,x,v){(function(s){function c(g,p){for(var n=0,i=g.length-1;0<=i;i--){var a=g[i];a==="."?g.splice(i,1):a===".."?(g.splice(i,1),n++):n&&(g.splice(i,1),n--)}if(p)for(;n--;)g.unshift("..");return g}function o(g,p){if(g.filter)return g.filter(p);for(var n=[],i=0;i'.concat(f,"").concat(h,""),this.dummyDOM||(this.dummyDOM=document.getElementById(l).parentNode),this.descriptions?this.descriptions.fallbackElements||(this.descriptions.fallbackElements={}):this.descriptions={fallbackElements:{}},this.descriptions.fallbackElements[a]?this.descriptions.fallbackElements[a].innerHTML!==f&&(this.descriptions.fallbackElements[a].innerHTML=f):this._describeElementHTML("fallback",a,f),m===this.LABEL&&(this.descriptions.labelElements||(this.descriptions.labelElements={}),this.descriptions.labelElements[a]?this.descriptions.labelElements[a].innerHTML!==f&&(this.descriptions.labelElements[a].innerHTML=f):this._describeElementHTML("label",a,f)))},s.default.prototype._describeHTML=function(a,h){var m,l=this.canvas.id;a==="fallback"?(this.dummyDOM.querySelector("#".concat(l+c))?this.dummyDOM.querySelector("#"+l+u).insertAdjacentHTML("beforebegin",'

')):(m='

'),this.dummyDOM.querySelector("#".concat(l,"accessibleOutput"))?this.dummyDOM.querySelector("#".concat(l,"accessibleOutput")).insertAdjacentHTML("beforebegin",m):this.dummyDOM.querySelector("#".concat(l)).innerHTML=m),this.descriptions.fallback=this.dummyDOM.querySelector("#".concat(l).concat(o)),this.descriptions.fallback.innerHTML=h):a==="label"&&(this.dummyDOM.querySelector("#".concat(l+g))?this.dummyDOM.querySelector("#".concat(l+n))&&this.dummyDOM.querySelector("#".concat(l+n)).insertAdjacentHTML("beforebegin",'

')):(m='

'),this.dummyDOM.querySelector("#".concat(l,"accessibleOutputLabel"))?this.dummyDOM.querySelector("#".concat(l,"accessibleOutputLabel")).insertAdjacentHTML("beforebegin",m):this.dummyDOM.querySelector("#"+l).insertAdjacentHTML("afterend",m)),this.descriptions.label=this.dummyDOM.querySelector("#"+l+p),this.descriptions.label.innerHTML=h)},s.default.prototype._describeElementHTML=function(a,h,m){var l,f=this.canvas.id;a==="fallback"?(this.dummyDOM.querySelector("#".concat(f+c))?this.dummyDOM.querySelector("#"+f+u)||this.dummyDOM.querySelector("#"+f+o).insertAdjacentHTML("afterend",'
Canvas elements and their descriptions
')):(l='
Canvas elements and their descriptions
'),this.dummyDOM.querySelector("#".concat(f,"accessibleOutput"))?this.dummyDOM.querySelector("#".concat(f,"accessibleOutput")).insertAdjacentHTML("beforebegin",l):this.dummyDOM.querySelector("#"+f).innerHTML=l),(l=document.createElement("tr")).id=f+"_fte_"+h,this.dummyDOM.querySelector("#"+f+u).appendChild(l),this.descriptions.fallbackElements[h]=this.dummyDOM.querySelector("#".concat(f).concat("_fte_").concat(h)),this.descriptions.fallbackElements[h].innerHTML=m):a==="label"&&(this.dummyDOM.querySelector("#".concat(f+g))?this.dummyDOM.querySelector("#".concat(f+n))||this.dummyDOM.querySelector("#"+f+p).insertAdjacentHTML("afterend",'
')):(l='
'),this.dummyDOM.querySelector("#".concat(f,"accessibleOutputLabel"))?this.dummyDOM.querySelector("#".concat(f,"accessibleOutputLabel")).insertAdjacentHTML("beforebegin",l):this.dummyDOM.querySelector("#"+f).insertAdjacentHTML("afterend",l)),(a=document.createElement("tr")).id=f+"_lte_"+h,this.dummyDOM.querySelector("#"+f+n).appendChild(a),this.descriptions.labelElements[h]=this.dummyDOM.querySelector("#".concat(f).concat("_lte_").concat(h)),this.descriptions.labelElements[h].innerHTML=m)},t=s.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.string.ends-with":195,"core-js/modules/es.string.replace":201}],261:[function(t,x,v){t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.from"),t("core-js/modules/es.array.map"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.from"),t("core-js/modules/es.array.map"),t("core-js/modules/es.string.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t},t.default.prototype._updateGridOutput=function(s){var c,o,u,g;this.dummyDOM.querySelector("#".concat(s,"_summary"))&&(c=this._accessibleOutputs[s],u=function(p,n,i,a){return n="".concat(n," canvas, ").concat(i," by ").concat(a," pixels, contains ").concat(p[0]),n=(p[0]===1?"".concat(n," shape: "):"".concat(n," shapes: ")).concat(p[1]),n}((o=function(p,n){var i,a="",h="",m=0;for(i in n){var l,f=0;for(l in n[i]){var y='
  • ').concat(n[i][l].color," ").concat(i,",");i==="line"?y+=" location = ".concat(n[i][l].pos,", length = ").concat(n[i][l].length," pixels"):(y+=" location = ".concat(n[i][l].pos),i!=="point"&&(y+=", area = ".concat(n[i][l].area," %")),y+="
  • "),a+=y,f++,m++}h=1').concat(n[i][f].color," ").concat(i,"
    "):'').concat(n[i][f].color," ").concat(i," midpoint"),l[n[i][f].loc.locY][n[i][f].loc.locX]?l[n[i][f].loc.locY][n[i][f].loc.locX]=l[n[i][f].loc.locY][n[i][f].loc.locX]+" "+y:l[n[i][f].loc.locY][n[i][f].loc.locX]=y,h++}for(a in l){var b,j="";for(b in l[a])j+="",l[a][b]!==void 0&&(j+=l[a][b]),j+="";m=m+j+""}return m}(s,this.ingredients.shapes),u!==c.summary.innerHTML&&(c.summary.innerHTML=u),g!==c.map.innerHTML&&(c.map.innerHTML=g),o.details!==c.shapeDetails.innerHTML&&(c.shapeDetails.innerHTML=o.details),this._accessibleOutputs[s]=c)},t=t.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.from":161,"core-js/modules/es.array.map":167,"core-js/modules/es.string.iterator":197}],262:[function(t,x,v){t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.fill"),t("core-js/modules/es.array.from"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.map"),t("core-js/modules/es.number.to-fixed"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.fill"),t("core-js/modules/es.array.map"),t("core-js/modules/es.number.to-fixed"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var s=(t=t("../core/main"))&&t.__esModule?t:{default:t};function c(u){return function(g){if(Array.isArray(g)){for(var p=0,n=new Array(g.length);p')):this.dummyDOM.querySelector("#".concat(a)).innerHTML='
    '))):g==="Label"&&(p=a+u+(h=g),this.dummyDOM.querySelector("#".concat(n=a+"accessibleOutput"+g))||(this.dummyDOM.querySelector("#".concat(a,"_Label"))?this.dummyDOM.querySelector("#".concat(a,"_Label")):this.dummyDOM.querySelector("#".concat(a))).insertAdjacentHTML("afterend",'
    '))),this._accessibleOutputs[p]={},u==="textOutput"?(h="#".concat(a,"gridOutput").concat(h),i='
    Text Output

      '),this.dummyDOM.querySelector(h)?this.dummyDOM.querySelector(h).insertAdjacentHTML("beforebegin",i):this.dummyDOM.querySelector("#".concat(n)).innerHTML=i,this._accessibleOutputs[p].list=this.dummyDOM.querySelector("#".concat(p,"_list"))):u==="gridOutput"&&(h="#".concat(a,"textOutput").concat(h),i='
      Grid Output

        '),this.dummyDOM.querySelector(h)?this.dummyDOM.querySelector(h).insertAdjacentHTML("afterend",i):this.dummyDOM.querySelector("#".concat(n)).innerHTML=i,this._accessibleOutputs[p].map=this.dummyDOM.querySelector("#".concat(p,"_map"))),this._accessibleOutputs[p].shapeDetails=this.dummyDOM.querySelector("#".concat(p,"_shapeDetails")),this._accessibleOutputs[p].summary=this.dummyDOM.querySelector("#".concat(p,"_summary"))},s.default.prototype._updateAccsOutput=function(){var u=this.canvas.id;JSON.stringify(this.ingredients.shapes)===this.ingredients.pShapes&&this.ingredients.colors.background===this.ingredients.pBackground||(this.ingredients.pShapes=JSON.stringify(this.ingredients.shapes),this._accessibleOutputs.text&&this._updateTextOutput(u+"textOutput"),this._accessibleOutputs.grid&&this._updateGridOutput(u+"gridOutput"),this._accessibleOutputs.textLabel&&this._updateTextOutput(u+"textOutputLabel"),this._accessibleOutputs.gridLabel&&this._updateGridOutput(u+"gridOutputLabel"))},s.default.prototype._accsBackground=function(u){this.ingredients.pShapes=JSON.stringify(this.ingredients.shapes),this.ingredients.pBackground=this.ingredients.colors.background,this.ingredients.shapes={},this.ingredients.colors.backgroundRGBA!==u&&(this.ingredients.colors.backgroundRGBA=u,this.ingredients.colors.background=this._rgbColorName(u))},s.default.prototype._accsCanvasColors=function(u,g){u==="fill"?this.ingredients.colors.fillRGBA!==g&&(this.ingredients.colors.fillRGBA=g,this.ingredients.colors.fill=this._rgbColorName(g)):u==="stroke"&&this.ingredients.colors.strokeRGBA!==g&&(this.ingredients.colors.strokeRGBA=g,this.ingredients.colors.stroke=this._rgbColorName(g))},s.default.prototype._accsOutput=function(u,g){u==="ellipse"&&g[2]===g[3]?u="circle":u==="rectangle"&&g[2]===g[3]&&(u="square");var p,n,i={},a=!0,h=function(l,f){var y;return l=l==="rectangle"||l==="ellipse"||l==="arc"||l==="circle"||l==="square"?(y=Math.round(f[0]+f[2]/2),Math.round(f[1]+f[3]/2)):l==="triangle"?(y=(f[0]+f[2]+f[4])/3,(f[1]+f[3]+f[5])/3):l==="quadrilateral"?(y=(f[0]+f[2]+f[4]+f[6])/4,(f[1]+f[3]+f[5]+f[7])/4):l==="line"?(y=(f[0]+f[2])/2,(f[1]+f[3])/2):(y=f[0],f[1]),[y,l]}(u,g);if(u==="line"?(i.color=this.ingredients.colors.stroke,i.length=Math.round(this.dist(g[0],g[1],g[2],g[3])),p=this._getPos(g[0],[1]),n=this._getPos(g[2],[3]),i.loc=o(h,this.width,this.height),i.pos=p===n?"at ".concat(p):"from ".concat(p," to ").concat(n)):(u==="point"?i.color=this.ingredients.colors.stroke:(i.color=this.ingredients.colors.fill,i.area=this._getArea(u,g)),i.pos=this._getPos.apply(this,c(h)),i.loc=o(h,this.width,this.height)),this.ingredients.shapes[u]){if(this.ingredients.shapes[u]!==[i]){for(var m in this.ingredients.shapes[u])JSON.stringify(this.ingredients.shapes[u][m])===JSON.stringify(i)&&(a=!1);a===!0&&this.ingredients.shapes[u].push(i)}}else this.ingredients.shapes[u]=[i]},s.default.prototype._getPos=function(n,p){var n=new DOMPointReadOnly(n,p),p=this._renderer.isP3D?new DOMMatrix(this._renderer.uMVMatrix.mat4):this.drawingContext.getTransform(),n=n.matrixTransform(p),p=n.x,n=n.y,i=this.width*this._pixelDensity,a=this.height*this._pixelDensity;return p<.4*i?n<.4*a?"top left":.6*aMath.PI?i+=n:i-=n)):u==="ellipse"||u==="circle"?i=3.14*g[2]/2*g[3]/2:u==="line"||u==="point"?i=0:u==="quadrilateral"?i=Math.abs((g[6]+g[0])*(g[7]-g[1])+(g[0]+g[2])*(g[1]-g[3])+(g[2]+g[4])*(g[3]-g[5])+(g[4]+g[6])*(g[5]-g[7]))/2:u==="rectangle"||u==="square"?i=g[2]*g[3]:u==="triangle"&&(i=Math.abs(g[0]*(g[3]-g[5])+g[2]*(g[5]-g[1])+g[4]*(g[1]-g[3]))/2),this.width*this._pixelDensity),h=this.height*this._pixelDensity,m=[new DOMPoint(0,0),new DOMPoint(a,0),new DOMPoint(a,h),new DOMPoint(0,h)],l=(this._renderer.isP3D?new DOMMatrix(this._renderer.uMVMatrix.mat4):this.drawingContext.getTransform()).inverse(),f=m.map(function(b){return b.matrixTransform(l)}),y=Math.abs((f[3].x+f[0].x)*(f[3].y-f[0].y)+(f[0].x+f[1].x)*(f[0].y-f[1].y)+(f[1].x+f[2].x)*(f[1].y-f[2].y)+(f[2].x+f[3].x)*(f[2].y-f[3].y))/2;return Math.round(100*i/y)},t=s.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.fill":155,"core-js/modules/es.array.from":161,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.map":167,"core-js/modules/es.number.to-fixed":180,"core-js/modules/es.object.to-string":187,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/web.dom-collections.iterator":243}],263:[function(t,x,v){t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.concat"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t},t.default.prototype._updateTextOutput=function(s){var c,o,u,g;this.dummyDOM.querySelector("#".concat(s,"_summary"))&&(c=this._accessibleOutputs[s],u=function(p,n,i,a){return i="Your output is a, ".concat(i," by ").concat(a," pixels, ").concat(n," canvas containing the following"),i=p===1?"".concat(i," shape:"):"".concat(i," ").concat(p," shapes:"),i}((o=function(p,n){var i,a="",h=0;for(i in n)for(var m in n[i]){var l='
      • ').concat(n[i][m].color," ").concat(i,"");i==="line"?l+=", ".concat(n[i][m].pos,", ").concat(n[i][m].length," pixels long.
      • "):(l+=", at ".concat(n[i][m].pos),i!=="point"&&(l+=", covering ".concat(n[i][m].area,"% of the canvas")),l+="."),a+=l,h++}return{numShapes:h,listShapes:a}}(s,this.ingredients.shapes)).numShapes,this.ingredients.colors.background,this.width,this.height),g=function(p,n){var i,a="",h=0;for(i in n)for(var m in n[i]){var l='').concat(n[i][m].color," ").concat(i,"");i==="line"?l+="location = ".concat(n[i][m].pos,"length = ").concat(n[i][m].length," pixels"):(l+="location = ".concat(n[i][m].pos,""),i!=="point"&&(l+=" area = ".concat(n[i][m].area,"%")),l+=""),a+=l,h++}return a}(s,this.ingredients.shapes),u!==c.summary.innerHTML&&(c.summary.innerHTML=u),o.listShapes!==c.list.innerHTML&&(c.list.innerHTML=o.listShapes),g!==c.shapeDetails.innerHTML&&(c.shapeDetails.innerHTML=g),this._accessibleOutputs[s]=c)},t=t.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152}],264:[function(t,x,v){var s=(s=t("./core/main"))&&s.__esModule?s:{default:s};t("./core/constants"),t("./core/environment"),t("./core/friendly_errors/stacktrace"),t("./core/friendly_errors/validate_params"),t("./core/friendly_errors/file_errors"),t("./core/friendly_errors/fes_core"),t("./core/friendly_errors/sketch_reader"),t("./core/helpers"),t("./core/legacy"),t("./core/preload"),t("./core/p5.Element"),t("./core/p5.Graphics"),t("./core/p5.Renderer"),t("./core/p5.Renderer2D"),t("./core/rendering"),t("./core/shim"),t("./core/structure"),t("./core/transform"),t("./core/shape/2d_primitives"),t("./core/shape/attributes"),t("./core/shape/curves"),t("./core/shape/vertex"),t("./accessibility/outputs"),t("./accessibility/textOutput"),t("./accessibility/gridOutput"),t("./accessibility/color_namer"),t("./color/color_conversion"),t("./color/creating_reading"),t("./color/p5.Color"),t("./color/setting"),t("./data/p5.TypedDict"),t("./data/local_storage.js"),t("./dom/dom"),t("./accessibility/describe"),t("./events/acceleration"),t("./events/keyboard"),t("./events/mouse"),t("./events/touch"),t("./image/filters"),t("./image/image"),t("./image/loading_displaying"),t("./image/p5.Image"),t("./image/pixels"),t("./io/files"),t("./io/p5.Table"),t("./io/p5.TableRow"),t("./io/p5.XML"),t("./math/calculation"),t("./math/math"),t("./math/noise"),t("./math/p5.Vector"),t("./math/random"),t("./math/trigonometry"),t("./typography/attributes"),t("./typography/loading_displaying"),t("./typography/p5.Font"),t("./utilities/array_functions"),t("./utilities/conversion"),t("./utilities/string_functions"),t("./utilities/time_date"),t("./webgl/3d_primitives"),t("./webgl/interaction"),t("./webgl/light"),t("./webgl/loading"),t("./webgl/material"),t("./webgl/p5.Camera"),t("./webgl/p5.DataArray"),t("./webgl/p5.Geometry"),t("./webgl/p5.Matrix"),t("./webgl/p5.RendererGL.Immediate"),t("./webgl/p5.RendererGL"),t("./webgl/p5.RendererGL.Retained"),t("./webgl/p5.Framebuffer"),t("./webgl/p5.Shader"),t("./webgl/p5.RenderBuffer"),t("./webgl/p5.Texture"),t("./webgl/text"),t("./core/init"),x.exports=s.default},{"./accessibility/color_namer":259,"./accessibility/describe":260,"./accessibility/gridOutput":261,"./accessibility/outputs":262,"./accessibility/textOutput":263,"./color/color_conversion":265,"./color/creating_reading":266,"./color/p5.Color":267,"./color/setting":268,"./core/constants":269,"./core/environment":270,"./core/friendly_errors/fes_core":271,"./core/friendly_errors/file_errors":272,"./core/friendly_errors/sketch_reader":273,"./core/friendly_errors/stacktrace":274,"./core/friendly_errors/validate_params":275,"./core/helpers":276,"./core/init":277,"./core/legacy":279,"./core/main":280,"./core/p5.Element":281,"./core/p5.Graphics":282,"./core/p5.Renderer":283,"./core/p5.Renderer2D":284,"./core/preload":285,"./core/rendering":286,"./core/shape/2d_primitives":287,"./core/shape/attributes":288,"./core/shape/curves":289,"./core/shape/vertex":290,"./core/shim":291,"./core/structure":292,"./core/transform":293,"./data/local_storage.js":294,"./data/p5.TypedDict":295,"./dom/dom":296,"./events/acceleration":297,"./events/keyboard":298,"./events/mouse":299,"./events/touch":300,"./image/filters":301,"./image/image":302,"./image/loading_displaying":303,"./image/p5.Image":304,"./image/pixels":305,"./io/files":306,"./io/p5.Table":307,"./io/p5.TableRow":308,"./io/p5.XML":309,"./math/calculation":310,"./math/math":311,"./math/noise":312,"./math/p5.Vector":313,"./math/random":314,"./math/trigonometry":315,"./typography/attributes":316,"./typography/loading_displaying":317,"./typography/p5.Font":318,"./utilities/array_functions":319,"./utilities/conversion":320,"./utilities/string_functions":321,"./utilities/time_date":322,"./webgl/3d_primitives":323,"./webgl/interaction":325,"./webgl/light":326,"./webgl/loading":327,"./webgl/material":328,"./webgl/p5.Camera":329,"./webgl/p5.DataArray":330,"./webgl/p5.Framebuffer":331,"./webgl/p5.Geometry":332,"./webgl/p5.Matrix":333,"./webgl/p5.RenderBuffer":334,"./webgl/p5.RendererGL":337,"./webgl/p5.RendererGL.Immediate":335,"./webgl/p5.RendererGL.Retained":336,"./webgl/p5.Shader":338,"./webgl/p5.Texture":339,"./webgl/text":340}],265:[function(t,x,v){Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t},t.default.ColorConversion={_hsbaToHSLA:function(s){var c=s[0],o=s[1],u=s[2],g=(2-o)*u/2;return g!=0&&(g==1?o=0:g<.5?o/=2-o:o=o*u/(2-2*g)),[c,o,g,s[3]]},_hsbaToRGBA:function(s){var c,o,u,g,p,n=6*s[0],i=s[1],a=s[2];return i===0?[a,a,a,s[3]]:(o=a*(1-i),u=a*(1-i*(n-(c=Math.floor(n)))),i=a*(1-i*(1+c-n)),n=c===1?(g=u,p=a,o):c===2?(g=o,p=a,i):c===3?(g=o,p=u,a):c===4?(g=i,p=o,a):c===5?(g=a,p=o,u):(g=a,p=i,o),[g,p,n,s[3]])},_hslaToHSBA:function(s){var c=s[0],o=s[1],u=s[2],g=u<.5?(1+o)*u:u+o-u*o;return[c,o=2*(g-u)/g,g,s[3]]},_hslaToRGBA:function(s){var c,o=6*s[0],u=s[1],g=s[2];return u===0?[g,g,g,s[3]]:[(c=function(p,n,i){return p<0?p+=6:6<=p&&(p-=6),p<1?n+(i-n)*p:p<3?i:p<4?n+(i-n)*(4-p):n})(2+o,u=2*g-(g=g<.5?(1+u)*g:g+u-g*u),g),c(o,u,g),c(o-2,u,g),s[3]]},_rgbaToHSBA:function(s){var c,o,u=s[0],g=s[1],p=s[2],n=Math.max(u,g,p),i=n-Math.min(u,g,p);return i==0?o=c=0:(o=i/n,u===n?c=(g-p)/i:g===n?c=2+(p-u)/i:p===n&&(c=4+(u-g)/i),c<0?c+=6:6<=c&&(c-=6)),[c/6,o,n,s[3]]},_rgbaToHSLA:function(s){var c,o,u=s[0],g=s[1],p=s[2],n=Math.max(u,g,p),a=Math.min(u,g,p),i=n+a,a=n-a;return a==0?o=c=0:(o=i<1?a/i:a/(2-i),u===n?c=(g-p)/a:g===n?c=2+(p-u)/a:p===n&&(c=4+(u-g)/a),c<0?c+=6:6<=c&&(c-=6)),[c/6,o,i/2,s[3]]}},t=t.default.ColorConversion,v.default=t},{"../core/main":280}],266:[function(t,x,v){function s(n){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(i){return typeof i}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":typeof i})(n)}function c(n){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(i){return s(i)}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":s(i)})(n)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.map"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.map"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=(p=t("../core/main"))&&p.__esModule?p:{default:p},u=function(n){if(n&&n.__esModule)return n;if(n===null||c(n)!=="object"&&typeof n!="function")return{default:n};var i=g();if(i&&i.has(n))return i.get(n);var a,h={},m=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(a in n){var l;Object.prototype.hasOwnProperty.call(n,a)&&((l=m?Object.getOwnPropertyDescriptor(n,a):null)&&(l.get||l.set)?Object.defineProperty(h,a,l):h[a]=n[a])}return h.default=n,i&&i.set(n,h),h}(t("../core/constants"));function g(){var n;return typeof WeakMap!="function"?null:(n=new WeakMap,g=function(){return n},n)}t("./p5.Color"),t("../core/friendly_errors/validate_params"),t("../core/friendly_errors/file_errors"),t("../core/friendly_errors/fes_core"),o.default.prototype.alpha=function(n){return o.default._validateParameters("alpha",arguments),this.color(n)._getAlpha()},o.default.prototype.blue=function(n){return o.default._validateParameters("blue",arguments),this.color(n)._getBlue()},o.default.prototype.brightness=function(n){return o.default._validateParameters("brightness",arguments),this.color(n)._getBrightness()},o.default.prototype.color=function(){for(var n,i=arguments.length,a=new Array(i),h=0;hl[0]?l[0]+=1:m[0]+=1),1<=(h=this.lerp(m[0],l[0],a))&&--h),n=this.lerp(m[1],l[1],a),i=this.lerp(m[2],l[2],a),m=this.lerp(m[3],l[3],a),h*=y[f][0],n*=y[f][1],i*=y[f][2],m*=y[f][3],this.color(h,n,i,m)},o.default.prototype.lightness=function(n){return o.default._validateParameters("lightness",arguments),this.color(n)._getLightness()},o.default.prototype.red=function(n){return o.default._validateParameters("red",arguments),this.color(n)._getRed()},o.default.prototype.saturation=function(n){return o.default._validateParameters("saturation",arguments),this.color(n)._getSaturation()};var p=o.default;v.default=p},{"../core/constants":269,"../core/friendly_errors/fes_core":271,"../core/friendly_errors/file_errors":272,"../core/friendly_errors/validate_params":275,"../core/main":280,"./p5.Color":267,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.map":167,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.to-string":187,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}],267:[function(h,x,v){function s(b){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(j){return typeof j}:function(j){return j&&typeof Symbol=="function"&&j.constructor===Symbol&&j!==Symbol.prototype?"symbol":typeof j})(b)}function c(b){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(j){return s(j)}:function(j){return j&&typeof Symbol=="function"&&j.constructor===Symbol&&j!==Symbol.prototype?"symbol":s(j)})(b)}h("core-js/modules/es.symbol"),h("core-js/modules/es.symbol.description"),h("core-js/modules/es.symbol.iterator"),h("core-js/modules/es.array.includes"),h("core-js/modules/es.array.iterator"),h("core-js/modules/es.array.join"),h("core-js/modules/es.array.map"),h("core-js/modules/es.array.slice"),h("core-js/modules/es.object.get-own-property-descriptor"),h("core-js/modules/es.object.to-string"),h("core-js/modules/es.regexp.constructor"),h("core-js/modules/es.regexp.exec"),h("core-js/modules/es.regexp.to-string"),h("core-js/modules/es.string.includes"),h("core-js/modules/es.string.iterator"),h("core-js/modules/es.string.trim"),h("core-js/modules/es.weak-map"),h("core-js/modules/web.dom-collections.iterator"),h("core-js/modules/es.array.includes"),h("core-js/modules/es.array.join"),h("core-js/modules/es.array.map"),h("core-js/modules/es.array.slice"),h("core-js/modules/es.object.to-string"),h("core-js/modules/es.regexp.constructor"),h("core-js/modules/es.regexp.exec"),h("core-js/modules/es.regexp.to-string"),h("core-js/modules/es.string.includes"),h("core-js/modules/es.string.trim"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=n(h("../core/main")),u=function(b){if(b&&b.__esModule)return b;if(b===null||c(b)!=="object"&&typeof b!="function")return{default:b};var j=p();if(j&&j.has(b))return j.get(b);var k,E={},M=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(k in b){var P;Object.prototype.hasOwnProperty.call(b,k)&&((P=M?Object.getOwnPropertyDescriptor(b,k):null)&&(P.get||P.set)?Object.defineProperty(E,k,P):E[k]=b[k])}return E.default=b,j&&j.set(b,E),E}(h("../core/constants")),g=n(h("./color_conversion"));function p(){var b;return typeof WeakMap!="function"?null:(b=new WeakMap,p=function(){return b},b)}function n(b){return b&&b.__esModule?b:{default:b}}function i(b,j){for(var k=0;k{},Jr=Array.isArray,zf=/#/g,Uv=/&/g,Bv=/\//g,Gv=/=/g,Vv=/\?/g,Wf=/\+/g,Hv=/%5B/g,zv=/%5D/g,qf=/%5E/g,Wv=/%60/g,Xf=/%7B/g,qv=/%7C/g,Yf=/%7D/g,Xv=/%20/g;function ml(r){return encodeURI(""+r).replace(qv,"|").replace(Hv,"[").replace(zv,"]")}function Yv(r){return ml(r).replace(Xf,"{").replace(Yf,"}").replace(qf,"^")}function Ra(r){return ml(r).replace(Wf,"%2B").replace(Xv,"+").replace(zf,"%23").replace(Uv,"%26").replace(Wv,"`").replace(Xf,"{").replace(Yf,"}").replace(qf,"^")}function $v(r){return Ra(r).replace(Gv,"%3D")}function Kv(r){return ml(r).replace(zf,"%23").replace(Vv,"%3F")}function Zv(r){return r==null?"":Kv(r).replace(Bv,"%2F")}function ns(r){try{return decodeURIComponent(""+r)}catch{}return""+r}const Qv=/\/$/,Jv=r=>r.replace(Qv,"");function Yi(r,d,w="/"){let t,x={},v="",s="";const c=d.indexOf("#");let o=d.indexOf("?");return c=0&&(o=-1),o>-1&&(t=d.slice(0,o),v=d.slice(o+1,c>-1?c:d.length),x=r(v)),c>-1&&(t=t||d.slice(0,c),s=d.slice(c,d.length)),t=n0(t??d,w),{fullPath:t+(v&&"?")+v+s,path:t,query:x,hash:ns(s)}}function e0(r,d){const w=d.query?r(d.query):"";return d.path+(w&&"?")+w+(d.hash||"")}function hc(r,d){return!d||!r.toLowerCase().startsWith(d.toLowerCase())?r:r.slice(d.length)||"/"}function t0(r,d,w){const t=d.matched.length-1,x=w.matched.length-1;return t>-1&&t===x&&wo(d.matched[t],w.matched[x])&&$f(d.params,w.params)&&r(d.query)===r(w.query)&&d.hash===w.hash}function wo(r,d){return(r.aliasOf||r)===(d.aliasOf||d)}function $f(r,d){if(Object.keys(r).length!==Object.keys(d).length)return!1;for(const w in r)if(!r0(r[w],d[w]))return!1;return!0}function r0(r,d){return Jr(r)?pc(r,d):Jr(d)?pc(d,r):r===d}function pc(r,d){return Jr(d)?r.length===d.length&&r.every((w,t)=>w===d[t]):r.length===1&&r[0]===d}function n0(r,d){if(r.startsWith("/"))return r;if(!r)return d;const w=d.split("/"),t=r.split("/"),x=t[t.length-1];(x===".."||x===".")&&t.push("");let v=w.length-1,s,c;for(s=0;s1&&v--;else break;return w.slice(0,v).join("/")+"/"+t.slice(s).join("/")}const Kr={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};var os;(function(r){r.pop="pop",r.push="push"})(os||(os={}));var Xo;(function(r){r.back="back",r.forward="forward",r.unknown=""})(Xo||(Xo={}));function o0(r){if(!r)if(io){const d=document.querySelector("base");r=d&&d.getAttribute("href")||"/",r=r.replace(/^\w+:\/\/[^\/]+/,"")}else r="/";return r[0]!=="/"&&r[0]!=="#"&&(r="/"+r),Jv(r)}const s0=/^[^#]+#/;function i0(r,d){return r.replace(s0,"#")+d}function a0(r,d){const w=document.documentElement.getBoundingClientRect(),t=r.getBoundingClientRect();return{behavior:d.behavior,left:t.left-w.left-(d.left||0),top:t.top-w.top-(d.top||0)}}const bi=()=>({left:window.scrollX,top:window.scrollY});function l0(r){let d;if("el"in r){const w=r.el,t=typeof w=="string"&&w.startsWith("#"),x=typeof w=="string"?t?document.getElementById(w.slice(1)):document.querySelector(w):w;if(!x)return;d=a0(x,r)}else d=r;"scrollBehavior"in document.documentElement.style?window.scrollTo(d):window.scrollTo(d.left!=null?d.left:window.scrollX,d.top!=null?d.top:window.scrollY)}function mc(r,d){return(history.state?history.state.position-d:-1)+r}const La=new Map;function u0(r,d){La.set(r,d)}function c0(r){const d=La.get(r);return La.delete(r),d}let d0=()=>location.protocol+"//"+location.host;function Kf(r,d){const{pathname:w,search:t,hash:x}=d,v=r.indexOf("#");if(v>-1){let c=x.includes(r.slice(v))?r.slice(v).length:1,o=x.slice(c);return o[0]!=="/"&&(o="/"+o),hc(o,"")}return hc(w,r)+t+x}function f0(r,d,w,t){let x=[],v=[],s=null;const c=({state:n})=>{const i=Kf(r,location),a=w.value,h=d.value;let y=0;if(n){if(w.value=i,d.value=n,s&&s===a){s=null;return}y=h?n.position-h.position:0}else t(i);x.forEach(l=>{l(w.value,a,{delta:y,type:os.pop,direction:y?y>0?Xo.forward:Xo.back:Xo.unknown})})};function o(){s=w.value}function u(n){x.push(n);const i=()=>{const a=x.indexOf(n);a>-1&&x.splice(a,1)};return v.push(i),i}function g(){const{history:n}=window;n.state&&n.replaceState(xt({},n.state,{scroll:bi()}),"")}function p(){for(const n of v)n();v=[],window.removeEventListener("popstate",c),window.removeEventListener("beforeunload",g)}return window.addEventListener("popstate",c),window.addEventListener("beforeunload",g,{passive:!0}),{pauseListeners:o,listen:u,destroy:p}}function yc(r,d,w,t=!1,x=!1){return{back:r,current:d,forward:w,replaced:t,position:window.history.length,scroll:x?bi():null}}function h0(r){const{history:d,location:w}=window,t={value:Kf(r,w)},x={value:d.state};x.value||v(t.value,{back:null,current:t.value,forward:null,position:d.length-1,replaced:!0,scroll:null},!0);function v(o,u,g){const p=r.indexOf("#"),n=p>-1?(w.host&&document.querySelector("base")?r:r.slice(p))+o:d0()+r+o;try{d[g?"replaceState":"pushState"](u,"",n),x.value=u}catch(i){console.error(i),w[g?"replace":"assign"](n)}}function s(o,u){const g=xt({},d.state,yc(x.value.back,o,x.value.forward,!0),u,{position:x.value.position});v(o,g,!0),t.value=o}function c(o,u){const g=xt({},x.value,d.state,{forward:o,scroll:bi()});v(g.current,g,!0);const p=xt({},yc(t.value,o,null),{position:g.position+1},u);v(o,p,!1),t.value=o}return{location:t,state:x,push:c,replace:s}}function Zf(r){r=o0(r);const d=h0(r),w=f0(r,d.state,d.location,d.replace);function t(v,s=!0){s||w.pauseListeners(),history.go(v)}const x=xt({location:"",base:r,go:t,createHref:i0.bind(null,r)},d,w);return Object.defineProperty(x,"location",{enumerable:!0,get:()=>d.location.value}),Object.defineProperty(x,"state",{enumerable:!0,get:()=>d.state.value}),x}function p0(r){return r=location.host?r||location.pathname+location.search:"",r.includes("#")||(r+="#"),Zf(r)}function m0(r){return typeof r=="string"||r&&typeof r=="object"}function Qf(r){return typeof r=="string"||typeof r=="symbol"}const Jf=Symbol("");var gc;(function(r){r[r.aborted=4]="aborted",r[r.cancelled=8]="cancelled",r[r.duplicated=16]="duplicated"})(gc||(gc={}));function xo(r,d){return xt(new Error,{type:r,[Jf]:!0},d)}function fn(r,d){return r instanceof Error&&Jf in r&&(d==null||!!(r.type&d))}const vc="[^/]+?",y0={sensitive:!1,strict:!1,start:!0,end:!0},g0=/[.+*?^${}()[\]/\\]/g;function v0(r,d){const w=xt({},y0,d),t=[];let x=w.start?"^":"";const v=[];for(const u of r){const g=u.length?[]:[90];w.strict&&!u.length&&(x+="/");for(let p=0;pd.length?d.length===1&&d[0]===80?1:-1:0}function eh(r,d){let w=0;const t=r.score,x=d.score;for(;w0&&d[d.length-1]<0}const _0={type:0,value:""},w0=/[a-zA-Z0-9_]/;function x0(r){if(!r)return[[]];if(r==="/")return[[_0]];if(!r.startsWith("/"))throw new Error(`Invalid path "${r}"`);function d(i){throw new Error(`ERR (${w})/"${u}": ${i}`)}let w=0,t=w;const x=[];let v;function s(){v&&x.push(v),v=[]}let c=0,o,u="",g="";function p(){u&&(w===0?v.push({type:0,value:u}):w===1||w===2||w===3?(v.length>1&&(o==="*"||o==="+")&&d(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),v.push({type:1,value:u,regexp:g,repeatable:o==="*"||o==="+",optional:o==="*"||o==="?"})):d("Invalid state to consume buffer"),u="")}function n(){u+=o}for(;c{s(m)}:qo}function s(p){if(Qf(p)){const n=t.get(p);n&&(t.delete(p),w.splice(w.indexOf(n),1),n.children.forEach(s),n.alias.forEach(s))}else{const n=w.indexOf(p);n>-1&&(w.splice(n,1),p.record.name&&t.delete(p.record.name),p.children.forEach(s),p.alias.forEach(s))}}function c(){return w}function o(p){const n=M0(p,w);w.splice(n,0,p),p.record.name&&!wc(p)&&t.set(p.record.name,p)}function u(p,n){let i,a={},h,y;if("name"in p&&p.name){if(i=t.get(p.name),!i)throw xo(1,{location:p});y=i.record.name,a=xt(_c(n.params,i.keys.filter(m=>!m.optional).concat(i.parent?i.parent.keys.filter(m=>m.optional):[]).map(m=>m.name)),p.params&&_c(p.params,i.keys.map(m=>m.name))),h=i.stringify(a)}else if(p.path!=null)h=p.path,i=w.find(m=>m.re.test(h)),i&&(a=i.parse(h),y=i.record.name);else{if(i=n.name?t.get(n.name):w.find(m=>m.re.test(n.path)),!i)throw xo(1,{location:p,currentLocation:n});y=i.record.name,a=xt({},n.params,p.params),h=i.stringify(a)}const l=[];let f=i;for(;f;)l.unshift(f.record),f=f.parent;return{name:y,path:h,params:a,matched:l,meta:k0(l)}}r.forEach(p=>v(p));function g(){w.length=0,t.clear()}return{addRoute:v,resolve:u,removeRoute:s,clearRoutes:g,getRoutes:c,getRecordMatcher:x}}function _c(r,d){const w={};for(const t of d)t in r&&(w[t]=r[t]);return w}function E0(r){return{path:r.path,redirect:r.redirect,name:r.name,meta:r.meta||{},aliasOf:void 0,beforeEnter:r.beforeEnter,props:T0(r),children:r.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in r?r.components||null:r.component&&{default:r.component}}}function T0(r){const d={},w=r.props||!1;if("component"in r)d.default=w;else for(const t in r.components)d[t]=typeof w=="object"?w[t]:w;return d}function wc(r){for(;r;){if(r.record.aliasOf)return!0;r=r.parent}return!1}function k0(r){return r.reduce((d,w)=>xt(d,w.meta),{})}function xc(r,d){const w={};for(const t in r)w[t]=t in d?d[t]:r[t];return w}function M0(r,d){let w=0,t=d.length;for(;w!==t;){const v=w+t>>1;eh(r,d[v])<0?t=v:w=v+1}const x=C0(r);return x&&(t=d.lastIndexOf(x,t-1)),t}function C0(r){let d=r;for(;d=d.parent;)if(th(d)&&eh(r,d)===0)return d}function th({record:r}){return!!(r.name||r.components&&Object.keys(r.components).length||r.redirect)}function O0(r){const d={};if(r===""||r==="?")return d;const t=(r[0]==="?"?r.slice(1):r).split("&");for(let x=0;xv&&Ra(v)):[t&&Ra(t)]).forEach(v=>{v!==void 0&&(d+=(d.length?"&":"")+w,v!=null&&(d+="="+v))})}return d}function P0(r){const d={};for(const w in r){const t=r[w];t!==void 0&&(d[w]=Jr(t)?t.map(x=>x==null?null:""+x):t==null?t:""+t)}return d}const A0=Symbol(""),Sc=Symbol(""),yl=Symbol(""),gl=Symbol(""),Ia=Symbol("");function Fo(){let r=[];function d(t){return r.push(t),()=>{const x=r.indexOf(t);x>-1&&r.splice(x,1)}}function w(){r=[]}return{add:d,list:()=>r.slice(),reset:w}}function Cn(r,d,w,t,x,v=s=>s()){const s=t&&(t.enterCallbacks[x]=t.enterCallbacks[x]||[]);return()=>new Promise((c,o)=>{const u=n=>{n===!1?o(xo(4,{from:w,to:d})):n instanceof Error?o(n):m0(n)?o(xo(2,{from:d,to:n})):(s&&t.enterCallbacks[x]===s&&typeof n=="function"&&s.push(n),c())},g=v(()=>r.call(t&&t.instances[x],d,w,u));let p=Promise.resolve(g);r.length<3&&(p=p.then(u)),p.catch(n=>o(n))})}function $i(r,d,w,t,x=v=>v()){const v=[];for(const s of r)for(const c in s.components){let o=s.components[c];if(!(d!=="beforeRouteEnter"&&!s.instances[c]))if(R0(o)){const g=(o.__vccOpts||o)[d];g&&v.push(Cn(g,w,t,s,c,x))}else{let u=o();v.push(()=>u.then(g=>{if(!g)return Promise.reject(new Error(`Couldn't resolve component "${c}" at "${s.path}"`));const p=Nv(g)?g.default:g;s.components[c]=p;const i=(p.__vccOpts||p)[d];return i&&Cn(i,w,t,s,c,x)()}))}}return v}function R0(r){return typeof r=="object"||"displayName"in r||"props"in r||"__vccOpts"in r}function Ec(r){const d=Ht(yl),w=Ht(gl),t=jt(()=>{const o=Bt(r.to);return d.resolve(o)}),x=jt(()=>{const{matched:o}=t.value,{length:u}=o,g=o[u-1],p=w.matched;if(!g||!p.length)return-1;const n=p.findIndex(wo.bind(null,g));if(n>-1)return n;const i=Tc(o[u-2]);return u>1&&Tc(g)===i&&p[p.length-1].path!==i?p.findIndex(wo.bind(null,o[u-2])):n}),v=jt(()=>x.value>-1&&F0(w.params,t.value.params)),s=jt(()=>x.value>-1&&x.value===w.matched.length-1&&$f(w.params,t.value.params));function c(o={}){return D0(o)?d[Bt(r.replace)?"replace":"push"](Bt(r.to)).catch(qo):Promise.resolve()}return{route:t,href:jt(()=>t.value.href),isActive:v,isExactActive:s,navigate:c}}const L0=pr({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Ec,setup(r,{slots:d}){const w=Bn(Ec(r)),{options:t}=Ht(yl),x=jt(()=>({[kc(r.activeClass,t.linkActiveClass,"router-link-active")]:w.isActive,[kc(r.exactActiveClass,t.linkExactActiveClass,"router-link-exact-active")]:w.isExactActive}));return()=>{const v=d.default&&d.default(w);return r.custom?v:rr("a",{"aria-current":w.isExactActive?r.ariaCurrentValue:null,href:w.href,onClick:w.navigate,class:x.value},v)}}}),I0=L0;function D0(r){if(!(r.metaKey||r.altKey||r.ctrlKey||r.shiftKey)&&!r.defaultPrevented&&!(r.button!==void 0&&r.button!==0)){if(r.currentTarget&&r.currentTarget.getAttribute){const d=r.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(d))return}return r.preventDefault&&r.preventDefault(),!0}}function F0(r,d){for(const w in d){const t=d[w],x=r[w];if(typeof t=="string"){if(t!==x)return!1}else if(!Jr(x)||x.length!==t.length||t.some((v,s)=>v!==x[s]))return!1}return!0}function Tc(r){return r?r.aliasOf?r.aliasOf.path:r.path:""}const kc=(r,d,w)=>r??d??w,N0=pr({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(r,{attrs:d,slots:w}){const t=Ht(Ia),x=jt(()=>r.route||t.value),v=Ht(Sc,0),s=jt(()=>{let u=Bt(v);const{matched:g}=x.value;let p;for(;(p=g[u])&&!p.components;)u++;return u}),c=jt(()=>x.value.matched[s.value]);Wr(Sc,jt(()=>s.value+1)),Wr(A0,c),Wr(Ia,x);const o=mt();return In(()=>[o.value,c.value,r.name],([u,g,p],[n,i,a])=>{g&&(g.instances[p]=u,i&&i!==g&&u&&u===n&&(g.leaveGuards.size||(g.leaveGuards=i.leaveGuards),g.updateGuards.size||(g.updateGuards=i.updateGuards))),u&&g&&(!i||!wo(g,i)||!n)&&(g.enterCallbacks[p]||[]).forEach(h=>h(u))},{flush:"post"}),()=>{const u=x.value,g=r.name,p=c.value,n=p&&p.components[g];if(!n)return Mc(w.default,{Component:n,route:u});const i=p.props[g],a=i?i===!0?u.params:typeof i=="function"?i(u):i:null,y=rr(n,xt({},a,d,{onVnodeUnmounted:l=>{l.component.isUnmounted&&(p.instances[g]=null)},ref:o}));return Mc(w.default,{Component:y,route:u})||y}}});function Mc(r,d){if(!r)return null;const w=r(d);return w.length===1?w[0]:w}const rh=N0;function U0(r){const d=S0(r.routes,r),w=r.parseQuery||O0,t=r.stringifyQuery||jc,x=r.history,v=Fo(),s=Fo(),c=Fo(),o=Ko(Kr);let u=Kr;io&&r.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const g=Xi.bind(null,$=>""+$),p=Xi.bind(null,Zv),n=Xi.bind(null,ns);function i($,J){let ne,ce;return Qf($)?(ne=d.getRecordMatcher($),ce=J):ce=$,d.addRoute(ce,ne)}function a($){const J=d.getRecordMatcher($);J&&d.removeRoute(J)}function h(){return d.getRoutes().map($=>$.record)}function y($){return!!d.getRecordMatcher($)}function l($,J){if(J=xt({},J||o.value),typeof $=="string"){const z=Yi(w,$,J.path),te=d.resolve({path:z.path},J),le=x.createHref(z.fullPath);return xt(z,te,{params:n(te.params),hash:ns(z.hash),redirectedFrom:void 0,href:le})}let ne;if($.path!=null)ne=xt({},$,{path:Yi(w,$.path,J.path).path});else{const z=xt({},$.params);for(const te in z)z[te]==null&&delete z[te];ne=xt({},$,{params:p(z)}),J.params=p(J.params)}const ce=d.resolve(ne,J),ie=$.hash||"";ce.params=g(n(ce.params));const pe=e0(t,xt({},$,{hash:Yv(ie),path:ce.path})),K=x.createHref(pe);return xt({fullPath:pe,hash:ie,query:t===jc?P0($.query):$.query||{}},ce,{redirectedFrom:void 0,href:K})}function f($){return typeof $=="string"?Yi(w,$,o.value.path):xt({},$)}function m($,J){if(u!==$)return xo(8,{from:J,to:$})}function b($){return E($)}function j($){return b(xt(f($),{replace:!0}))}function k($){const J=$.matched[$.matched.length-1];if(J&&J.redirect){const{redirect:ne}=J;let ce=typeof ne=="function"?ne($):ne;return typeof ce=="string"&&(ce=ce.includes("?")||ce.includes("#")?ce=f(ce):{path:ce},ce.params={}),xt({query:$.query,hash:$.hash,params:ce.path!=null?{}:$.params},ce)}}function E($,J){const ne=u=l($),ce=o.value,ie=$.state,pe=$.force,K=$.replace===!0,z=k(ne);if(z)return E(xt(f(z),{state:typeof z=="object"?xt({},ie,z.state):ie,force:pe,replace:K}),J||ne);const te=ne;te.redirectedFrom=J;let le;return!pe&&t0(t,ce,ne)&&(le=xo(16,{to:te,from:ce}),ee(ce,ce,!0,!1)),(le?Promise.resolve(le):L(te,ce)).catch(me=>fn(me)?fn(me,2)?me:Z(me):V(me,te,ce)).then(me=>{if(me){if(fn(me,2))return E(xt({replace:K},f(me.to),{state:typeof me.to=="object"?xt({},ie,me.to.state):ie,force:pe}),J||te)}else me=I(te,ce,!0,K,ie);return C(te,ce,me),me})}function M($,J){const ne=m($,J);return ne?Promise.reject(ne):Promise.resolve()}function P($){const J=D.values().next().value;return J&&typeof J.runWithContext=="function"?J.runWithContext($):$()}function L($,J){let ne;const[ce,ie,pe]=B0($,J);ne=$i(ce.reverse(),"beforeRouteLeave",$,J);for(const z of ce)z.leaveGuards.forEach(te=>{ne.push(Cn(te,$,J))});const K=M.bind(null,$,J);return ne.push(K),W(ne).then(()=>{ne=[];for(const z of v.list())ne.push(Cn(z,$,J));return ne.push(K),W(ne)}).then(()=>{ne=$i(ie,"beforeRouteUpdate",$,J);for(const z of ie)z.updateGuards.forEach(te=>{ne.push(Cn(te,$,J))});return ne.push(K),W(ne)}).then(()=>{ne=[];for(const z of pe)if(z.beforeEnter)if(Jr(z.beforeEnter))for(const te of z.beforeEnter)ne.push(Cn(te,$,J));else ne.push(Cn(z.beforeEnter,$,J));return ne.push(K),W(ne)}).then(()=>($.matched.forEach(z=>z.enterCallbacks={}),ne=$i(pe,"beforeRouteEnter",$,J,P),ne.push(K),W(ne))).then(()=>{ne=[];for(const z of s.list())ne.push(Cn(z,$,J));return ne.push(K),W(ne)}).catch(z=>fn(z,8)?z:Promise.reject(z))}function C($,J,ne){c.list().forEach(ce=>P(()=>ce($,J,ne)))}function I($,J,ne,ce,ie){const pe=m($,J);if(pe)return pe;const K=J===Kr,z=io?history.state:{};ne&&(ce||K?x.replace($.fullPath,xt({scroll:K&&z&&z.scroll},ie)):x.push($.fullPath,ie)),o.value=$,ee($,J,ne,K),Z()}let A;function N(){A||(A=x.listen(($,J,ne)=>{if(!G.listening)return;const ce=l($),ie=k(ce);if(ie){E(xt(ie,{replace:!0}),ce).catch(qo);return}u=ce;const pe=o.value;io&&u0(mc(pe.fullPath,ne.delta),bi()),L(ce,pe).catch(K=>fn(K,12)?K:fn(K,2)?(E(K.to,ce).then(z=>{fn(z,20)&&!ne.delta&&ne.type===os.pop&&x.go(-1,!1)}).catch(qo),Promise.reject()):(ne.delta&&x.go(-ne.delta,!1),V(K,ce,pe))).then(K=>{K=K||I(ce,pe,!1),K&&(ne.delta&&!fn(K,8)?x.go(-ne.delta,!1):ne.type===os.pop&&fn(K,20)&&x.go(-1,!1)),C(ce,pe,K)}).catch(qo)}))}let F=Fo(),B=Fo(),q;function V($,J,ne){Z($);const ce=B.list();return ce.length?ce.forEach(ie=>ie($,J,ne)):console.error($),Promise.reject($)}function H(){return q&&o.value!==Kr?Promise.resolve():new Promise(($,J)=>{F.add([$,J])})}function Z($){return q||(q=!$,N(),F.list().forEach(([J,ne])=>$?ne($):J()),F.reset()),$}function ee($,J,ne,ce){const{scrollBehavior:ie}=r;if(!io||!ie)return Promise.resolve();const pe=!ne&&c0(mc($.fullPath,0))||(ce||!ne)&&history.state&&history.state.scroll||null;return Fr().then(()=>ie($,J,pe)).then(K=>K&&l0(K)).catch(K=>V(K,$,J))}const ue=$=>x.go($);let T;const D=new Set,G={currentRoute:o,listening:!0,addRoute:i,removeRoute:a,clearRoutes:d.clearRoutes,hasRoute:y,getRoutes:h,resolve:l,options:r,push:b,replace:j,go:ue,back:()=>ue(-1),forward:()=>ue(1),beforeEach:v.add,beforeResolve:s.add,afterEach:c.add,onError:B.add,isReady:H,install($){const J=this;$.component("RouterLink",I0),$.component("RouterView",rh),$.config.globalProperties.$router=J,Object.defineProperty($.config.globalProperties,"$route",{enumerable:!0,get:()=>Bt(o)}),io&&!T&&o.value===Kr&&(T=!0,b(x.location).catch(ie=>{}));const ne={};for(const ie in Kr)Object.defineProperty(ne,ie,{get:()=>o.value[ie],enumerable:!0});$.provide(yl,J),$.provide(gl,as(ne)),$.provide(Ia,o);const ce=$.unmount;D.add($),$.unmount=function(){D.delete($),D.size<1&&(u=Kr,A&&A(),A=null,o.value=Kr,T=!1,q=!1),ce()}}};function W($){return $.reduce((J,ne)=>J.then(()=>P(ne)),Promise.resolve())}return G}function B0(r,d){const w=[],t=[],x=[],v=Math.max(d.matched.length,r.matched.length);for(let s=0;swo(u,c))?t.push(c):w.push(c));const o=r.matched[s];o&&(d.matched.find(u=>wo(u,o))||x.push(o))}return[w,t,x]}function G0(r){return Ht(gl)}const V0=(r,d)=>d.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,w=>{var t;return((t=r.params[w.slice(1)])==null?void 0:t.toString())||""}),Da=(r,d)=>{const w=r.route.matched.find(x=>{var v;return((v=x.components)==null?void 0:v.default)===r.Component.type}),t=d??(w==null?void 0:w.meta.key)??(w&&V0(r.route,w));return typeof t=="function"?t(r.route):t},H0=(r,d)=>({default:()=>r?rr(bm,r===!0?{}:r,d):d});function vl(r){return Array.isArray(r)?r:[r]}const z0="modulepreload",W0=function(r,d){return r[0]==="."?new URL(r,d).href:r},Cc={},q0=function(d,w,t){let x=Promise.resolve();if(w&&w.length>0){const v=document.getElementsByTagName("link"),s=document.querySelector("meta[property=csp-nonce]"),c=(s==null?void 0:s.nonce)||(s==null?void 0:s.getAttribute("nonce"));x=Promise.all(w.map(o=>{if(o=W0(o,t),o in Cc)return;Cc[o]=!0;const u=o.endsWith(".css"),g=u?'[rel="stylesheet"]':"";if(!!t)for(let i=v.length-1;i>=0;i--){const a=v[i];if(a.href===o&&(!u||a.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${o}"]${g}`))return;const n=document.createElement("link");if(n.rel=u?"stylesheet":z0,u||(n.as="script",n.crossOrigin=""),n.href=o,c&&n.setAttribute("nonce",c),document.head.appendChild(n),u)return new Promise((i,a)=>{n.addEventListener("load",i),n.addEventListener("error",()=>a(new Error(`Unable to preload CSS for ${o}`)))})}))}return x.then(()=>d()).catch(v=>{const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=v,window.dispatchEvent(s),!s.defaultPrevented)throw v})},rt=(...r)=>q0(...r).catch(d=>{const w=new Event("nuxt.preloadError");throw w.payload=d,window.dispatchEvent(w),d}),Ki=null,Zi=null,wr={layout:"empty"},Qi=null,Ji=null,ea=null,xr={layout:"light"},jr={layout:"light"},Sr={layout:"light"},ta=null,Er={layout:"light"},Tr={layout:"light"},kr={layout:"light"},Mr={layout:"light"},Cr={layout:"light"},Or={layout:"light"},Pr={layout:"light"},Ar={layout:"light"},Oc=[{name:"articles-slug",path:"/articles/:slug(.*)*",meta:{},alias:[],redirect:Ki==null?void 0:Ki.redirect,component:()=>rt(()=>import("./Gb-Mbhdk.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9]),import.meta.url).then(r=>r.default||r)},{name:"articles",path:"/articles",meta:{},alias:[],redirect:Zi==null?void 0:Zi.redirect,component:()=>rt(()=>import("./CRLNagtS.js"),__vite__mapDeps([10,1,2,3,4,5,6,7,8]),import.meta.url).then(r=>r.default||r)},{name:(wr==null?void 0:wr.name)??"card",path:(wr==null?void 0:wr.path)??"/card",meta:wr||{},alias:(wr==null?void 0:wr.alias)||[],redirect:wr==null?void 0:wr.redirect,component:()=>rt(()=>import("./Dzt8DsnY.js"),[],import.meta.url).then(r=>r.default||r)},{name:"examples-nested_transitions",path:"/examples/nested_transitions",meta:{},alias:[],redirect:Qi==null?void 0:Qi.redirect,component:()=>rt(()=>import("./CGx64xBQ.js"),[],import.meta.url).then(r=>r.default||r)},{name:"index",path:"/",meta:{},alias:[],redirect:Ji==null?void 0:Ji.redirect,component:()=>rt(()=>import("./Ci9WvbVQ.js"),__vite__mapDeps([11,12,8,5,4]),import.meta.url).then(r=>r.default||r)},{name:"playground-audio",path:"/playground/audio",meta:{},alias:[],redirect:ea==null?void 0:ea.redirect,component:()=>rt(()=>import("./CfIOX_tU.js"),[],import.meta.url).then(r=>r.default||r)},{name:(xr==null?void 0:xr.name)??"playground-chords",path:(xr==null?void 0:xr.path)??"/playground/chords",meta:xr||{},alias:(xr==null?void 0:xr.alias)||[],redirect:xr==null?void 0:xr.redirect,component:()=>rt(()=>import("./8m7fprhq.js"),[],import.meta.url).then(r=>r.default||r)},{name:(jr==null?void 0:jr.name)??"playground-conway",path:(jr==null?void 0:jr.path)??"/playground/conway",meta:jr||{},alias:(jr==null?void 0:jr.alias)||[],redirect:jr==null?void 0:jr.redirect,component:()=>rt(()=>import("./V4NJ029S.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Sr==null?void 0:Sr.name)??"playground-french",path:(Sr==null?void 0:Sr.path)??"/playground/french",meta:Sr||{},alias:(Sr==null?void 0:Sr.alias)||[],redirect:Sr==null?void 0:Sr.redirect,component:()=>rt(()=>import("./KYfJ1yMs.js"),__vite__mapDeps([13,5,7]),import.meta.url).then(r=>r.default||r)},{name:"playground",path:"/playground",meta:{},alias:[],redirect:ta==null?void 0:ta.redirect,component:()=>rt(()=>import("./CmyKjUr8.js"),__vite__mapDeps([14,12]),import.meta.url).then(r=>r.default||r)},{name:(Er==null?void 0:Er.name)??"playground-matrix",path:(Er==null?void 0:Er.path)??"/playground/matrix",meta:Er||{},alias:(Er==null?void 0:Er.alias)||[],redirect:Er==null?void 0:Er.redirect,component:()=>rt(()=>import("./Bv5xXi_H.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Tr==null?void 0:Tr.name)??"playground-metronome",path:(Tr==null?void 0:Tr.path)??"/playground/metronome",meta:Tr||{},alias:(Tr==null?void 0:Tr.alias)||[],redirect:Tr==null?void 0:Tr.redirect,component:()=>rt(()=>import("./DNWUxvYV.js"),[],import.meta.url).then(r=>r.default||r)},{name:(kr==null?void 0:kr.name)??"playground-midi",path:(kr==null?void 0:kr.path)??"/playground/midi",meta:kr||{},alias:(kr==null?void 0:kr.alias)||[],redirect:kr==null?void 0:kr.redirect,component:()=>rt(()=>import("./CX8WYcQA.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Mr==null?void 0:Mr.name)??"playground-palettes-mountains",path:(Mr==null?void 0:Mr.path)??"/playground/palettes/mountains",meta:Mr||{},alias:(Mr==null?void 0:Mr.alias)||[],redirect:Mr==null?void 0:Mr.redirect,component:()=>rt(()=>import("./BDj4EL7w.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Cr==null?void 0:Cr.name)??"playground-palettes-variance",path:(Cr==null?void 0:Cr.path)??"/playground/palettes/variance",meta:Cr||{},alias:(Cr==null?void 0:Cr.alias)||[],redirect:Cr==null?void 0:Cr.redirect,component:()=>rt(()=>import("./B3uj60Hf.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Or==null?void 0:Or.name)??"playground-plotter",path:(Or==null?void 0:Or.path)??"/playground/plotter",meta:Or||{},alias:(Or==null?void 0:Or.alias)||[],redirect:Or==null?void 0:Or.redirect,component:()=>rt(()=>import("./BJy0y-3L.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Pr==null?void 0:Pr.name)??"playground-tiling",path:(Pr==null?void 0:Pr.path)??"/playground/tiling",meta:Pr||{},alias:(Pr==null?void 0:Pr.alias)||[],redirect:Pr==null?void 0:Pr.redirect,component:()=>rt(()=>import("./BknKiCrO.js"),[],import.meta.url).then(r=>r.default||r)},{name:(Ar==null?void 0:Ar.name)??"playground-waves",path:(Ar==null?void 0:Ar.path)??"/playground/waves",meta:Ar||{},alias:(Ar==null?void 0:Ar.alias)||[],redirect:Ar==null?void 0:Ar.redirect,component:()=>rt(()=>import("./CZ4lq9R5.js"),[],import.meta.url).then(r=>r.default||r)}],nh=(r,d,w)=>(d=d===!0?{}:d,{default:()=>{var t;return d?rr(r,d,w):(t=w.default)==null?void 0:t.call(w)}});function Pc(r){const d=(r==null?void 0:r.meta.key)??r.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,w=>{var t;return((t=r.params[w.slice(1)])==null?void 0:t.toString())||""});return typeof d=="function"?d(r):d}function X0(r,d){return r===d||d===Kr?!1:Pc(r)!==Pc(d)?!0:!r.matched.every((t,x)=>{var v,s;return t.components&&t.components.default===((s=(v=d.matched[x])==null?void 0:v.components)==null?void 0:s.default)})}const Y0={scrollBehavior(r,d,w){var u;const t=It(),x=((u=qr().options)==null?void 0:u.scrollBehaviorType)??"auto";let v=w||void 0;const s=typeof r.meta.scrollToTop=="function"?r.meta.scrollToTop(r,d):r.meta.scrollToTop;if(!v&&d&&r&&s!==!1&&X0(r,d)&&(v={left:0,top:0}),r.path===d.path)return d.hash&&!r.hash?{left:0,top:0}:r.hash?{el:r.hash,top:Ac(r.hash),behavior:x}:!1;const c=g=>!!(g.meta.pageTransition??Aa),o=c(d)&&c(r)?"page:transition:finish":"page:finish";return new Promise(g=>{t.hooks.hookOnce(o,async()=>{await new Promise(p=>setTimeout(p,0)),r.hash&&(v={el:r.hash,top:Ac(r.hash),behavior:x}),g(v)})})}};function Ac(r){try{const d=document.querySelector(r);if(d)return parseFloat(getComputedStyle(d).scrollMarginTop)}catch{}return 0}const $0={hashMode:!1,scrollBehaviorType:"auto"},Rr={...$0,...Y0},K0=async r=>{var o;let d,w;if(!((o=r.meta)!=null&&o.validate))return;const t=It(),x=qr();if(([d,w]=rs(()=>Promise.resolve(r.meta.validate(r))),d=await d,w(),d)===!0)return;const s=gi({statusCode:404,statusMessage:`Page Not Found: ${r.fullPath}`,data:{path:r.fullPath}}),c=x.beforeResolve(u=>{if(c(),u===r){const g=x.afterEach(async()=>{g(),await t.runWithContext(()=>lo(s)),window.history.pushState({},"",r.fullPath)});return!1}})},Z0=async r=>{let d,w;const t=([d,w]=rs(()=>pl(r.path)),d=await d,w(),d);if(t.redirect)return gn(t.redirect,{acceptRelative:!0})?(window.location.href=t.redirect,!1):t.redirect},Q0=[K0,Z0],Yo={};function J0(r,d,w){const{pathname:t,search:x,hash:v}=d,s=r.indexOf("#");if(s>-1){const u=v.includes(r.slice(s))?r.slice(s).length:1;let g=v.slice(u);return g[0]!=="/"&&(g="/"+g),Qu(g,"")}const c=Qu(t,r),o=!w||Fy(c,w,{trailingSlash:!0})?c:w;return o+(o.includes("?")?"":x)+v}const eb=vn({name:"nuxt:router",enforce:"pre",async setup(r){var y,l;let d,w,t=pi().app.baseURL;Rr.hashMode&&!t.includes("#")&&(t+="#");const x=((y=Rr.history)==null?void 0:y.call(Rr,t))??(Rr.hashMode?p0(t):Zf(t)),v=((l=Rr.routes)==null?void 0:l.call(Rr,Oc))??Oc;let s;const c=U0({...Rr,scrollBehavior:(f,m,b)=>{if(m===Kr){s=b;return}if(Rr.scrollBehavior){if(c.options.scrollBehavior=Rr.scrollBehavior,"scrollRestoration"in window.history){const j=c.beforeEach(()=>{j(),window.history.scrollRestoration="manual"})}return Rr.scrollBehavior(f,Kr,s||b)}},history:x,routes:v});"scrollRestoration"in window.history&&(window.history.scrollRestoration="auto"),r.vueApp.use(c);const o=Ko(c.currentRoute.value);c.afterEach((f,m)=>{o.value=m}),Object.defineProperty(r.vueApp.config.globalProperties,"previousRoute",{get:()=>o.value});const u=J0(t,window.location,r.payload.path),g=Ko(c.currentRoute.value),p=()=>{g.value=c.currentRoute.value};r.hook("page:finish",p),c.afterEach((f,m)=>{var b,j,k,E;((j=(b=f.matched[0])==null?void 0:b.components)==null?void 0:j.default)===((E=(k=m.matched[0])==null?void 0:k.components)==null?void 0:E.default)&&p()});const n={};for(const f in g.value)Object.defineProperty(n,f,{get:()=>g.value[f]});r._route=as(n),r._middleware=r._middleware||{global:[],named:{}};try{[d,w]=rs(()=>c.isReady()),await d,w()}catch(f){[d,w]=rs(()=>r.runWithContext(()=>lo(f))),await d,w()}const i=u!==c.currentRoute.value.fullPath?c.resolve(u):c.currentRoute.value;p();const a=r.payload.state._layout;c.beforeEach(async(f,m)=>{var b;await r.callHook("page:loading:start"),f.meta=Bn(f.meta),r.isHydrating&&a&&!go(f.meta.layout)&&(f.meta.layout=a),r._processingMiddleware=!0;{const j=new Set([...Q0,...r._middleware.global]);for(const k of f.matched){const E=k.meta.middleware;if(E)for(const M of vl(E))j.add(M)}{const k=await r.runWithContext(()=>pl(f.path));if(k.appMiddleware)for(const E in k.appMiddleware)k.appMiddleware[E]?j.add(E):j.delete(E)}for(const k of j){const E=typeof k=="string"?r._middleware.named[k]||await((b=Yo[k])==null?void 0:b.call(Yo).then(P=>P.default||P)):k;if(!E)throw new Error(`Unknown route middleware: '${k}'.`);const M=await r.runWithContext(()=>E(f,m));if(!r.payload.serverRendered&&r.isHydrating&&(M===!1||M instanceof Error)){const P=M||ka({statusCode:404,statusMessage:`Page Not Found: ${u}`});return await r.runWithContext(()=>lo(P)),!1}if(M!==!0&&(M||M===!1))return M}}}),c.onError(async()=>{delete r._processingMiddleware,await r.callHook("page:loading:end")});const h=yi();return c.afterEach(async(f,m,b)=>{delete r._processingMiddleware,!r.isHydrating&&h.value&&await r.runWithContext(Mg),b&&await r.callHook("page:loading:end"),f.matched.length===0&&await r.runWithContext(()=>lo(ka({statusCode:404,fatal:!1,statusMessage:`Page not found: ${f.fullPath}`,data:{path:f.fullPath}})))}),r.hooks.hookOnce("app:created",async()=>{try{"name"in i&&(i.name=void 0),await c.replace({...i,force:!0}),c.options.scrollBehavior=Rr.scrollBehavior}catch(f){await r.runWithContext(()=>lo(f))}}),{provide:{router:c}}}}),Fa=globalThis.requestIdleCallback||(r=>{const d=Date.now(),w={didTimeout:!1,timeRemaining:()=>Math.max(0,50-(Date.now()-d))};return setTimeout(()=>{r(w)},1)}),tb=globalThis.cancelIdleCallback||(r=>{clearTimeout(r)}),bl=r=>{const d=It();d.isHydrating?d.hooks.hookOnce("app:suspense:resolve",()=>{Fa(r)}):Fa(r)},rb=vn({name:"nuxt:payload",setup(r){qr().beforeResolve(async(d,w)=>{if(d.path===w.path)return;const t=await dc(d.path);t&&Object.assign(r.static.data,t.data)}),bl(()=>{var d;r.hooks.hook("link:prefetch",async w=>{hs(w).protocol||await dc(w)}),((d=navigator.connection)==null?void 0:d.effectiveType)!=="slow-2g"&&setTimeout(vi,1e3)})}}),nb=vn(r=>{let d;async function w(){const t=await vi();d&&clearTimeout(d),d=setTimeout(w,1e3*60*60);try{const x=await $fetch(cl("builds/latest.json")+`?${Date.now()}`);x.id!==t.id&&r.hooks.callHook("app:manifest:update",x)}catch{}}bl(()=>{d=setTimeout(w,1e3*60*60)})}),ob=ft(()=>rt(()=>import("./mpBF_AdW.js"),__vite__mapDeps([15,6,1,2,3,4,5,16,7,8]),import.meta.url).then(r=>r.default||r.default||r)),sb=ft(()=>rt(()=>import("./c-8mvODc.js"),__vite__mapDeps([17,16,7,8,5,4]),import.meta.url).then(r=>r.default||r.default||r)),ib=ft(()=>rt(()=>import("./Beu9PnWL.js"),__vite__mapDeps([18,7,5,8,4]),import.meta.url).then(r=>r.default||r.default||r)),ab=ft(()=>rt(()=>import("./EFdih8x4.js"),__vite__mapDeps([16,7,8,5,4]),import.meta.url).then(r=>r.default||r.default||r)),lb=ft(()=>rt(()=>import("./Cj9zn9Hh.js"),__vite__mapDeps([6,1,2,3,4,5]),import.meta.url).then(r=>r.default||r.default||r)),ub=ft(()=>rt(()=>import("./CWeMlRBK.js"),__vite__mapDeps([19,1,2,3,4,5]),import.meta.url).then(r=>r.default||r.default||r)),cb=ft(()=>rt(()=>import("./CvqFk8MA.js"),__vite__mapDeps([20,3]),import.meta.url).then(r=>r.default||r.default||r)),db=ft(()=>rt(()=>import("./CSeyXkCN.js"),[],import.meta.url).then(r=>r.default||r.default||r)),fb=ft(()=>rt(()=>import("./8tpp9ZIr.js"),[],import.meta.url).then(r=>r.default||r.default||r)),hb=ft(()=>rt(()=>import("./BW3Uyh46.js"),__vite__mapDeps([21,20,3]),import.meta.url).then(r=>r.default||r.default||r)),pb=ft(()=>rt(()=>import("./C1gyBLca.js"),__vite__mapDeps([22,23,24]),import.meta.url).then(r=>r.default||r.default||r)),mb=ft(()=>rt(()=>import("./I56hc03J.js"),[],import.meta.url).then(r=>r.default||r.default||r)),yb=ft(()=>rt(()=>import("./eJFH2hOw.js"),__vite__mapDeps([25,23,24]),import.meta.url).then(r=>r.default||r.default||r)),gb=ft(()=>rt(()=>import("./CxFdcY6a.js"),[],import.meta.url).then(r=>r.default||r.default||r)),vb=ft(()=>rt(()=>import("./DO0L514y.js"),[],import.meta.url).then(r=>r.default||r.default||r)),bb=ft(()=>rt(()=>import("./Cuqb2hhI.js"),[],import.meta.url).then(r=>r.default||r.default||r)),_b=ft(()=>rt(()=>import("./D0cw7U9Q.js"),[],import.meta.url).then(r=>r.default||r.default||r)),wb=ft(()=>rt(()=>import("./vPzKiM2h.js"),[],import.meta.url).then(r=>r.default||r.default||r)),xb=ft(()=>rt(()=>import("./C18jNCO7.js"),[],import.meta.url).then(r=>r.default||r.default||r)),jb=ft(()=>rt(()=>import("./ClxUSaue.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Sb=ft(()=>rt(()=>import("./B9owgOfn.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Eb=ft(()=>rt(()=>import("./DkUCuJrl.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Tb=ft(()=>rt(()=>import("./_Au1_THb.js"),[],import.meta.url).then(r=>r.default||r.default||r)),kb=ft(()=>rt(()=>import("./KhVY6nTr.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Mb=ft(()=>rt(()=>import("./DYKfhnuI.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Cb=ft(()=>rt(()=>import("./MGGx6DJ7.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ob=ft(()=>rt(()=>import("./7n6Wnr7D.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Pb=ft(()=>rt(()=>import("./DRDFsaxg.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ab=ft(()=>rt(()=>import("./BKnB9ShE.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Rb=ft(()=>rt(()=>import("./Ce-DNi_D.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Lb=ft(()=>rt(()=>import("./BY1K6PIA.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ib=ft(()=>rt(()=>import("./DzpNuskE.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Db=ft(()=>rt(()=>import("./yMITBXRA.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Fb=ft(()=>rt(()=>import("./BmD66l6I.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Nb=ft(()=>rt(()=>import("./cjxB7njK.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Ub=ft(()=>rt(()=>import("./T-PpGVH_.js"),[],import.meta.url).then(r=>r.default||r.default||r)),Bb=[["ContentDoc",ob],["ContentList",sb],["ContentNavigation",ib],["ContentQuery",ab],["ContentRenderer",lb],["ContentRendererMarkdown",ub],["MDCSlot",cb],["DocumentDrivenEmpty",db],["DocumentDrivenNotFound",fb],["Markdown",hb],["ProseCode",pb],["ProseCodeInline",mb],["ProsePre",yb],["ProseA",gb],["ProseBlockquote",vb],["ProseEm",bb],["ProseH1",_b],["ProseH2",wb],["ProseH3",xb],["ProseH4",jb],["ProseH5",Sb],["ProseH6",Eb],["ProseHr",Tb],["ProseImg",kb],["ProseLi",Mb],["ProseOl",Cb],["ProseP",Ob],["ProseScript",Pb],["ProseStrong",Ab],["ProseTable",Rb],["ProseTbody",Lb],["ProseTd",Ib],["ProseTh",Db],["ProseThead",Fb],["ProseTr",Nb],["ProseUl",Ub]],Gb=vn({name:"nuxt:global-components",setup(r){for(const[d,w]of Bb)r.vueApp.component(d,w),r.vueApp.component("Lazy"+d,w)}}),Pn={default:()=>rt(()=>import("./Bzgpm7XF.js"),[],import.meta.url).then(r=>r.default||r),empty:()=>rt(()=>import("./8IBqTAFr.js"),[],import.meta.url).then(r=>r.default||r),light:()=>rt(()=>import("./BiZieXJo.js"),[],import.meta.url).then(r=>r.default||r)},Vb=vn({name:"nuxt:prefetch",setup(r){const d=qr();r.hooks.hook("app:mounted",()=>{d.beforeEach(async w=>{var x;const t=(x=w==null?void 0:w.meta)==null?void 0:x.layout;t&&typeof Pn[t]=="function"&&await Pn[t]()})}),r.hooks.hook("link:prefetch",w=>{if(gn(w))return;const t=d.resolve(w);if(!t)return;const x=t.meta.layout;let v=vl(t.meta.middleware);v=v.filter(s=>typeof s=="string");for(const s of v)typeof Yo[s]=="function"&&Yo[s]();x&&typeof Pn[x]=="function"&&Pn[x]()})}});function Hb(r={}){const d=r.path||window.location.pathname;let w={};try{w=Ks(sessionStorage.getItem("nuxt:reload")||"{}")}catch{}if(r.force||(w==null?void 0:w.path)!==d||(w==null?void 0:w.expires){t.clear()}),r.hook("app:chunkError",({error:v})=>{t.add(v)});function x(v){const c="href"in v&&v.href[0]==="#"?w.app.baseURL+v.href:hi(w.app.baseURL,v.fullPath);Hb({path:c,persistState:!0})}r.hook("app:manifest:update",()=>{d.beforeResolve(x)}),d.onError((v,s)=>{t.has(v)&&x(s)})}});var Rs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Wb(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function Ls(r){throw new Error('Could not dynamically require "'+r+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var oh={exports:{}};/*! p5.js v1.9.4 May 21, 2024 */(function(r,d){(function(w){r.exports=w()})(function(){var w;return function t(x,v,s){function c(g,p){if(!v[g]){if(!x[g]){var n=typeof Ls=="function"&&Ls;if(!p&&n)return n(g,!0);if(o)return o(g,!0);throw(p=new Error("Cannot find module '"+g+"'")).code="MODULE_NOT_FOUND",p}n=v[g]={exports:{}},x[g][0].call(n.exports,function(i){return c(x[g][1][i]||i)},n,n.exports,t,x,v,s)}return v[g].exports}for(var o=typeof Ls=="function"&&Ls,u=0;u>16&255,f[m++]=a>>8&255,f[m++]=255&a;return l===2&&(a=c[i.charCodeAt(h)]<<2|c[i.charCodeAt(h+1)]>>4,f[m++]=255&a),l===1&&(a=c[i.charCodeAt(h)]<<10|c[i.charCodeAt(h+1)]<<4|c[i.charCodeAt(h+2)]>>2,f[m++]=a>>8&255,f[m++]=255&a),f},v.fromByteArray=function(i){for(var a,h=i.length,y=h%3,l=[],f=0,m=h-y;f>18&63]+s[L>>12&63]+s[L>>6&63]+s[63&L]}(E));return M.join("")}(i,f,m>2]+s[a<<4&63]+"==")):y==2&&(a=(i[h-2]<<8)+i[h-1],l.push(s[a>>10]+s[a>>4&63]+s[a<<2&63]+"=")),l.join("")};for(var s=[],c=[],o=typeof Uint8Array<"u"?Uint8Array:Array,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g=0,p=u.length;g>>1;case"base64":return V(T).length;default:if($)return W?-1:q(T).length;D=(""+D).toLowerCase(),$=!0}}function m(T,D,G){var W,$=!1;if((D=D===void 0||D<0?0:D)>this.length||(G=G===void 0||G>this.length?this.length:G)<=0||(G>>>=0)<=(D>>>=0))return"";for(T=T||"utf8";;)switch(T){case"hex":var J=this,de=D,ne=G,K=J.length;(!ne||ne<0||K=T.length){if($)return-1;G=T.length-1}else if(G<0){if(!$)return-1;G=0}if(typeof D=="string"&&(D=n.from(D,W)),n.isBuffer(D))return D.length===0?-1:k(T,D,G,W,$);if(typeof D=="number")return D&=255,typeof Uint8Array.prototype.indexOf=="function"?($?Uint8Array.prototype.indexOf:Uint8Array.prototype.lastIndexOf).call(T,D,G):k(T,[D],G,W,$);throw new TypeError("val must be string, number or Buffer")}function k(T,D,G,W,$){var J=1,ne=T.length,ce=D.length;if(W!==void 0&&((W=String(W).toLowerCase())==="ucs2"||W==="ucs-2"||W==="utf16le"||W==="utf-16le")){if(T.length<2||D.length<2)return-1;ne/=J=2,ce/=2,G/=2}function ie(le,me){return J===1?le[me]:le.readUInt16BE(me*J)}if($)for(var pe=-1,K=G;K>8,ce=ce%256,ie.push(ce),ie.push(ne);return ie}(D,T.length-G),T,G,W)}function P(T,D,G){G=Math.min(T.length,G);for(var W=[],$=D;$>>10&1023|55296),K=56320|1023&K),W.push(K),$+=z}var te=W,le=te.length;if(le<=L)return String.fromCharCode.apply(String,te);for(var me="",de=0;de"u"||typeof console.error!="function"||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(n.prototype,"parent",{enumerable:!0,get:function(){if(n.isBuffer(this))return this.buffer}}),Object.defineProperty(n.prototype,"offset",{enumerable:!0,get:function(){if(n.isBuffer(this))return this.byteOffset}}),typeof Symbol<"u"&&Symbol.species!=null&&n[Symbol.species]===n&&Object.defineProperty(n,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),n.poolSize=8192,n.from=i,Object.setPrototypeOf(n.prototype,Uint8Array.prototype),Object.setPrototypeOf(n,Uint8Array),n.alloc=function(T,D,G){return D=D,G=G,a(T=T),!(T<=0)&&D!==void 0?typeof G=="string"?p(T).fill(D,G):p(T).fill(D):p(T)},n.allocUnsafe=h,n.allocUnsafeSlow=h,n.isBuffer=function(T){return T!=null&&T._isBuffer===!0&&T!==n.prototype},n.compare=function(T,D){if(Z(T,Uint8Array)&&(T=n.from(T,T.offset,T.byteLength)),Z(D,Uint8Array)&&(D=n.from(D,D.offset,D.byteLength)),!n.isBuffer(T)||!n.isBuffer(D))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(T===D)return 0;for(var G=T.length,W=D.length,$=0,J=Math.min(G,W);$T&&(D+=" ... "),""},u&&(n.prototype[u]=n.prototype.inspect),n.prototype.compare=function(T,D,G,W,$){if(Z(T,Uint8Array)&&(T=n.from(T,T.offset,T.byteLength)),!n.isBuffer(T))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof T);if(G===void 0&&(G=T?T.length:0),W===void 0&&(W=0),$===void 0&&($=this.length),(D=D===void 0?0:D)<0||G>T.length||W<0||$>this.length)throw new RangeError("out of range index");if($<=W&&G<=D)return 0;if($<=W)return-1;if(G<=D)return 1;if(this===T)return 0;for(var J=($>>>=0)-(W>>>=0),ne=(G>>>=0)-(D>>>=0),ce=Math.min(J,ne),ie=this.slice(W,$),pe=T.slice(D,G),K=0;K>>=0,isFinite(G)?(G>>>=0,W===void 0&&(W="utf8")):(W=G,G=void 0)}var $=this.length-D;if((G===void 0||$this.length)throw new RangeError("Attempt to write outside buffer bounds");W=W||"utf8";for(var J,ne,ce,ie=!1;;)switch(W){case"hex":var pe=this,K=T,z=D,te=G,le=(z=Number(z)||0,pe.length-z);(!te||le<(te=Number(te)))&&(te=le),(le=K.length)/2T.length)throw new RangeError("Index out of range")}function A(T,D,G,W){if(G+W>T.length)throw new RangeError("Index out of range");if(G<0)throw new RangeError("Index out of range")}function N(T,D,G,W,$){return D=+D,G>>>=0,$||A(T,0,G,4),o.write(T,D,G,W,23,4),G+4}function F(T,D,G,W,$){return D=+D,G>>>=0,$||A(T,0,G,8),o.write(T,D,G,W,52,8),G+8}n.prototype.slice=function(T,D){var G=this.length,G=((T=~~T)<0?(T+=G)<0&&(T=0):G>>=0,D>>>=0,G||C(T,D,this.length);for(var W=this[T],$=1,J=0;++J>>=0,D>>>=0,G||C(T,D,this.length);for(var W=this[T+--D],$=1;0>>=0,D||C(T,1,this.length),this[T]},n.prototype.readUInt16LE=function(T,D){return T>>>=0,D||C(T,2,this.length),this[T]|this[T+1]<<8},n.prototype.readUInt16BE=function(T,D){return T>>>=0,D||C(T,2,this.length),this[T]<<8|this[T+1]},n.prototype.readUInt32LE=function(T,D){return T>>>=0,D||C(T,4,this.length),(this[T]|this[T+1]<<8|this[T+2]<<16)+16777216*this[T+3]},n.prototype.readUInt32BE=function(T,D){return T>>>=0,D||C(T,4,this.length),16777216*this[T]+(this[T+1]<<16|this[T+2]<<8|this[T+3])},n.prototype.readIntLE=function(T,D,G){T>>>=0,D>>>=0,G||C(T,D,this.length);for(var W=this[T],$=1,J=0;++J>>=0,D>>>=0,G||C(T,D,this.length);for(var W=D,$=1,J=this[T+--W];0>>=0,D||C(T,1,this.length),128&this[T]?-1*(255-this[T]+1):this[T]},n.prototype.readInt16LE=function(T,D){return T>>>=0,D||C(T,2,this.length),D=this[T]|this[T+1]<<8,32768&D?4294901760|D:D},n.prototype.readInt16BE=function(T,D){return T>>>=0,D||C(T,2,this.length),D=this[T+1]|this[T]<<8,32768&D?4294901760|D:D},n.prototype.readInt32LE=function(T,D){return T>>>=0,D||C(T,4,this.length),this[T]|this[T+1]<<8|this[T+2]<<16|this[T+3]<<24},n.prototype.readInt32BE=function(T,D){return T>>>=0,D||C(T,4,this.length),this[T]<<24|this[T+1]<<16|this[T+2]<<8|this[T+3]},n.prototype.readFloatLE=function(T,D){return T>>>=0,D||C(T,4,this.length),o.read(this,T,!0,23,4)},n.prototype.readFloatBE=function(T,D){return T>>>=0,D||C(T,4,this.length),o.read(this,T,!1,23,4)},n.prototype.readDoubleLE=function(T,D){return T>>>=0,D||C(T,8,this.length),o.read(this,T,!0,52,8)},n.prototype.readDoubleBE=function(T,D){return T>>>=0,D||C(T,8,this.length),o.read(this,T,!1,52,8)},n.prototype.writeUIntLE=function(T,D,G,W){T=+T,D>>>=0,G>>>=0,W||I(this,T,D,G,Math.pow(2,8*G)-1,0);var $=1,J=0;for(this[D]=255&T;++J>>=0,G>>>=0,W||I(this,T,D,G,Math.pow(2,8*G)-1,0);var $=G-1,J=1;for(this[D+$]=255&T;0<=--$&&(J*=256);)this[D+$]=T/J&255;return D+G},n.prototype.writeUInt8=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,1,255,0),this[D]=255&T,D+1},n.prototype.writeUInt16LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,65535,0),this[D]=255&T,this[D+1]=T>>>8,D+2},n.prototype.writeUInt16BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,65535,0),this[D]=T>>>8,this[D+1]=255&T,D+2},n.prototype.writeUInt32LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,4294967295,0),this[D+3]=T>>>24,this[D+2]=T>>>16,this[D+1]=T>>>8,this[D]=255&T,D+4},n.prototype.writeUInt32BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,4294967295,0),this[D]=T>>>24,this[D+1]=T>>>16,this[D+2]=T>>>8,this[D+3]=255&T,D+4},n.prototype.writeIntLE=function(T,D,G,W){T=+T,D>>>=0,W||I(this,T,D,G,(W=Math.pow(2,8*G-1))-1,-W);var $=0,J=1,ne=0;for(this[D]=255&T;++$>0)-ne&255;return D+G},n.prototype.writeIntBE=function(T,D,G,W){T=+T,D>>>=0,W||I(this,T,D,G,(W=Math.pow(2,8*G-1))-1,-W);var $=G-1,J=1,ne=0;for(this[D+$]=255&T;0<=--$&&(J*=256);)T<0&&ne===0&&this[D+$+1]!==0&&(ne=1),this[D+$]=(T/J>>0)-ne&255;return D+G},n.prototype.writeInt8=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,1,127,-128),this[D]=255&(T=T<0?255+T+1:T),D+1},n.prototype.writeInt16LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,32767,-32768),this[D]=255&T,this[D+1]=T>>>8,D+2},n.prototype.writeInt16BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,2,32767,-32768),this[D]=T>>>8,this[D+1]=255&T,D+2},n.prototype.writeInt32LE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,2147483647,-2147483648),this[D]=255&T,this[D+1]=T>>>8,this[D+2]=T>>>16,this[D+3]=T>>>24,D+4},n.prototype.writeInt32BE=function(T,D,G){return T=+T,D>>>=0,G||I(this,T,D,4,2147483647,-2147483648),this[D]=(T=T<0?4294967295+T+1:T)>>>24,this[D+1]=T>>>16,this[D+2]=T>>>8,this[D+3]=255&T,D+4},n.prototype.writeFloatLE=function(T,D,G){return N(this,T,D,!0,G)},n.prototype.writeFloatBE=function(T,D,G){return N(this,T,D,!1,G)},n.prototype.writeDoubleLE=function(T,D,G){return F(this,T,D,!0,G)},n.prototype.writeDoubleBE=function(T,D,G){return F(this,T,D,!1,G)},n.prototype.copy=function(T,D,G,W){if(!n.isBuffer(T))throw new TypeError("argument should be a Buffer");if(G=G||0,W||W===0||(W=this.length),D>=T.length&&(D=T.length),(W=0=this.length)throw new RangeError("Index out of range");if(W<0)throw new RangeError("sourceEnd out of bounds");W>this.length&&(W=this.length);var $=(W=T.length-D>>=0,G=G===void 0?this.length:G>>>0,typeof(T=T||0)=="number")for(J=D;J>6|192,63&G|128)}else if(G<65536){if((D-=3)<0)break;J.push(G>>12|224,G>>6&63|128,63&G|128)}else{if(!(G<1114112))throw new Error("Invalid code point");if((D-=4)<0)break;J.push(G>>18|240,G>>12&63|128,G>>6&63|128,63&G|128)}}return J}function V(T){return c.toByteArray(function(D){if((D=(D=D.split("=")[0]).trim().replace(B,"")).length<2)return"";for(;D.length%4!=0;)D+="=";return D}(T))}function H(T,D,G,W){for(var $=0;$=D.length||$>=T.length);++$)D[$+G]=T[$];return $}function Z(T,D){return T instanceof D||T!=null&&T.constructor!=null&&T.constructor.name!=null&&T.constructor.name===D.name}function ee(T){return T!=T}var ue=function(){for(var T="0123456789abcdef",D=new Array(256),G=0;G<16;++G)for(var W=16*G,$=0;$<16;++$)D[W+$]=T[G]+T[$];return D}()}).call(this,t("buffer").Buffer)},{"base64-js":1,buffer:4,ieee754:251}],5:[function(t,x,v){x.exports=function(s){if(typeof s!="function")throw TypeError(String(s)+" is not a function");return s}},{}],6:[function(t,x,v){var s=t("../internals/is-object");x.exports=function(c){if(s(c)||c===null)return c;throw TypeError("Can't set "+String(c)+" as a prototype")}},{"../internals/is-object":75}],7:[function(o,x,v){var s=o("../internals/well-known-symbol"),c=o("../internals/object-create"),o=o("../internals/object-define-property"),u=s("unscopables"),g=Array.prototype;g[u]==null&&o.f(g,u,{configurable:!0,value:c(null)}),x.exports=function(p){g[u][p]=!0}},{"../internals/object-create":91,"../internals/object-define-property":93,"../internals/well-known-symbol":149}],8:[function(t,x,v){var s=t("../internals/string-multibyte").charAt;x.exports=function(c,o,u){return o+(u?s(c,o).length:1)}},{"../internals/string-multibyte":124}],9:[function(t,x,v){x.exports=function(s,c,o){if(s instanceof c)return s;throw TypeError("Incorrect "+(o?o+" ":"")+"invocation")}},{}],10:[function(t,x,v){var s=t("../internals/is-object");x.exports=function(c){if(s(c))return c;throw TypeError(String(c)+" is not an object")}},{"../internals/is-object":75}],11:[function(t,x,v){x.exports=typeof ArrayBuffer<"u"&&typeof DataView<"u"},{}],12:[function(A,x,v){function s(F){return p(F)&&n(N,i(F))}var c,o=A("../internals/array-buffer-native"),u=A("../internals/descriptors"),g=A("../internals/global"),p=A("../internals/is-object"),n=A("../internals/has"),i=A("../internals/classof"),a=A("../internals/create-non-enumerable-property"),h=A("../internals/redefine"),y=A("../internals/object-define-property").f,l=A("../internals/object-get-prototype-of"),f=A("../internals/object-set-prototype-of"),L=A("../internals/well-known-symbol"),A=A("../internals/uid"),m=g.Int8Array,b=m&&m.prototype,j=g.Uint8ClampedArray,j=j&&j.prototype,k=m&&l(m),E=b&&l(b),M=Object.prototype,P=M.isPrototypeOf,L=L("toStringTag"),C=A("TYPED_ARRAY_TAG"),I=o&&!!f&&i(g.opera)!=="Opera",A=!1,N={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8};for(c in N)g[c]||(I=!1);if((!I||typeof k!="function"||k===Function.prototype)&&(k=function(){throw TypeError("Incorrect invocation")},I))for(c in N)g[c]&&f(g[c],k);if((!I||!E||E===M)&&(E=k.prototype,I))for(c in N)g[c]&&f(g[c].prototype,E);if(I&&l(j)!==E&&f(j,E),u&&!n(E,L))for(c in A=!0,y(E,L,{get:function(){return p(this)?this[C]:void 0}}),N)g[c]&&a(g[c],C,c);x.exports={NATIVE_ARRAY_BUFFER_VIEWS:I,TYPED_ARRAY_TAG:A&&C,aTypedArray:function(F){if(s(F))return F;throw TypeError("Target is not a typed array")},aTypedArrayConstructor:function(F){if(f){if(P.call(k,F))return F}else for(var B in N)if(n(N,c)&&(B=g[B],B&&(F===B||P.call(B,F))))return F;throw TypeError("Target is not a typed array constructor")},exportTypedArrayMethod:function(F,B,q){if(u){if(q)for(var V in N)V=g[V],V&&n(V.prototype,F)&&delete V.prototype[F];E[F]&&!q||h(E,F,!q&&I&&b[F]||B)}},exportTypedArrayStaticMethod:function(F,B,q){var V,H;if(u){if(f){if(q)for(V in N)(H=g[V])&&n(H,F)&&delete H[F];if(k[F]&&!q)return;try{return h(k,F,!q&&I&&m[F]||B)}catch{}}for(V in N)!(H=g[V])||H[F]&&!q||h(H,F,B)}},isView:function(F){return F=i(F),F==="DataView"||n(N,F)},isTypedArray:s,TypedArray:k,TypedArrayPrototype:E}},{"../internals/array-buffer-native":11,"../internals/classof":29,"../internals/create-non-enumerable-property":38,"../internals/descriptors":43,"../internals/global":60,"../internals/has":61,"../internals/is-object":75,"../internals/object-define-property":93,"../internals/object-get-prototype-of":98,"../internals/object-set-prototype-of":102,"../internals/redefine":109,"../internals/uid":146,"../internals/well-known-symbol":149}],13:[function(G,x,v){function s(z){return[255&z]}function c(z){return[255&z,z>>8&255]}function o(z){return[255&z,z>>8&255,z>>16&255,z>>24&255]}function u(z){return z[3]<<24|z[2]<<16|z[1]<<8|z[0]}function g(z){return J(z,23,4)}function p(z){return J(z,52,8)}function n(z,te){A(z[Z],te,{get:function(){return B(this)[te]}})}function i(ge,te,ye,me){if(ye=M(ye),ge=B(ge),ye+te>ge.byteLength)throw $(ee);var de=B(ge.buffer).bytes,ye=ye+ge.byteOffset,ge=de.slice(ye,ye+te);return me?ge:ge.reverse()}function a(z,te,le,me,de,ye){if(le=M(le),z=B(z),le+te>z.byteLength)throw $(ee);for(var ge=B(z.buffer).bytes,ke=le+z.byteOffset,ve=me(+de),Ie=0;Iepe;)(ce=ie[pe++])in T||f(T,ce,ue[ce]);h.constructor=T}C&&L(G)!==W&&C(G,W);var P=new D(new T(2)),K=G.setInt8;P.setInt8(0,2147483648),P.setInt8(1,2147483649),!P.getInt8(0)&&P.getInt8(1)||m(G,{setInt8:function(te,le){K.call(this,te,le<<24>>24)},setUint8:function(te,le){K.call(this,te,le<<24>>24)}},{unsafe:!0})}else T=function(z){j(this,T,V),z=M(z),q(this,{bytes:N.call(new Array(z),0),byteLength:z}),y||(this.byteLength=z)},D=function(z,de,le){j(this,D,H),j(z,T,H);var me=B(z).byteLength,de=k(de);if(de<0||me>24},getUint8:function(z){return i(this,1,z)[0]},getInt16:function(z){return z=i(this,2,z,1>16},getUint16:function(z){return z=i(this,2,z,1>>0},getFloat32:function(z){return ne(i(this,4,z,1"+n+""}},{"../internals/require-object-coercible":114}],37:[function(t,x,v){function s(){return this}var c=t("../internals/iterators-core").IteratorPrototype,o=t("../internals/object-create"),u=t("../internals/create-property-descriptor"),g=t("../internals/set-to-string-tag"),p=t("../internals/iterators");x.exports=function(n,i,a){return i+=" Iterator",n.prototype=o(c,{next:u(1,a)}),g(n,i,!1,!0),p[i]=s,n}},{"../internals/create-property-descriptor":39,"../internals/iterators":80,"../internals/iterators-core":79,"../internals/object-create":91,"../internals/set-to-string-tag":118}],38:[function(t,x,v){var s=t("../internals/descriptors"),c=t("../internals/object-define-property"),o=t("../internals/create-property-descriptor");x.exports=s?function(u,g,p){return c.f(u,g,o(1,p))}:function(u,g,p){return u[g]=p,u}},{"../internals/create-property-descriptor":39,"../internals/descriptors":43,"../internals/object-define-property":93}],39:[function(t,x,v){x.exports=function(s,c){return{enumerable:!(1&s),configurable:!(2&s),writable:!(4&s),value:c}}},{}],40:[function(t,x,v){var s=t("../internals/to-primitive"),c=t("../internals/object-define-property"),o=t("../internals/create-property-descriptor");x.exports=function(u,g,p){g=s(g),g in u?c.f(u,g,o(0,p)):u[g]=p}},{"../internals/create-property-descriptor":39,"../internals/object-define-property":93,"../internals/to-primitive":141}],41:[function(l,x,v){function s(){return this}var c=l("../internals/export"),o=l("../internals/create-iterator-constructor"),u=l("../internals/object-get-prototype-of"),g=l("../internals/object-set-prototype-of"),p=l("../internals/set-to-string-tag"),n=l("../internals/create-non-enumerable-property"),i=l("../internals/redefine"),a=l("../internals/well-known-symbol"),h=l("../internals/is-pure"),y=l("../internals/iterators"),l=l("../internals/iterators-core"),f=l.IteratorPrototype,m=l.BUGGY_SAFARI_ITERATORS,b=a("iterator"),j="values",k="entries";x.exports=function(E,M,P,q,C,I,A){o(P,M,q);function N(T){if(T===C&&ee)return ee;if(!m&&T in H)return H[T];switch(T){case"keys":case j:case k:return function(){return new P(this,T)}}return function(){return new P(this)}}var F,B,q=M+" Iterator",V=!1,H=E.prototype,Z=H[b]||H["@@iterator"]||C&&H[C],ee=!m&&Z||N(C),ue=M=="Array"&&H.entries||Z;if(ue&&(ue=u(ue.call(new E)),f!==Object.prototype&&ue.next&&(h||u(ue)===f||(g?g(ue,f):typeof ue[b]!="function"&&n(ue,b,s)),p(ue,q,!0,!0),h&&(y[q]=s))),C==j&&Z&&Z.name!==j&&(V=!0,ee=function(){return Z.call(this)}),h&&!A||H[b]===ee||n(H,b,ee),y[M]=ee,C)if(F={values:N(j),keys:I?ee:N("keys"),entries:N(k)},A)for(B in F)!m&&!V&&B in H||i(H,B,F[B]);else c({target:M,proto:!0,forced:m||V},F);return F}},{"../internals/create-iterator-constructor":37,"../internals/create-non-enumerable-property":38,"../internals/export":50,"../internals/is-pure":76,"../internals/iterators":80,"../internals/iterators-core":79,"../internals/object-get-prototype-of":98,"../internals/object-set-prototype-of":102,"../internals/redefine":109,"../internals/set-to-string-tag":118,"../internals/well-known-symbol":149}],42:[function(t,x,v){var s=t("../internals/path"),c=t("../internals/has"),o=t("../internals/well-known-symbol-wrapped"),u=t("../internals/object-define-property").f;x.exports=function(g){var p=s.Symbol||(s.Symbol={});c(p,g)||u(p,g,{value:o.f(g)})}},{"../internals/has":61,"../internals/object-define-property":93,"../internals/path":105,"../internals/well-known-symbol-wrapped":148}],43:[function(t,x,v){t=t("../internals/fails"),x.exports=!t(function(){return Object.defineProperty({},1,{get:function(){return 7}})[1]!=7})},{"../internals/fails":51}],44:[function(c,x,v){var s=c("../internals/global"),c=c("../internals/is-object"),o=s.document,u=c(o)&&c(o.createElement);x.exports=function(g){return u?o.createElement(g):{}}},{"../internals/global":60,"../internals/is-object":75}],45:[function(t,x,v){x.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},{}],46:[function(t,x,v){t=t("../internals/engine-user-agent"),x.exports=/(iphone|ipod|ipad).*applewebkit/i.test(t)},{"../internals/engine-user-agent":47}],47:[function(t,x,v){t=t("../internals/get-built-in"),x.exports=t("navigator","userAgent")||""},{"../internals/get-built-in":57}],48:[function(o,x,v){var s,c,u=o("../internals/global"),o=o("../internals/engine-user-agent"),u=u.process,u=u&&u.versions,u=u&&u.v8;u?c=(s=u.split("."))[0]+s[1]:o&&(!(s=o.match(/Edge\/(\d+)/))||74<=s[1])&&(s=o.match(/Chrome\/(\d+)/))&&(c=s[1]),x.exports=c&&+c},{"../internals/engine-user-agent":47,"../internals/global":60}],49:[function(t,x,v){x.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},{}],50:[function(t,x,v){var s=t("../internals/global"),c=t("../internals/object-get-own-property-descriptor").f,o=t("../internals/create-non-enumerable-property"),u=t("../internals/redefine"),g=t("../internals/set-global"),p=t("../internals/copy-constructor-properties"),n=t("../internals/is-forced");x.exports=function(i,a){var h,y,l,f=i.target,m=i.global,b=i.stat,j=m?s:b?s[f]||g(f,{}):(s[f]||{}).prototype;if(j)for(h in a){if(y=a[h],l=i.noTargetGet?(l=c(j,h))&&l.value:j[h],!n(m?h:f+(b?".":"#")+h,i.forced)&&l!==void 0){if(typeof y==typeof l)continue;p(y,l)}(i.sham||l&&l.sham)&&o(y,"sham",!0),u(j,h,y,i)}}},{"../internals/copy-constructor-properties":33,"../internals/create-non-enumerable-property":38,"../internals/global":60,"../internals/is-forced":74,"../internals/object-get-own-property-descriptor":94,"../internals/redefine":109,"../internals/set-global":116}],51:[function(t,x,v){x.exports=function(s){try{return!!s()}catch{return!0}}},{}],52:[function(a,x,v){a("../modules/es.regexp.exec");var s=a("../internals/redefine"),c=a("../internals/fails"),o=a("../internals/well-known-symbol"),u=a("../internals/regexp-exec"),g=a("../internals/create-non-enumerable-property"),p=o("species"),n=!c(function(){var l=/./;return l.exec=function(){var f=[];return f.groups={a:"7"},f},"".replace(l,"$")!=="7"}),i="a".replace(/./,"$0")==="$0",a=o("replace"),h=!!/./[a]&&/./[a]("a","$0")==="",y=!c(function(){var f=/(?:)/,l=f.exec,f=(f.exec=function(){return l.apply(this,arguments)},"ab".split(f));return f.length!==2||f[0]!=="a"||f[1]!=="b"});x.exports=function(l,f,m,b){var j,k,E=o(l),M=!c(function(){var L={};return L[E]=function(){return 7},""[l](L)!=7}),P=M&&!c(function(){var L=!1,C=/a/;return l==="split"&&((C={constructor:{}}).constructor[p]=function(){return C},C.flags="",C[E]=/./[E]),C.exec=function(){return L=!0,null},C[E](""),!L});M&&P&&(l!=="replace"||n&&i&&!h)&&(l!=="split"||y)||(j=/./[E],m=(P=m(E,""[l],function(L,C,I,A,N){return C.exec===u?M&&!N?{done:!0,value:j.call(C,I,A)}:{done:!0,value:L.call(I,C,A)}:{done:!1}},{REPLACE_KEEPS_$0:i,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:h}))[0],k=P[1],s(String.prototype,l,m),s(RegExp.prototype,E,f==2?function(L,C){return k.call(L,this,C)}:function(L){return k.call(L,this)})),b&&g(RegExp.prototype[E],"sham",!0)}},{"../internals/create-non-enumerable-property":38,"../internals/fails":51,"../internals/redefine":109,"../internals/regexp-exec":111,"../internals/well-known-symbol":149,"../modules/es.regexp.exec":192}],53:[function(t,x,v){function s(g,p,n,i,a,h,y,l){for(var f,m=a,b=0,j=!!y&&u(y,l,3);b>1,j=n===23?c(2,-24)-c(2,-77):0,k=p<0||p===0&&1/p<0?1:0,E=0;for((p=s(p))!=p||p===1/0?(h=p!=p?1:0,a=m):(a=o(u(p)/g),p*(y=c(2,-a))<1&&(a--,y*=2),2<=(p+=1<=a+b?j/y:j*c(2,1-b))*y&&(a++,y/=2),m<=a+b?(h=0,a=m):1<=a+b?(h=(p*y-1)*c(2,n),a+=b):(h=p*c(2,b-1)*c(2,n),a=0));8<=n;l[E++]=255&h,h/=256,n-=8);for(a=a<>1,l=m-7,f=a-1,m=p[f--],b=127&m;for(m>>=7;0>=-l,l+=n;0"+b+""},m=function(){try{c=document.domain&&new ActiveXObject("htmlfile")}catch{}m=c?((b=c).write(f("")),b.close(),j=b.parentWindow.Object,b=null,j):(b=i("iframe"),j="java"+y+":",b.style.display="none",n.appendChild(b),b.src=String(j),(j=b.contentWindow.document).open(),j.write(f("document.F=Object")),j.close(),j.F);for(var b,j,k=g.length;k--;)delete m[h][g[k]];return m()};p[l]=!0,x.exports=Object.create||function(b,j){var k;return b!==null?(s[h]=o(b),k=new s,s[h]=null,k[l]=b):k=m(),j===void 0?k:u(k,j)}},{"../internals/an-object":10,"../internals/document-create-element":44,"../internals/enum-bug-keys":49,"../internals/hidden-keys":62,"../internals/html":64,"../internals/object-define-properties":92,"../internals/shared-key":119}],92:[function(t,x,v){var s=t("../internals/descriptors"),c=t("../internals/object-define-property"),o=t("../internals/an-object"),u=t("../internals/object-keys");x.exports=s?Object.defineProperties:function(g,p){o(g);for(var n,i=u(p),a=i.length,h=0;ha;)!s(i,n=p[a++])||~o(h,n)||h.push(n);return h}},{"../internals/array-includes":18,"../internals/has":61,"../internals/hidden-keys":62,"../internals/to-indexed-object":135}],100:[function(t,x,v){var s=t("../internals/object-keys-internal"),c=t("../internals/enum-bug-keys");x.exports=Object.keys||function(o){return s(o,c)}},{"../internals/enum-bug-keys":49,"../internals/object-keys-internal":99}],101:[function(t,x,v){var s={}.propertyIsEnumerable,c=Object.getOwnPropertyDescriptor,o=c&&!s.call({1:2},1);v.f=o?function(u){return u=c(this,u),!!u&&u.enumerable}:s},{}],102:[function(t,x,v){var s=t("../internals/an-object"),c=t("../internals/a-possible-prototype");x.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var o,u=!1,g={};try{(o=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set).call(g,[]),u=g instanceof Array}catch{}return function(p,n){return s(p),c(n),u?o.call(p,n):p.__proto__=n,p}}():void 0)},{"../internals/a-possible-prototype":6,"../internals/an-object":10}],103:[function(t,x,v){var s=t("../internals/to-string-tag-support"),c=t("../internals/classof");x.exports=s?{}.toString:function(){return"[object "+c(this)+"]"}},{"../internals/classof":29,"../internals/to-string-tag-support":142}],104:[function(t,x,v){var s=t("../internals/get-built-in"),c=t("../internals/object-get-own-property-names"),o=t("../internals/object-get-own-property-symbols"),u=t("../internals/an-object");x.exports=s("Reflect","ownKeys")||function(g){var p=c.f(u(g)),n=o.f;return n?p.concat(n(g)):p}},{"../internals/an-object":10,"../internals/get-built-in":57,"../internals/object-get-own-property-names":96,"../internals/object-get-own-property-symbols":97}],105:[function(t,x,v){t=t("../internals/global"),x.exports=t},{"../internals/global":60}],106:[function(t,x,v){x.exports=function(s){try{return{error:!1,value:s()}}catch(c){return{error:!0,value:c}}}},{}],107:[function(t,x,v){var s=t("../internals/an-object"),c=t("../internals/is-object"),o=t("../internals/new-promise-capability");x.exports=function(u,g){return s(u),c(g)&&g.constructor===u?g:((0,(u=o.f(u)).resolve)(g),u.promise)}},{"../internals/an-object":10,"../internals/is-object":75,"../internals/new-promise-capability":87}],108:[function(t,x,v){var s=t("../internals/redefine");x.exports=function(c,o,u){for(var g in o)s(c,g,o[g],u);return c}},{"../internals/redefine":109}],109:[function(p,x,v){var s=p("../internals/global"),c=p("../internals/create-non-enumerable-property"),o=p("../internals/has"),u=p("../internals/set-global"),g=p("../internals/inspect-source"),p=p("../internals/internal-state"),n=p.get,i=p.enforce,a=String(String).split("String");(x.exports=function(h,y,l,j){var m=!!j&&!!j.unsafe,b=!!j&&!!j.enumerable,j=!!j&&!!j.noTargetGet;typeof l=="function"&&(typeof y!="string"||o(l,"name")||c(l,"name",y),i(l).source=a.join(typeof y=="string"?y:"")),h===s?b?h[y]=l:u(y,l):(m?!j&&h[y]&&(b=!0):delete h[y],b?h[y]=l:c(h,y,l))})(Function.prototype,"toString",function(){return typeof this=="function"&&n(this).source||g(this)})},{"../internals/create-non-enumerable-property":38,"../internals/global":60,"../internals/has":61,"../internals/inspect-source":69,"../internals/internal-state":71,"../internals/set-global":116}],110:[function(t,x,v){var s=t("./classof-raw"),c=t("./regexp-exec");x.exports=function(o,u){var g=o.exec;if(typeof g=="function"){if(g=g.call(o,u),typeof g!="object")throw TypeError("RegExp exec method returned something other than an Object or null");return g}if(s(o)!=="RegExp")throw TypeError("RegExp#exec called on incompatible receiver");return c.call(o,u)}},{"./classof-raw":28,"./regexp-exec":111}],111:[function(u,x,v){var s,c,o=u("./regexp-flags"),u=u("./regexp-sticky-helpers"),g=RegExp.prototype.exec,p=String.prototype.replace,n=g,i=(s=/a/,c=/b*/g,g.call(s,"a"),g.call(c,"a"),s.lastIndex!==0||c.lastIndex!==0),a=u.UNSUPPORTED_Y||u.BROKEN_CARET,h=/()??/.exec("")[1]!==void 0;x.exports=n=i||h||a?function(y){var l,f,m,b,j=this,k=a&&j.sticky,E=o.call(j),M=j.source,P=0,L=y;return k&&((E=E.replace("y","")).indexOf("g")===-1&&(E+="g"),L=String(y).slice(j.lastIndex),0f&&(y=y.slice(0,f)),p?h+y:y+h)}}var c=t("../internals/to-length"),o=t("../internals/string-repeat"),u=t("../internals/require-object-coercible"),g=Math.ceil;x.exports={start:s(!1),end:s(!0)}},{"../internals/require-object-coercible":114,"../internals/string-repeat":128,"../internals/to-length":137}],127:[function(t,x,v){function s(m){return m+22+75*(m<26)}function c(m){var b,j=[],k=(m=function(Z){for(var ee=[],ue=0,T=Z.length;uel((o-M)/N))throw RangeError(h);for(M+=(I-E)*N,E=I,A=0;Ao)throw RangeError(h);if(b==E){for(var F=M,B=u;;B+=u){var q=B<=P?1:P+g<=B?g:B-P;if(F>1,Z+=l(Z/ee);y*g>>1>>=1)&&(u+=u))1&p&&(g+=u);return g}},{"../internals/require-object-coercible":114,"../internals/to-integer":136}],129:[function(t,x,v){var s=t("../internals/fails"),c=t("../internals/whitespaces");x.exports=function(o){return s(function(){return!!c[o]()||"​…᠎"[o]()!="​…᠎"||c[o].name!==o})}},{"../internals/fails":51,"../internals/whitespaces":150}],130:[function(o,x,v){function s(p){return function(n){return n=String(c(n)),1&p&&(n=n.replace(u,"")),n=2&p?n.replace(g,""):n}}var c=o("../internals/require-object-coercible"),o="["+o("../internals/whitespaces")+"]",u=RegExp("^"+o+o+"*"),g=RegExp(o+o+"*$");x.exports={start:s(1),end:s(2),trim:s(3)}},{"../internals/require-object-coercible":114,"../internals/whitespaces":150}],131:[function(y,x,v){function s(C){return function(){L(C)}}function c(C){L(C.data)}function o(C){g.postMessage(C+"",l.protocol+"//"+l.host)}var u,g=y("../internals/global"),p=y("../internals/fails"),n=y("../internals/classof-raw"),i=y("../internals/function-bind-context"),a=y("../internals/html"),h=y("../internals/document-create-element"),y=y("../internals/engine-is-ios"),l=g.location,f=g.setImmediate,m=g.clearImmediate,b=g.process,j=g.MessageChannel,k=g.Dispatch,E=0,M={},P="onreadystatechange",L=function(C){var I;M.hasOwnProperty(C)&&(I=M[C],delete M[C],I())};f&&m||(f=function(C){for(var I=[],A=1;A=h.length?{value:a.target=void 0,done:!0}:y=="keys"?{value:l,done:!1}:y=="values"?{value:h[l],done:!1}:{value:[l,h[l]],done:!1}},"values"),o.Arguments=o.Array,c("keys"),c("values"),c("entries")},{"../internals/add-to-unscopables":7,"../internals/define-iterator":41,"../internals/internal-state":71,"../internals/iterators":80,"../internals/to-indexed-object":135}],165:[function(g,x,v){var s=g("../internals/export"),u=g("../internals/indexed-object"),c=g("../internals/to-indexed-object"),g=g("../internals/array-method-is-strict"),o=[].join,u=u!=Object,g=g("join",",");s({target:"Array",proto:!0,forced:u||!g},{join:function(p){return o.call(c(this),p===void 0?",":p)}})},{"../internals/array-method-is-strict":22,"../internals/export":50,"../internals/indexed-object":67,"../internals/to-indexed-object":135}],166:[function(c,x,v){var s=c("../internals/export"),c=c("../internals/array-last-index-of");s({target:"Array",proto:!0,forced:c!==[].lastIndexOf},{lastIndexOf:c})},{"../internals/array-last-index-of":20,"../internals/export":50}],167:[function(u,x,v){var s=u("../internals/export"),c=u("../internals/array-iteration").map,o=u("../internals/array-method-has-species-support"),u=u("../internals/array-method-uses-to-length"),o=o("map"),u=u("map");s({target:"Array",proto:!0,forced:!o||!u},{map:function(g){return c(this,g,1I;I++)p(k,P=C[I])&&!p(L,P)&&m(L,P,f(k,P));(L.prototype=E).constructor=L,g(o,j,L)}},{"../internals/classof-raw":28,"../internals/descriptors":43,"../internals/fails":51,"../internals/global":60,"../internals/has":61,"../internals/inherit-if-required":68,"../internals/is-forced":74,"../internals/object-create":91,"../internals/object-define-property":93,"../internals/object-get-own-property-descriptor":94,"../internals/object-get-own-property-names":96,"../internals/redefine":109,"../internals/string-trim":130,"../internals/to-primitive":141}],179:[function(t,x,v){t("../internals/export")({target:"Number",stat:!0},{isFinite:t("../internals/number-is-finite")})},{"../internals/export":50,"../internals/number-is-finite":89}],180:[function(p,x,v){function s(a,h,y){return h===0?y:h%2==1?s(a,h-1,y*a):s(a*a,h/2,y)}var c=p("../internals/export"),o=p("../internals/to-integer"),u=p("../internals/this-number-value"),g=p("../internals/string-repeat"),p=p("../internals/fails"),n=1 .toFixed,i=Math.floor;c({target:"Number",proto:!0,forced:n&&(8e-5.toFixed(3)!=="0.000"||.9.toFixed(0)!=="1"||1.255.toFixed(2)!=="1.25"||0xde0b6b3a7640080.toFixed(0)!=="1000000000000000128")||!p(function(){n.call({})})},{toFixed:function(j){function h(P,L){for(var C=-1,I=L;++C<6;)I+=P*k[C],k[C]=I%1e7,I=i(I/1e7)}function y(P){for(var L=6,C=0;0<=--L;)C+=k[L],k[L]=i(C/P),C=C%P*1e7}function l(){for(var P,L=6,C="";0<=--L;)C===""&&L!==0&&k[L]===0||(P=String(k[L]),C=C===""?P:C+g.call("0",7-P.length)+P);return C}var f,m,b=u(this),j=o(j),k=[0,0,0,0,0,0],E="",M="0";if(j<0||20Pe;){var He,We,qe,Ye=se[Pe++],lt=Se?Ye.ok:Ye.fail,ot=Ye.resolve,Ze=Ye.reject,it=Ye.domain;try{lt?(Se||(Ee.rejection===ye&&function(nt,kt){C.call(n,function(){pe?J.emit("rejectionHandled",nt):De(te,nt,kt.value)})}(Re,Ee),Ee.rejection=de),lt===!0?He=we:(it&&it.enter(),He=lt(we),it&&(it.exit(),qe=!0)),He===Ye.promise?Ze(W("Promise-chain cycle")):(We=ve(He))?We.call(He,ot,Ze):ot(He)):Ze(we)}catch(nt){it&&!qe&&it.exit(),Ze(nt)}}Ee.reactions=[],Ee.notified=!1,re&&!Ee.rejection&&(Q=Re,ae=Ee,C.call(n,function(){var nt=ae.value,kt=Le(ae);if(kt&&(kt=B(function(){pe?J.emit("unhandledRejection",nt,Q):De(z,Q,nt)}),ae.rejection=pe||Le(ae)?ye:de,kt.error))throw kt.value}))}))},De=function(Re,Ee,re){var se;K?((se=$.createEvent("Event")).promise=Ee,se.reason=re,se.initEvent(Re,!1,!0),n.dispatchEvent(se)):se={promise:Ee,reason:re},(Ee=n["on"+Re])?Ee(se):Re===z&&N("Unhandled promise rejection",re)},Le=function(Re){return Re.rejection!==de&&!Re.parent},Ne=function(Re,Ee,re,se){return function(Q){Re(Ee,re,Q,se)}},Be=function(Re,Ee,re,se){Ee.done||(Ee.done=!0,(Ee=se||Ee).value=re,Ee.state=me,Ie(Re,Ee,!0))},xe=function(Re,Ee,re,se){if(!Ee.done){Ee.done=!0,se&&(Ee=se);try{if(Re===re)throw W("Promise can't be resolved itself");var Q=ve(re);Q?I(function(){var ae={done:!1};try{Q.call(re,Ne(xe,Re,ae,Ee),Ne(Be,Re,ae,Ee))}catch(we){Be(Re,ae,we,Ee)}}):(Ee.value=re,Ee.state=le,Ie(Re,Ee,!1))}catch(ae){Be(Re,{done:!1},ae,Ee)}}};ge&&(G=function(Re){j(this,G,ee),b(Re),s.call(this);var Ee=ue(this);try{Re(Ne(xe,this,Ee),Ne(Be,this,Ee))}catch(re){Be(this,Ee,re)}},(s=function(Re){T(this,{type:ee,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:void 0})}).prototype=y(G.prototype,{then:function(Re,Ee){var re=D(this),se=ce(L(this,G));return se.ok=typeof Re!="function"||Re,se.fail=typeof Ee=="function"&&Ee,se.domain=pe?J.domain:void 0,re.parent=!0,re.reactions.push(se),re.state!=0&&Ie(this,re,!1),se.promise},catch:function(Re){return this.then(void 0,Re)}}),c=function(){var Re=new s,Ee=ue(Re);this.promise=Re,this.resolve=Ne(xe,Re,Ee),this.reject=Ne(Be,Re,Ee)},F.f=ce=function(Re){return Re===G||Re===o?new c:ie(Re)},p||typeof a!="function"||(u=a.prototype.then,h(a.prototype,"then",function(Re,Ee){var re=this;return new G(function(se,Q){u.call(re,se,Q)}).then(Re,Ee)},{unsafe:!0}),typeof ne=="function"&&g({global:!0,enumerable:!0,forced:!0},{fetch:function(Re){return A(G,ne.apply(n,arguments))}}))),g({global:!0,wrap:!0,forced:ge},{Promise:G}),l(G,ee,!1,!0),f(ee),o=i(ee),g({target:ee,stat:!0,forced:ge},{reject:function(Re){var Ee=ce(this);return Ee.reject.call(void 0,Re),Ee.promise}}),g({target:ee,stat:!0,forced:p||ge},{resolve:function(Re){return A(p&&this===o?G:this,Re)}}),g({target:ee,stat:!0,forced:ke},{all:function(Re){var Ee=this,re=ce(Ee),se=re.resolve,Q=re.reject,ae=B(function(){var we=b(Ee.resolve),Se=[],Pe=0,He=1;M(Re,function(We){var qe=Pe++,Ye=!1;Se.push(void 0),He++,we.call(Ee,We).then(function(lt){Ye||(Ye=!0,Se[qe]=lt,--He||se(Se))},Q)}),--He||se(Se)});return ae.error&&Q(ae.value),re.promise},race:function(Re){var Ee=this,re=ce(Ee),se=re.reject,Q=B(function(){var ae=b(Ee.resolve);M(Re,function(we){ae.call(Ee,we).then(re.resolve,se)})});return Q.error&&se(Q.value),re.promise}})},{"../internals/a-function":5,"../internals/an-instance":9,"../internals/check-correctness-of-iteration":27,"../internals/classof-raw":28,"../internals/engine-v8-version":48,"../internals/export":50,"../internals/get-built-in":57,"../internals/global":60,"../internals/host-report-errors":63,"../internals/inspect-source":69,"../internals/internal-state":71,"../internals/is-forced":74,"../internals/is-object":75,"../internals/is-pure":76,"../internals/iterate":78,"../internals/microtask":82,"../internals/native-promise-constructor":83,"../internals/new-promise-capability":87,"../internals/perform":106,"../internals/promise-resolve":107,"../internals/redefine":109,"../internals/redefine-all":108,"../internals/set-species":117,"../internals/set-to-string-tag":118,"../internals/species-constructor":122,"../internals/task":131,"../internals/well-known-symbol":149}],189:[function(n,x,v){var s=n("../internals/export"),y=n("../internals/get-built-in"),c=n("../internals/a-function"),o=n("../internals/an-object"),u=n("../internals/is-object"),g=n("../internals/object-create"),p=n("../internals/function-bind"),n=n("../internals/fails"),i=y("Reflect","construct"),a=n(function(){function l(){}return!(i(function(){},[],l)instanceof l)}),h=!n(function(){i(function(){})}),y=a||h;s({target:"Reflect",stat:!0,forced:y,sham:y},{construct:function(l,f){c(l),o(f);var m=arguments.length<3?l:c(arguments[2]);if(h&&!a)return i(l,f,m);if(l==m){switch(f.length){case 0:return new l;case 1:return new l(f[0]);case 2:return new l(f[0],f[1]);case 3:return new l(f[0],f[1],f[2]);case 4:return new l(f[0],f[1],f[2],f[3])}var b=[null];return b.push.apply(b,f),new(p.apply(l,b))}return b=m.prototype,m=g(u(b)?b:Object.prototype),b=Function.apply.call(l,m,f),u(b)?b:m}})},{"../internals/a-function":5,"../internals/an-object":10,"../internals/export":50,"../internals/fails":51,"../internals/function-bind":56,"../internals/get-built-in":57,"../internals/is-object":75,"../internals/object-create":91}],190:[function(t,x,v){var s=t("../internals/export"),c=t("../internals/is-object"),o=t("../internals/an-object"),u=t("../internals/has"),g=t("../internals/object-get-own-property-descriptor"),p=t("../internals/object-get-prototype-of");s({target:"Reflect",stat:!0},{get:function n(i,a){var h,y=arguments.length<3?i:arguments[2];return o(i)===y?i[a]:(h=g.f(i,a))?u(h,"value")?h.value:h.get===void 0?void 0:h.get.call(y):c(h=p(i))?n(h,a,y):void 0}})},{"../internals/an-object":10,"../internals/export":50,"../internals/has":61,"../internals/is-object":75,"../internals/object-get-own-property-descriptor":94,"../internals/object-get-prototype-of":98}],191:[function(t,x,v){var s=t("../internals/descriptors"),c=t("../internals/global"),o=t("../internals/is-forced"),u=t("../internals/inherit-if-required"),g=t("../internals/object-define-property").f,p=t("../internals/object-get-own-property-names").f,n=t("../internals/is-regexp"),i=t("../internals/regexp-flags"),a=t("../internals/regexp-sticky-helpers"),h=t("../internals/redefine"),y=t("../internals/fails"),l=t("../internals/internal-state").set,f=t("../internals/set-species"),m=t("../internals/well-known-symbol")("match"),b=c.RegExp,j=b.prototype,k=/a/g,E=/a/g,M=new b(k)!==k,P=a.UNSUPPORTED_Y;if(s&&o("RegExp",!M||P||y(function(){return E[m]=!1,b(k)!=k||b(E)==E||b(k,"i")!="/a/i"}))){for(var L=function(A,N){var F,B=this instanceof L,q=n(A),V=N===void 0;return!B&&q&&A.constructor===L&&V?A:(M?q&&!V&&(A=A.source):A instanceof L&&(V&&(N=i.call(A)),A=A.source),P&&(F=!!N&&-1I;)(function(A){A in L||g(L,A,{configurable:!0,get:function(){return b[A]},set:function(N){b[A]=N}})})(C[I++]);(j.constructor=L).prototype=j,h(c,"RegExp",L)}f("RegExp")},{"../internals/descriptors":43,"../internals/fails":51,"../internals/global":60,"../internals/inherit-if-required":68,"../internals/internal-state":71,"../internals/is-forced":74,"../internals/is-regexp":77,"../internals/object-define-property":93,"../internals/object-get-own-property-names":96,"../internals/redefine":109,"../internals/regexp-flags":112,"../internals/regexp-sticky-helpers":113,"../internals/set-species":117,"../internals/well-known-symbol":149}],192:[function(c,x,v){var s=c("../internals/export"),c=c("../internals/regexp-exec");s({target:"RegExp",proto:!0,forced:/./.exec!==c},{exec:c})},{"../internals/export":50,"../internals/regexp-exec":111}],193:[function(u,x,v){var s=u("../internals/redefine"),c=u("../internals/an-object"),n=u("../internals/fails"),o=u("../internals/regexp-flags"),u="toString",g=RegExp.prototype,p=g[u],n=n(function(){return p.call({source:"a",flags:"b"})!="/a/b"}),i=p.name!=u;(n||i)&&s(RegExp.prototype,u,function(){var a=c(this),h=String(a.source),y=a.flags;return"/"+h+"/"+String(y===void 0&&a instanceof RegExp&&!("flags"in g)?o.call(a):y)},{unsafe:!0})},{"../internals/an-object":10,"../internals/fails":51,"../internals/redefine":109,"../internals/regexp-flags":112}],194:[function(c,x,v){var s=c("../internals/collection"),c=c("../internals/collection-strong");x.exports=s("Set",function(o){return function(){return o(this,arguments.length?arguments[0]:void 0)}},c)},{"../internals/collection":32,"../internals/collection-strong":30}],195:[function(p,x,v){var s=p("../internals/export"),c=p("../internals/object-get-own-property-descriptor").f,o=p("../internals/to-length"),u=p("../internals/not-a-regexp"),g=p("../internals/require-object-coercible"),a=p("../internals/correct-is-regexp-logic"),p=p("../internals/is-pure"),n="".endsWith,i=Math.min,a=a("endsWith");s({target:"String",proto:!0,forced:!!(p||a||!(s=c(String.prototype,"endsWith"))||s.writable)&&!a},{endsWith:function(h){var y=String(g(this)),l=(u(h),1=i.length?{value:void 0,done:!0}:(i=s(i,a),n.index+=i.length,{value:i,done:!1})})},{"../internals/define-iterator":41,"../internals/internal-state":71,"../internals/string-multibyte":124}],198:[function(t,x,v){var s=t("../internals/fix-regexp-well-known-symbol-logic"),c=t("../internals/an-object"),o=t("../internals/to-length"),u=t("../internals/require-object-coercible"),g=t("../internals/advance-string-index"),p=t("../internals/regexp-exec-abstract");s("match",1,function(n,i,a){return[function(h){var y=u(this),l=h==null?void 0:h[n];return l!==void 0?l.call(h,y):new RegExp(h)[n](String(y))},function(h){var y=a(i,h,this);if(y.done)return y.value;var l=c(h),f=String(this);if(!l.global)return p(l,f);for(var m=l.unicode,b=[],j=l.lastIndex=0;(k=p(l,f))!==null;){var k=String(k[0]);(b[j]=k)===""&&(l.lastIndex=g(f,o(l.lastIndex),m)),j++}return j===0?null:b}]})},{"../internals/advance-string-index":8,"../internals/an-object":10,"../internals/fix-regexp-well-known-symbol-logic":52,"../internals/regexp-exec-abstract":110,"../internals/require-object-coercible":114,"../internals/to-length":137}],199:[function(t,x,v){var s=t("../internals/export"),c=t("../internals/string-pad").start;s({target:"String",proto:!0,forced:t("../internals/string-pad-webkit-bug")},{padStart:function(o){return c(this,o,1]*>)/g,f=/\$([$&'`]|\d\d?)/g;s("replace",2,function(m,b,j,k){var E=k.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,M=k.REPLACE_KEEPS_$0,P=E?"$":"$0";return[function(L,C){var I=p(this),A=L==null?void 0:L[m];return A!==void 0?A.call(L,I,C):b.call(String(I),L,C)},function(L,C){if(!E&&M||typeof C=="string"&&C.indexOf(P)===-1){var I=j(b,L,this,C);if(I.done)return I.value}for(var A,N=c(L),F=String(this),B=typeof C=="function",q=(B||(C=String(C)),N.global),V=(q&&(A=N.unicode,N.lastIndex=0),[]);(T=i(N,F))!==null&&(V.push(T),q);)String(T[0])===""&&(N.lastIndex=n(F,u(N.lastIndex),A));for(var H,Z="",ee=0,ue=0;ue>>0;if(C==0)return[];if(M===void 0)return[L];if(!c(M))return j.call(L,M,C);for(var I,A,N,F=[],P=(M.ignoreCase?"i":"")+(M.multiline?"m":"")+(M.unicode?"u":"")+(M.sticky?"y":""),B=0,q=new RegExp(M.source,P+"g");(I=a.call(q,L))&&!(B<(A=q.lastIndex)&&(F.push(L.slice(B,I.index)),1=C));)q.lastIndex===I.index&&q.lastIndex++;return B===L.length?!N&&q.test("")||F.push(""):F.push(L.slice(B)),F.length>C?F.slice(0,C):F}:"0".split(void 0,0).length?function(M,P){return M===void 0&&P===0?[]:j.call(this,M,P)}:j;return[function(M,P){var L=u(this),C=M==null?void 0:M[b];return C!==void 0?C.call(M,L,P):E.call(String(L),M,P)},function(I,P){var L=k(E,I,this,P,E!==j);if(L.done)return L.value;var L=o(I),C=String(this),I=g(L,RegExp),A=L.unicode,N=(L.ignoreCase?"i":"")+(L.multiline?"m":"")+(L.unicode?"u":"")+(m?"y":"g"),F=new I(m?L:"^(?:"+L.source+")",N),B=P===void 0?f:P>>>0;if(B==0)return[];if(C.length===0)return i(F,C)===null?[C]:[];for(var q=0,V=0,H=[];Vne.key){pe.splice(ce,0,ne);break}ce===z&&pe.push(ne)}ie.updateURL()},forEach:function(ne){for(var ce,ie=H(this).entries,pe=j(ne,16))return;for(Nt=0;Jt();){if(Qt=null,Nt>0)if(Jt()=="."&&Nt<4)$e++;else return;if(!G.test(Jt()))return;for(;G.test(Jt());){if(en=parseInt(Jt(),10),Qt===null)Qt=en;else{if(Qt==0)return;Qt=Qt*10+en}if(Qt>255)return;$e++}gt[Xe]=gt[Xe]*256+Qt,Nt++,(Nt==2||Nt==4)&&Xe++}if(Nt!=4)return;break}else if(Jt()==":"){if($e++,!Jt())return}else if(Jt())return;gt[Xe++]=Vt}if(ht!==null)for(_r=Xe-ht,Xe=7;Xe!=0&&_r>0;)tn=gt[Xe],gt[Xe--]=gt[ht+_r-1],gt[ht+--_r]=tn;else if(Xe!=8)return;return gt}(ze.slice(1,-1)))?void(_e.host=Ke):ee;if(ve(_e))return ze=M(ze),ce.test(ze)||(Ke=function(Ge){var gt=Ge.split("."),Xe,ht,$e,Vt,Yt,Nt,Qt;if(gt.length&>[gt.length-1]==""&>.pop(),(Xe=gt.length)>4)return Ge;for(ht=[],$e=0;$e1&&Vt.charAt(0)=="0"&&(Yt=W.test(Vt)?16:8,Vt=Vt.slice(Yt==8?1:2)),Vt==="")Nt=0;else{if(!(Yt==10?J:Yt==8?$:ne).test(Vt))return Ge;Nt=parseInt(Vt,Yt)}ht.push(Nt)}for($e=0;$e=V(256,5-Xe))return null}else if(Nt>255)return null;for(Qt=ht.pop(),$e=0;$e":1,"`":1}),de=j({},me,{"#":1,"?":1,"{":1,"}":1}),ye=j({},de,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),ge=function(_e,ze){var Ke=E(_e,0);return 32"u"&&s!==void 0&&{}.toString.call(s)==="[object process]",m=typeof Uint8ClampedArray<"u"&&typeof importScripts<"u"&&typeof MessageChannel<"u";function b(){var z=setTimeout;return function(){return z(k,1)}}var j=new Array(1e3);function k(){for(var z=0;zL,applyPalette:()=>function(B,q,V="rgb565"){if(!B||!B.buffer)throw new Error("quantize() expected RGBA Uint8Array data");if(!(B instanceof Uint8Array||B instanceof Uint8ClampedArray))throw new Error("quantize() expected RGBA Uint8Array data");if(256>24&255,G=$>>16&255,W=$>>8&255,$=255&$,J=h($,W,G,D),J=J in T?T[J]:T[J]=function(z,te,le,me,de){let ye=0,ge=1e100;for(let De=0;Dege||(ke=ve[0],(Ie+=E(ke-z))>ge||(ke=ve[1],(Ie+=E(ke-te))>ge||(ke=ve[2],(Ie+=E(ke-le))>ge||(ge=Ie,ye=De))))}return ye}($,W,G,D,q);ue[K]=J}else{const K=V==="rgb444"?y:a;for(let z=0;z>16&255,ce=ie>>8&255,ie=255&ie,pe=K(ie,ce,ne),pe=pe in T?T[pe]:T[pe]=function(te,le,me,de){let ye=0,ge=1e100;for(let De=0;Dege||(ke=ve[1],(Ie+=E(ke-le))>ge||(ke=ve[2],(Ie+=E(ke-me))>ge||(ge=Ie,ye=De)))}return ye}(ie,ce,ne,q);ue[z]=pe}}return ue},default:()=>F,nearestColor:()=>function(B,q,V=j){return B[M(B,q,V)]},nearestColorIndex:()=>M,nearestColorIndexWithDistance:()=>P,prequantize:()=>function(B,{roundRGB:q=5,roundAlpha:V=10,oneBitAlpha:H=null}={}){const Z=new Uint32Array(B.buffer);for(let G=0;G>24&255;var ee,ue=D>>16&255,T=D>>8&255,D=255&D;W=k(W,V),H&&(ee=typeof H=="number"?H:127,W=W<=ee?0:255),D=k(D,q),T=k(T,q),ue=k(ue,q),Z[G]=W<<24|ue<<16|T<<8|D<<0}},quantize:()=>function(B,q,V={}){var{format:H="rgb565",clearAlpha:Z=!0,clearAlphaColor:ee=0,clearAlphaThreshold:ue=0,oneBitAlpha:T=!1}=V;if(!B||!B.buffer)throw new Error("quantize() expected RGBA Uint8Array data");if(!(B instanceof Uint8Array||B instanceof Uint8ClampedArray))throw new Error("quantize() expected RGBA Uint8Array data");B=new Uint32Array(B.buffer);let D=V.useSqrt!==!1;const G=H==="rgba4444",W=function(Le,Ne){const Be=Ne==="rgb444"?4096:65536,xe=new Array(Be),Re=Le.length;if(Ne==="rgba4444")for(let ot=0;ot>24&255,re=Q>>16&255,se=Q>>8&255,Q=255&Q,ae=h(Q,se,re,Ee);let Ze=ae in xe?xe[ae]:xe[ae]=b();Ze.rc+=Q,Ze.gc+=se,Ze.bc+=re,Ze.ac+=Ee,Ze.cnt++}else if(Ne==="rgb444")for(let ot=0;ot>16&255,Se=Pe>>8&255,Pe=255&Pe,He=y(Pe,Se,we);let Ze=He in xe?xe[He]:xe[He]=b();Ze.rc+=Pe,Ze.gc+=Se,Ze.bc+=we,Ze.cnt++}else for(let ot=0;ot>16&255,qe=Ye>>8&255,Ye=255&Ye,lt=a(Ye,qe,We);let Ze=lt in xe?xe[lt]:xe[lt]=b();Ze.rc+=Ye,Ze.gc+=qe,Ze.bc+=We,Ze.cnt++}return xe}(B,H),$=W.length,J=$-1,ne=new Uint32Array($+1);for(var ce=0,ie=0;ie<$;++ie){const Le=W[ie];Le!=null&&(ve=1/Le.cnt,G&&(Le.ac*=ve),Le.rc*=ve,Le.gc*=ve,Le.bc*=ve,W[ce++]=Le)}f(q)/ce<.022&&(D=!1);for(var pe,K,z,ie=0;ie>1,!(W[pe=ne[z]].err<=te));K=z)ne[K]=pe;ne[K]=ie}var le,me=ce-q;for(ie=0;ie=le.mtm&&W[le.nn].mtm<=le.tm)break;for(le.mtm==J?de=ne[1]=ne[ne[0]--]:(m(W,de),le.tm=ie),te=W[de].err,K=1;(z=K+K)<=ne[0]&&(zW[ne[z+1]].err&&z++,!(te<=W[pe=ne[z]].err));K=z)ne[K]=pe;ne[K]=de}var ye=W[le.nn],ge=le.cnt,ke=ye.cnt,ve=1/(ge+ke);G&&(le.ac=ve*(ge*le.ac+ke*ye.ac)),le.rc=ve*(ge*le.rc+ke*ye.rc),le.gc=ve*(ge*le.gc+ke*ye.gc),le.bc=ve*(ge*le.bc+ke*ye.bc),le.cnt+=ye.cnt,le.mtm=++ie,W[ye.bk].fw=ye.fw,W[ye.fw].bk=ye.bk,ye.mtm=J}let Ie=[];for(ie=0;;0){let Le=l(Math.round(W[ie].rc),0,255),Ne=l(Math.round(W[ie].gc),0,255),Be=l(Math.round(W[ie].bc),0,255),xe=255;G&&(xe=l(Math.round(W[ie].ac),0,255),T&&(De=typeof T=="number"?T:127,xe=xe<=De?0:255),Z&&xe<=ue&&(Le=Ne=Be=ee,xe=0));var De=G?[Le,Ne,Be,xe]:[Le,Ne,Be];if(function(Re,Ee){for(let Q=0;Qfunction(B,q,V=5){if(B.length&&q.length){var H=B.map(D=>D.slice(0,3)),Z=V*V,ee=B[0].length;for(let D=0;Dee?G.slice(0,3):G.slice();var T=P(H,G.slice(0,3),j),ue=T[0],T=T[1];0>>0),ee!=0&&(Z=Math.max(Z,256));const ue=V;V=new Uint8Array(Z),0>=8,$-=8;if((te>pe||ce)&&(ce?(ie=ne,pe=(1<>=8,$-=8;0>3}function h(B,q,V,H){return B>>4|240&q|(240&V)<<4|(240&H)<<8}function y(B,q,V){return B>>4<<8|240&q|V>>4}function l(B,q,V){return B>8&255)}function A(B,q){for(var V=0;V>1,y=-7,l=o?m-1:0,f=o?-1:1,m=s[c+l];for(l+=f,p=m&(1<<-y)-1,m>>=-y,y+=i;0>=-y,y+=u;0>1,l=g===23?Math.pow(2,-24)-Math.pow(2,-77):0,f=u?0:b-1,m=u?1:-1,b=c<0||c===0&&1/c<0?1:0;for(c=Math.abs(c),isNaN(c)||c===1/0?(i=isNaN(c)?1:0,n=h):(n=Math.floor(Math.log(c)/Math.LN2),c*(u=Math.pow(2,-n))<1&&(n--,u*=2),2<=(c+=1<=n+y?l/u:l*Math.pow(2,1-y))*u&&(n++,u/=2),h<=n+y?(i=0,n=h):1<=n+y?(i=(c*u-1)*Math.pow(2,g),n+=y):(i=c*Math.pow(2,y-1)*Math.pow(2,g),n=0));8<=g;s[o+f]=255&i,f+=m,i/=256,g-=8);for(n=n<Math.abs(re[0])&&(se=1),se=Math.abs(re[2])>Math.abs(re[se])?2:se}function I(re,se){re.f+=se.f,re.b.f+=se.b.f}function A(re,se,Q){return re=re.a,se=se.a,Q=Q.a,se.b.a===re?Q.b.a===re?o(se.a,Q.a)?g(Q.b.a,se.a,Q.a)<=0:0<=g(se.b.a,Q.a,se.a):g(Q.b.a,re,Q.a)<=0:Q.b.a===re?0<=g(se.b.a,re,se.a):(se=u(se.b.a,re,se.a),(re=u(Q.b.a,re,Q.a))<=se)}function N(re){re.a.i=null;var se=re.e;se.a.c=se.c,se.c.a=se.a,re.e=null}function F(re,se){l(re.a),re.c=!1,(re.a=se).i=re}function B(re){for(var se=re.a.a;(re=Ee(re)).a.a===se;);return re.c&&(F(re,se=m(Re(re).a.b,re.a.e)),re=Ee(re)),re}function q(re,se,Q){var ae=new xe;return ae.a=Q,ae.e=ce(re.f,se.e,ae),Q.i=ae}function V(re,se){switch(re.s){case 100130:return(1&se)!=0;case 100131:return se!==0;case 100132:return 0>1]],He[Pe[qe]])?Ne:Be)(Q,qe),He[Se]=null,We[Se]=Q.b,Q.b=Se}else for(Q.c[-(Se+1)]=null;0Math.max(Pe.a,We.a))){if(o(Se,Pe)){if(0Q.f&&(Q.f*=2,Q.c=Ie(Q.c,Q.f+1)),Q.b===0?we=ae:(we=Q.b,Q.b=Q.c[Q.b]),Q.e[we]=se,Q.c[we]=ae,Q.d[ae]=we,Q.h&&Be(Q,ae),we):(Q=re.a++,re.c[Q]=se,-(Q+1))}function ke(re){if(re.a===0)return Le(re.b);var se=re.c[re.d[re.a-1]];if(re.b.a!==0&&o(De(re.b),se))return Le(re.b);for(;--re.a,0re.a||o(ae[Pe],ae[We])){we[Q[Se]=Pe]=Se;break}we[Q[Se]=We]=Se,Se=He}}function Be(re,se){for(var Q=re.d,ae=re.e,we=re.c,Se=se,Pe=Q[Se];;){var He=Se>>1,We=Q[He];if(He==0||o(ae[We],ae[Pe])){we[Q[Se]=Pe]=Se;break}we[Q[Se]=We]=Se,Se=He}}function xe(){this.e=this.a=null,this.f=0,this.c=this.b=this.h=this.d=!1}function Re(re){return re.e.c.b}function Ee(re){return re.e.a.b}(s=pe.prototype).x=function(){K(this,0)},s.B=function(re,se){switch(re){case 100142:return;case 100140:switch(se){case 100130:case 100131:case 100132:case 100133:case 100134:return void(this.s=se)}break;case 100141:return void(this.m=!!se);default:return void z(this,100900)}z(this,100901)},s.y=function(re){switch(re){case 100142:return 0;case 100140:return this.s;case 100141:return this.m;default:z(this,100900)}return!1},s.A=function(re,se,Q){this.j[0]=re,this.j[1]=se,this.j[2]=Q},s.z=function(re,se){var Q=se||null;switch(re){case 100100:case 100106:this.h=Q;break;case 100104:case 100110:this.l=Q;break;case 100101:case 100107:this.k=Q;break;case 100102:case 100108:this.i=Q;break;case 100103:case 100109:this.p=Q;break;case 100105:case 100111:this.o=Q;break;case 100112:this.r=Q;break;default:z(this,100900)}},s.C=function(re,se){var Q=!1,ae=[0,0,0];K(this,2);for(var we=0;we<3;++we){var Se=re[we];Se<-1e150&&(Se=-1e150,Q=!0),1e150ae[qe]&&(ae[qe]=Ye,we[qe]=Q)}if(ae[1]-He[1]>ae[Q=0]-He[0]&&(Q=1),He[Q=ae[2]-He[2]>ae[Q]-He[Q]?2:Q]>=ae[Q])Pe[0]=0,Pe[1]=0,Pe[2]=1;else{for(He=We[Q],we=we[Q],We=[ae=0,0,0],He=[He.g[0]-we.g[0],He.g[1]-we.g[1],He.g[2]-we.g[2]],qe=[0,0,0],Q=Se.e;Q!==Se;Q=Q.e)qe[0]=Q.g[0]-we.g[0],qe[1]=Q.g[1]-we.g[1],qe[2]=Q.g[2]-we.g[2],We[0]=He[1]*qe[2]-He[2]*qe[1],We[1]=He[2]*qe[0]-He[0]*qe[2],We[2]=He[0]*qe[1]-He[1]*qe[0],ae<(Ye=We[0]*We[0]+We[1]*We[1]+We[2]*We[2])&&(ae=Ye,Pe[0]=We[0],Pe[1]=We[1],Pe[2]=We[2]);ae<=0&&(Pe[0]=Pe[1]=Pe[2]=0,Pe[C(He)]=1)}Se=!0}for(We=C(Pe),Q=this.b.c,ae=(We+1)%3,we=(We+2)%3,We=0>=1;)++y;if(f=1<>8&255,o[n++]=255&g,o[n++]=g>>8&255,o[n++]=(a!==null?128:0)|y,o[n++]=l,o[n++]=0,a!==null)for(var m=0,b=a.length;m>16&255,o[n++]=j>>8&255,o[n++]=255&j}if(i!==null){if(i<0||65535>8&255,o[n++]=0}var k=!1;this.addFrame=function(E,M,P,L,C,I){if(k===!0&&(--n,k=!1),I=I===void 0?{}:I,E<0||M<0||65535>=1;)++F;var B=1<>8&255,o[n++]=Z,o[n++]=0),o[n++]=44,o[n++]=255&E,o[n++]=E>>8&255,o[n++]=255&M,o[n++]=M>>8&255,o[n++]=255&P,o[n++]=P>>8&255,o[n++]=255&L,o[n++]=L>>8&255,o[n++]=A===!0?128|F-1:0,A===!0)for(var ee=0,ue=N.length;ee>16&255,o[n++]=T>>8&255,o[n++]=255&T}return n=function(D,G,W,$){D[G++]=W;var J=G++,ne=1<>=8,z-=8,G===J+256&&(D[J]=255,J=G++)}function me(Le){te|=Le<>=8,z-=8,G===J+256&&(D[J]=255,J=G++);pe===4096?(me(ne),pe=1+ie,K=W+1,ye={}):(1<>=y,f-=y,M==i)h=1+a,l=(1<<(y=n+1))-1,E=null;else{if(M==a)break;for(var P=M>8,++L;var I=C;if(p>=8;E!==null&&h<4096&&(k[h++]=E<<8|I,l+1<=h&&y<12&&(++y,l=l<<1|1)),E=M}}b!==p&&console.log("Warning, gif stream shorter than expected.")}try{v.GifWriter=s,v.GifReader=function(o){var u=0;if(o[u++]!==71||o[u++]!==73||o[u++]!==70||o[u++]!==56||(o[u++]+1&253)!=56||o[u++]!==97)throw new Error("Invalid GIF 87a/89a header.");var g=o[u++]|o[u++]<<8,p=o[u++]|o[u++]<<8,n=o[u++],i=1<<1+(7&n),a=(o[u++],o[u++],null),h=null,y=(n>>7&&(a=u,u+=3*(h=i)),!0),l=[],f=0,m=null,b=0,j=null;for(this.width=g,this.height=p;y&&u>2&7,u++;break;case 254:for(;;){if(!(0<=(E=o[u++])))throw Error("Invalid block size");if(E===0)break;u+=E}break;default:throw new Error("Unknown graphic control label: 0x"+o[u-1].toString(16))}break;case 44:var E,M=o[u++]|o[u++]<<8,P=o[u++]|o[u++]<<8,L=o[u++]|o[u++]<<8,C=o[u++]|o[u++]<<8,q=o[u++],I=q>>6&1,A=1<<1+(7&q),N=a,F=h,B=!1,q=(q>>7&&(B=!0,N=u,u+=3*(F=A)),u);for(u++;;){if(!(0<=(E=o[u++])))throw Error("Invalid block size");if(E===0)break;u+=E}l.push({x:M,y:P,width:L,height:C,has_local_palette:B,palette_offset:N,palette_size:F,data_offset:q,data_length:u-q,transparent_index:m,interlaced:!!I,delay:f,disposal:b});break;case 59:y=!1;break;default:throw new Error("Unknown gif block: 0x"+o[u-1].toString(16))}this.numFrames=function(){return l.length},this.loopCount=function(){return j},this.frameInfo=function(V){if(V<0||V>=l.length)throw new Error("Frame index out of range.");return l[V]},this.decodeAndBlitFrameBGRA=function(V,H){for(var V=this.frameInfo(V),Z=V.width*V.height,ee=new Uint8Array(Z),ue=(c(o,V.data_offset,ee,Z),V.palette_offset),T=V.transparent_index,D=(T===null&&(T=256),V.width),G=g-D,W=D,$=4*(V.y*g+V.x),J=4*((V.y+V.height)*g+V.x),ne=$,ce=4*G,ie=(V.interlaced===!0&&(ce+=4*g*7),8),pe=0,K=ee.length;pe>=1)),le===T?ne+=4:(z=o[ue+3*le],te=o[ue+3*le+1],le=o[ue+3*le+2],H[ne++]=le,H[ne++]=te,H[ne++]=z,H[ne++]=255),--W}},this.decodeAndBlitFrameRGBA=function(V,H){for(var V=this.frameInfo(V),Z=V.width*V.height,ee=new Uint8Array(Z),ue=(c(o,V.data_offset,ee,Z),V.palette_offset),T=V.transparent_index,D=(T===null&&(T=256),V.width),G=g-D,W=D,$=4*(V.y*g+V.x),J=4*((V.y+V.height)*g+V.x),ne=$,ce=4*G,ie=(V.interlaced===!0&&(ce+=4*g*7),8),pe=0,K=ee.length;pe>=1)),le===T?ne+=4:(z=o[ue+3*le],te=o[ue+3*le+1],le=o[ue+3*le+2],H[ne++]=z,H[ne++]=te,H[ne++]=le,H[ne++]=255),--W}}}}catch{}},{}],254:[function(t,x,v){(function(s){var c,o;c=this,o=function(u){function g(U){if(this==null)throw TypeError();var S,O=String(this),R=O.length,U=U?Number(U):0;if(!((U=U!=U?0:U)<0||R<=U))return 55296<=(S=O.charCodeAt(U))&&S<=56319&&U+1>>16-S;return _.tag>>>=S,_.bitcount-=S,R+O}function A(_,S){for(;_.bitcount<24;)_.tag|=_.source[_.sourceIndex++]<<_.bitcount,_.bitcount+=8;for(var O=0,R=0,U=0,X=_.tag;R=2*R+(1&X),X>>>=1,O+=S.table[++U],0<=(R-=S.table[U]););return _.tag=X,_.bitcount-=U,S.trans[O+R]}function N(_,S,O){for(;;){var R=A(_,S);if(R===256)return n;if(R<256)_.dest[_.destLen++]=R;else for(var U,X=I(_,f[R-=257],m[R]),R=A(_,O),Y=U=_.destLen-I(_,b[R],j[R]);Y>>=1,R=U,I(X,2,0)){case 0:O=function(Oe){for(var Je,ut;8this.x2&&(this.x2=_)),typeof S=="number"&&((isNaN(this.y1)||isNaN(this.y2))&&(this.y1=S,this.y2=S),Sthis.y2&&(this.y2=S))},Z.prototype.addX=function(_){this.addPoint(_,null)},Z.prototype.addY=function(_){this.addPoint(null,_)},Z.prototype.addBezier=function(_,S,O,R,U,X,Y,oe){var he=[_,S],fe=[O,R],je=[U,X],Me=[Y,oe];this.addPoint(_,S),this.addPoint(Y,oe);for(var Te=0;Te<=1;Te++){var be,Ue=6*he[Te]-12*fe[Te]+6*je[Te],Ae=-3*he[Te]+9*fe[Te]-9*je[Te]+3*Me[Te],Fe=3*fe[Te]-3*he[Te];Ae==0?Ue==0||0<(be=-Fe/Ue)&&be<1&&(Te===0&&this.addX(H(he[Te],fe[Te],je[Te],Me[Te],be)),Te===1&&this.addY(H(he[Te],fe[Te],je[Te],Me[Te],be))):(be=Math.pow(Ue,2)-4*Fe*Ae)<0||(0<(Fe=(-Ue+Math.sqrt(be))/(2*Ae))&&Fe<1&&(Te===0&&this.addX(H(he[Te],fe[Te],je[Te],Me[Te],Fe)),Te===1&&this.addY(H(he[Te],fe[Te],je[Te],Me[Te],Fe))),0<(Fe=(-Ue-Math.sqrt(be))/(2*Ae))&&Fe<1&&(Te===0&&this.addX(H(he[Te],fe[Te],je[Te],Me[Te],Fe)),Te===1&&this.addY(H(he[Te],fe[Te],je[Te],Me[Te],Fe))))}},Z.prototype.addQuad=function(_,S,O,R,U,X){O=_+2/3*(O-_),R=S+2/3*(R-S),this.addBezier(_,S,O,R,O+1/3*(U-_),R+1/3*(X-S),U,X)},ee.prototype.moveTo=function(_,S){this.commands.push({type:"M",x:_,y:S})},ee.prototype.lineTo=function(_,S){this.commands.push({type:"L",x:_,y:S})},ee.prototype.curveTo=ee.prototype.bezierCurveTo=function(_,S,O,R,U,X){this.commands.push({type:"C",x1:_,y1:S,x2:O,y2:R,x:U,y:X})},ee.prototype.quadTo=ee.prototype.quadraticCurveTo=function(_,S,O,R){this.commands.push({type:"Q",x1:_,y1:S,x:O,y:R})},ee.prototype.close=ee.prototype.closePath=function(){this.commands.push({type:"Z"})},ee.prototype.extend=function(_){var S;if(_.commands)_=_.commands;else if(_ instanceof Z)return S=_,this.moveTo(S.x1,S.y1),this.lineTo(S.x2,S.y1),this.lineTo(S.x2,S.y2),this.lineTo(S.x1,S.y2),void this.close();Array.prototype.push.apply(this.commands,_)},ee.prototype.getBoundingBox=function(){for(var _=new Z,S=0,O=0,R=0,U=0,X=0;X>8&255,255&_]},$.USHORT=J(2),W.SHORT=function(_){return[(_=32768<=_?-(65536-_):_)>>8&255,255&_]},$.SHORT=J(2),W.UINT24=function(_){return[_>>16&255,_>>8&255,255&_]},$.UINT24=J(3),W.ULONG=function(_){return[_>>24&255,_>>16&255,_>>8&255,255&_]},$.ULONG=J(4),W.LONG=function(_){return[(_=2147483648<=_?-(4294967296-_):_)>>24&255,_>>16&255,_>>8&255,255&_]},$.LONG=J(4),W.FIXED=W.ULONG,$.FIXED=$.ULONG,W.FWORD=W.SHORT,$.FWORD=$.SHORT,W.UFWORD=W.USHORT,$.UFWORD=$.USHORT,W.LONGDATETIME=function(_){return[0,0,0,0,_>>24&255,_>>16&255,_>>8&255,255&_]},$.LONGDATETIME=J(8),W.TAG=function(_){return D.argument(_.length===4,"Tag should be exactly 4 ASCII characters."),[_.charCodeAt(0),_.charCodeAt(1),_.charCodeAt(2),_.charCodeAt(3)]},$.TAG=J(4),W.Card8=W.BYTE,$.Card8=$.BYTE,W.Card16=W.USHORT,$.Card16=$.USHORT,W.OffSize=W.BYTE,$.OffSize=$.BYTE,W.SID=W.USHORT,$.SID=$.USHORT,W.NUMBER=function(_){return-107<=_&&_<=107?[_+139]:108<=_&&_<=1131?[247+((_-=108)>>8),255&_]:-1131<=_&&_<=-108?[251+((_=-_-108)>>8),255&_]:-32768<=_&&_<=32767?W.NUMBER16(_):W.NUMBER32(_)},$.NUMBER=function(_){return W.NUMBER(_).length},W.NUMBER16=function(_){return[28,_>>8&255,255&_]},$.NUMBER16=J(3),W.NUMBER32=function(_){return[29,_>>24&255,_>>16&255,_>>8&255,255&_]},$.NUMBER32=J(5),W.REAL=function(_){for(var S=_.toString(),O=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(S),R=(O&&(O=parseFloat("1e"+((O[2]?+O[2]:0)+O[1].length)),S=(Math.round(_*O)/O).toString()),""),U=0,X=S.length;U>8&255,S[S.length]=255&R}return S},$.UTF16=function(_){return 2*_.length};var ne,ce={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"},ie=(G.MACSTRING=function(_,S,O,R){var U=ce[R];if(U!==void 0){for(var X="",Y=0;Y>8&255,Te+256&255)}return fe})(_,R,S);return S},W.INDEX=function(_){for(var S=1,O=[S],R=[],U=0;U<_.length;U+=1){var X=W.OBJECT(_[U]);Array.prototype.push.apply(R,X),S+=X.length,O.push(S)}if(R.length===0)return[0,0];for(var Y=[],oe=1+Math.floor(Math.log(S)/Math.log(2))/8|0,he=[void 0,W.BYTE,W.USHORT,W.UINT24,W.ULONG][oe],fe=0;fe>8,S[je+1]=255&Me,S=S.concat(R[fe])}return S},$.TABLE=function(_){for(var S=0,O=_.fields.length,R=0;R>1,oe.skip("uShort",3),Fe.glyphIndexMap={};for(var ut,et=new Ee.Parser(Ce,Oe+Je+14),tt=new Ee.Parser(Ce,Oe+Je+16+2*ut),ct=new Ee.Parser(Ce,Oe+Je+16+4*ut),Mt=new Ee.Parser(Ce,Oe+Je+16+6*ut),Ut=Oe+Je+16+8*ut,qt=0;qt>4,Y=15&Y;if(X==15||(R+=U[X],Y==15))break;R+=U[Y]}return parseFloat(R)}if(32<=S&&S<=246)return S-139;if(247<=S&&S<=250)return 256*(S-247)+_.parseByte()+108;if(251<=S&&S<=254)return 256*-(S-251)-_.parseByte()-108;throw new Error("Invalid b0 "+S)}function lr(_,S,O){var R=new Ee.Parser(_,S=S!==void 0?S:0),U=[],X=[];for(O=O!==void 0?O:_.length;R.relativeOffset>1,be.length=0,Ae=!0}return function tt(ct){for(var Mt,Ut,qt,ur,cr,$r,Tt,Pt,wt,dr,Dt,sr,At=0;AtMath.abs(sr-Oe)?Ce=Dt+be.shift():Oe=sr+be.shift(),Te.curveTo(R,U,X,Y,Tt,Pt),Te.curveTo(wt,dr,Dt,sr,Ce,Oe);break;default:console.log("Glyph "+S.index+": unknown operator 1200"+er),be.length=0}break;case 14:0>3;break;case 21:2>16),At+=2;break;case 29:cr=be.pop()+_.gsubrsBias,($r=_.gsubrs[cr])&&tt($r);break;case 30:for(;0=O.begin&&_=we.length&&(X=R.parseChar(),O.names.push(R.parseString(X)));break;case 2.5:O.numberOfGlyphs=R.parseUShort(),O.offset=new Array(O.numberOfGlyphs);for(var oe=0;oeMe.value.tag?1:-1}),S.fields=S.fields.concat(R),S.fields=S.fields.concat(U),S}function Rl(_,S,O){for(var R=0;R 123 are reserved for internal usage");be|=1<>>1,X=_[U].tag;if(X===S)return U;X>>1,X=_[U];if(X===S)return U;X>>1,Y=(U=_[X]).start;if(Y===S)return U;Y(U=_[O-1]).end?0:U}function gs(_,S){this.font=_,this.tableName=S}function vs(_){gs.call(this,_,"gpos")}function rn(_){gs.call(this,_,"gsub")}function Dl(_,S,O){for(var R=_.subtables,U=0;US.points.length-1||R.matchedPoints[1]>U.points.length-1)throw Error("Matched points out of range in "+S.name);var Y=S.points[R.matchedPoints[0]],oe=U.points[R.matchedPoints[1]],R={xScale:R.xScale,scale01:R.scale01,scale10:R.scale10,yScale:R.yScale,dx:0,dy:0},oe=Ti([oe],R)[0];R.dx=Y.x-oe.x,R.dy=Y.y-oe.y,X=Ti(U.points,R)}S.points=S.points.concat(X)}}return Ul(S.points)}(vs.prototype=gs.prototype={searchTag:Ei,binSearch:Ll,getTable:function(_){var S=this.font.tables[this.tableName];return S=!S&&_?this.font.tables[this.tableName]=this.createDefaultTable():S},getScriptNames:function(){var _=this.getTable();return _?_.scripts.map(function(S){return S.tag}):[]},getDefaultScriptName:function(){var _=this.getTable();if(_){for(var S=!1,O=0;O<_.scripts.length;O++){var R=_.scripts[O].tag;if(R==="DFLT")return R;R==="latn"&&(S=!0)}return S?"latn":void 0}},getScriptTable:function(_,S){var O,R=this.getTable(S);if(R)return O=R.scripts,0<=(R=Ei(R.scripts,_=_||"DFLT"))?O[R].script:S?(O.splice(-1-R,0,S={tag:_,script:{defaultLangSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]},langSysRecords:[]}}),S.script):void 0},getLangSysTable:function(U,S,O){var R,U=this.getScriptTable(U,O);if(U)return S&&S!=="dflt"&&S!=="DFLT"?0<=(R=Ei(U.langSysRecords,S))?U.langSysRecords[R].langSys:O?(U.langSysRecords.splice(-1-R,0,O={tag:S,langSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]}}),O.langSys):void 0:U.defaultLangSys},getFeatureTable:function(_,S,O,R){if(_=this.getLangSysTable(_,S,R),_){for(var U,X=_.featureIndexes,Y=this.font.tables[this.tableName].features,oe=0;oe=Y[S-1].tag,"Features must be added in alphabetical order."),Y.push(U={tag:O,feature:{params:0,lookupListIndexes:[]}}),X.push(S),U.feature}},getLookupTables:function(X,S,O,R,U){var X=this.getFeatureTable(X,S,O,U),Y=[];if(X){for(var oe,he=X.lookupListIndexes,fe=this.font.tables[this.tableName].lookups,je=0;je",X),S.stack.push(Math.round(64*X))}function Mi(_,S){var O=S.stack,R=O.pop(),U=S.fv,X=S.pv,Y=S.ppem,oe=S.deltaBase+16*(_-1),he=S.deltaShift,fe=S.z0;u.DEBUG&&console.log(S.step,"DELTAP["+_+"]",R,O);for(var je=0;je>4)===Y&&(0<=(Te=(15&Te)-8)&&Te++,u.DEBUG&&console.log(S.step,"DELTAPFIX",Me,"by",Te*he),Me=fe[Me],U.setRelative(Me,Me,Te*he,X))}}function _s(_,S){var O=S.stack,R=O.pop();u.DEBUG&&console.log(S.step,"ROUND[]"),O.push(64*S.round(R/64))}function Ci(_,S){var O=S.stack,R=O.pop(),U=S.ppem,X=S.deltaBase+16*(_-1),Y=S.deltaShift;u.DEBUG&&console.log(S.step,"DELTAC["+_+"]",R,O);for(var oe=0;oe>4)===U&&(0<=(fe=(15&fe)-8)&&fe++,fe=fe*Y,u.DEBUG&&console.log(S.step,"DELTACFIX",he,"by",fe),S.cvt[he]+=fe)}}function su(_,S){var O,U=S.stack,R=U.pop(),U=U.pop(),X=S.z2[R],Y=S.z1[U];u.DEBUG&&console.log(S.step,"SDPVTL["+_+"]",R,U),R=_?(O=X.y-Y.y,Y.x-X.x):(O=Y.x-X.x,Y.y-X.y),S.dpv=Ro(O,R)}function _n(_,S){var O=S.stack,R=S.prog,U=S.ip;u.DEBUG&&console.log(S.step,"PUSHB["+_+"]");for(var X=0;X<_;X++)O.push(R[++U]);S.ip=U}function wn(_,S){var O=S.ip,R=S.prog,U=S.stack;u.DEBUG&&console.log(S.ip,"PUSHW["+_+"]");for(var X=0;X<_;X++){var Y=R[++O]<<8|R[++O];32768&Y&&(Y=-(1+(65535^Y))),U.push(Y)}S.ip=O}function Qe(_,S,O,R,U,X){var Y,oe,fe=X.stack,he=_&&fe.pop(),fe=fe.pop(),je=X.rp0,je=X.z0[je],Me=X.z1[fe],Te=X.minDis,be=X.fv,Ue=X.dpv,Ae=Y=Ue.distance(Me,je,!0,!0),Fe=0<=Ae?1:-1;Ae=Math.abs(Ae),_&&(oe=X.cvt[he],R&&Math.abs(Ae-oe)":"_")+(R?"R":"_")+(U===0?"Gr":U===1?"Bl":U===2?"Wh":"")+"]",_?he+"("+X.cvt[he]+","+oe+")":"",fe,"(d =",Y,"->",Fe*Ae,")"),X.rp1=X.rp0,X.rp2=fe,S&&(X.rp0=fe)}Gl.prototype.exec=function(_,S){if(typeof S!="number")throw new Error("Point size is not a number!");if(!(2",R),oe.interpolate(Me,X,Y,he),oe.touch(Me)}_.loop=1},tu.bind(void 0,0),tu.bind(void 0,1),function(_){for(var S=_.stack,O=_.rp0,R=_.z0[O],U=_.loop,X=_.fv,Y=_.pv,oe=_.z1;U--;){var he=S.pop(),fe=oe[he];u.DEBUG&&console.log(_.step,(1<_.loop?"loop "+(_.loop-U)+": ":"")+"ALIGNRP[]",he),X.setRelative(fe,R,0,Y),X.touch(fe)}_.loop=1},function(_){u.DEBUG&&console.log(_.step,"RTDG[]"),_.round=xh},ru.bind(void 0,0),ru.bind(void 0,1),function(_){var S=_.prog,O=_.ip,R=_.stack,U=S[++O];u.DEBUG&&console.log(_.step,"NPUSHB[]",U);for(var X=0;X"u"?Ih:Dh)(_,function(O,R){if(O)return S(O);var U;try{U=Oi(R)}catch(X){return S(X,null)}return S(null,U)})},u.loadSync=function(_){return Oi(Fl(t("fs").readFileSync(_)))},Object.defineProperty(u,"__esModule",{value:!0})},o(typeof v=="object"&&x!==void 0?v:c.opentype={})}).call(this,t("buffer").Buffer)},{buffer:4,fs:2}],255:[function(t,x,v){(function(s){function c(g,p){for(var n=0,i=g.length-1;0<=i;i--){var a=g[i];a==="."?g.splice(i,1):a===".."?(g.splice(i,1),n++):n&&(g.splice(i,1),n--)}if(p)for(;n--;)g.unshift("..");return g}function o(g,p){if(g.filter)return g.filter(p);for(var n=[],i=0;i'.concat(f,"").concat(h,""),this.dummyDOM||(this.dummyDOM=document.getElementById(l).parentNode),this.descriptions?this.descriptions.fallbackElements||(this.descriptions.fallbackElements={}):this.descriptions={fallbackElements:{}},this.descriptions.fallbackElements[a]?this.descriptions.fallbackElements[a].innerHTML!==f&&(this.descriptions.fallbackElements[a].innerHTML=f):this._describeElementHTML("fallback",a,f),y===this.LABEL&&(this.descriptions.labelElements||(this.descriptions.labelElements={}),this.descriptions.labelElements[a]?this.descriptions.labelElements[a].innerHTML!==f&&(this.descriptions.labelElements[a].innerHTML=f):this._describeElementHTML("label",a,f)))},s.default.prototype._describeHTML=function(a,h){var y,l=this.canvas.id;a==="fallback"?(this.dummyDOM.querySelector("#".concat(l+c))?this.dummyDOM.querySelector("#"+l+u).insertAdjacentHTML("beforebegin",'

        ')):(y='

        '),this.dummyDOM.querySelector("#".concat(l,"accessibleOutput"))?this.dummyDOM.querySelector("#".concat(l,"accessibleOutput")).insertAdjacentHTML("beforebegin",y):this.dummyDOM.querySelector("#".concat(l)).innerHTML=y),this.descriptions.fallback=this.dummyDOM.querySelector("#".concat(l).concat(o)),this.descriptions.fallback.innerHTML=h):a==="label"&&(this.dummyDOM.querySelector("#".concat(l+g))?this.dummyDOM.querySelector("#".concat(l+n))&&this.dummyDOM.querySelector("#".concat(l+n)).insertAdjacentHTML("beforebegin",'

        ')):(y='

        '),this.dummyDOM.querySelector("#".concat(l,"accessibleOutputLabel"))?this.dummyDOM.querySelector("#".concat(l,"accessibleOutputLabel")).insertAdjacentHTML("beforebegin",y):this.dummyDOM.querySelector("#"+l).insertAdjacentHTML("afterend",y)),this.descriptions.label=this.dummyDOM.querySelector("#"+l+p),this.descriptions.label.innerHTML=h)},s.default.prototype._describeElementHTML=function(a,h,y){var l,f=this.canvas.id;a==="fallback"?(this.dummyDOM.querySelector("#".concat(f+c))?this.dummyDOM.querySelector("#"+f+u)||this.dummyDOM.querySelector("#"+f+o).insertAdjacentHTML("afterend",'
        Canvas elements and their descriptions
        ')):(l='
        Canvas elements and their descriptions
        '),this.dummyDOM.querySelector("#".concat(f,"accessibleOutput"))?this.dummyDOM.querySelector("#".concat(f,"accessibleOutput")).insertAdjacentHTML("beforebegin",l):this.dummyDOM.querySelector("#"+f).innerHTML=l),(l=document.createElement("tr")).id=f+"_fte_"+h,this.dummyDOM.querySelector("#"+f+u).appendChild(l),this.descriptions.fallbackElements[h]=this.dummyDOM.querySelector("#".concat(f).concat("_fte_").concat(h)),this.descriptions.fallbackElements[h].innerHTML=y):a==="label"&&(this.dummyDOM.querySelector("#".concat(f+g))?this.dummyDOM.querySelector("#".concat(f+n))||this.dummyDOM.querySelector("#"+f+p).insertAdjacentHTML("afterend",'
        ')):(l='
        '),this.dummyDOM.querySelector("#".concat(f,"accessibleOutputLabel"))?this.dummyDOM.querySelector("#".concat(f,"accessibleOutputLabel")).insertAdjacentHTML("beforebegin",l):this.dummyDOM.querySelector("#"+f).insertAdjacentHTML("afterend",l)),(a=document.createElement("tr")).id=f+"_lte_"+h,this.dummyDOM.querySelector("#"+f+n).appendChild(a),this.descriptions.labelElements[h]=this.dummyDOM.querySelector("#".concat(f).concat("_lte_").concat(h)),this.descriptions.labelElements[h].innerHTML=y)},t=s.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.string.ends-with":195,"core-js/modules/es.string.replace":201}],261:[function(t,x,v){t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.from"),t("core-js/modules/es.array.map"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.from"),t("core-js/modules/es.array.map"),t("core-js/modules/es.string.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t},t.default.prototype._updateGridOutput=function(s){var c,o,u,g;this.dummyDOM.querySelector("#".concat(s,"_summary"))&&(c=this._accessibleOutputs[s],u=function(p,n,i,a){return n="".concat(n," canvas, ").concat(i," by ").concat(a," pixels, contains ").concat(p[0]),n=(p[0]===1?"".concat(n," shape: "):"".concat(n," shapes: ")).concat(p[1]),n}((o=function(p,n){var i,a="",h="",y=0;for(i in n){var l,f=0;for(l in n[i]){var m='
      • ').concat(n[i][l].color," ").concat(i,",");i==="line"?m+=" location = ".concat(n[i][l].pos,", length = ").concat(n[i][l].length," pixels"):(m+=" location = ".concat(n[i][l].pos),i!=="point"&&(m+=", area = ".concat(n[i][l].area," %")),m+="
      • "),a+=m,f++,y++}h=1').concat(n[i][f].color," ").concat(i,"
        "):'').concat(n[i][f].color," ").concat(i," midpoint"),l[n[i][f].loc.locY][n[i][f].loc.locX]?l[n[i][f].loc.locY][n[i][f].loc.locX]=l[n[i][f].loc.locY][n[i][f].loc.locX]+" "+m:l[n[i][f].loc.locY][n[i][f].loc.locX]=m,h++}for(a in l){var b,j="";for(b in l[a])j+="",l[a][b]!==void 0&&(j+=l[a][b]),j+="";y=y+j+""}return y}(s,this.ingredients.shapes),u!==c.summary.innerHTML&&(c.summary.innerHTML=u),g!==c.map.innerHTML&&(c.map.innerHTML=g),o.details!==c.shapeDetails.innerHTML&&(c.shapeDetails.innerHTML=o.details),this._accessibleOutputs[s]=c)},t=t.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.from":161,"core-js/modules/es.array.map":167,"core-js/modules/es.string.iterator":197}],262:[function(t,x,v){t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.fill"),t("core-js/modules/es.array.from"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.map"),t("core-js/modules/es.number.to-fixed"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.fill"),t("core-js/modules/es.array.map"),t("core-js/modules/es.number.to-fixed"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var s=(t=t("../core/main"))&&t.__esModule?t:{default:t};function c(u){return function(g){if(Array.isArray(g)){for(var p=0,n=new Array(g.length);p')):this.dummyDOM.querySelector("#".concat(a)).innerHTML='
        '))):g==="Label"&&(p=a+u+(h=g),this.dummyDOM.querySelector("#".concat(n=a+"accessibleOutput"+g))||(this.dummyDOM.querySelector("#".concat(a,"_Label"))?this.dummyDOM.querySelector("#".concat(a,"_Label")):this.dummyDOM.querySelector("#".concat(a))).insertAdjacentHTML("afterend",'
        '))),this._accessibleOutputs[p]={},u==="textOutput"?(h="#".concat(a,"gridOutput").concat(h),i='
        Text Output

          '),this.dummyDOM.querySelector(h)?this.dummyDOM.querySelector(h).insertAdjacentHTML("beforebegin",i):this.dummyDOM.querySelector("#".concat(n)).innerHTML=i,this._accessibleOutputs[p].list=this.dummyDOM.querySelector("#".concat(p,"_list"))):u==="gridOutput"&&(h="#".concat(a,"textOutput").concat(h),i='
          Grid Output

            '),this.dummyDOM.querySelector(h)?this.dummyDOM.querySelector(h).insertAdjacentHTML("afterend",i):this.dummyDOM.querySelector("#".concat(n)).innerHTML=i,this._accessibleOutputs[p].map=this.dummyDOM.querySelector("#".concat(p,"_map"))),this._accessibleOutputs[p].shapeDetails=this.dummyDOM.querySelector("#".concat(p,"_shapeDetails")),this._accessibleOutputs[p].summary=this.dummyDOM.querySelector("#".concat(p,"_summary"))},s.default.prototype._updateAccsOutput=function(){var u=this.canvas.id;JSON.stringify(this.ingredients.shapes)===this.ingredients.pShapes&&this.ingredients.colors.background===this.ingredients.pBackground||(this.ingredients.pShapes=JSON.stringify(this.ingredients.shapes),this._accessibleOutputs.text&&this._updateTextOutput(u+"textOutput"),this._accessibleOutputs.grid&&this._updateGridOutput(u+"gridOutput"),this._accessibleOutputs.textLabel&&this._updateTextOutput(u+"textOutputLabel"),this._accessibleOutputs.gridLabel&&this._updateGridOutput(u+"gridOutputLabel"))},s.default.prototype._accsBackground=function(u){this.ingredients.pShapes=JSON.stringify(this.ingredients.shapes),this.ingredients.pBackground=this.ingredients.colors.background,this.ingredients.shapes={},this.ingredients.colors.backgroundRGBA!==u&&(this.ingredients.colors.backgroundRGBA=u,this.ingredients.colors.background=this._rgbColorName(u))},s.default.prototype._accsCanvasColors=function(u,g){u==="fill"?this.ingredients.colors.fillRGBA!==g&&(this.ingredients.colors.fillRGBA=g,this.ingredients.colors.fill=this._rgbColorName(g)):u==="stroke"&&this.ingredients.colors.strokeRGBA!==g&&(this.ingredients.colors.strokeRGBA=g,this.ingredients.colors.stroke=this._rgbColorName(g))},s.default.prototype._accsOutput=function(u,g){u==="ellipse"&&g[2]===g[3]?u="circle":u==="rectangle"&&g[2]===g[3]&&(u="square");var p,n,i={},a=!0,h=function(l,f){var m;return l=l==="rectangle"||l==="ellipse"||l==="arc"||l==="circle"||l==="square"?(m=Math.round(f[0]+f[2]/2),Math.round(f[1]+f[3]/2)):l==="triangle"?(m=(f[0]+f[2]+f[4])/3,(f[1]+f[3]+f[5])/3):l==="quadrilateral"?(m=(f[0]+f[2]+f[4]+f[6])/4,(f[1]+f[3]+f[5]+f[7])/4):l==="line"?(m=(f[0]+f[2])/2,(f[1]+f[3])/2):(m=f[0],f[1]),[m,l]}(u,g);if(u==="line"?(i.color=this.ingredients.colors.stroke,i.length=Math.round(this.dist(g[0],g[1],g[2],g[3])),p=this._getPos(g[0],[1]),n=this._getPos(g[2],[3]),i.loc=o(h,this.width,this.height),i.pos=p===n?"at ".concat(p):"from ".concat(p," to ").concat(n)):(u==="point"?i.color=this.ingredients.colors.stroke:(i.color=this.ingredients.colors.fill,i.area=this._getArea(u,g)),i.pos=this._getPos.apply(this,c(h)),i.loc=o(h,this.width,this.height)),this.ingredients.shapes[u]){if(this.ingredients.shapes[u]!==[i]){for(var y in this.ingredients.shapes[u])JSON.stringify(this.ingredients.shapes[u][y])===JSON.stringify(i)&&(a=!1);a===!0&&this.ingredients.shapes[u].push(i)}}else this.ingredients.shapes[u]=[i]},s.default.prototype._getPos=function(n,p){var n=new DOMPointReadOnly(n,p),p=this._renderer.isP3D?new DOMMatrix(this._renderer.uMVMatrix.mat4):this.drawingContext.getTransform(),n=n.matrixTransform(p),p=n.x,n=n.y,i=this.width*this._pixelDensity,a=this.height*this._pixelDensity;return p<.4*i?n<.4*a?"top left":.6*aMath.PI?i+=n:i-=n)):u==="ellipse"||u==="circle"?i=3.14*g[2]/2*g[3]/2:u==="line"||u==="point"?i=0:u==="quadrilateral"?i=Math.abs((g[6]+g[0])*(g[7]-g[1])+(g[0]+g[2])*(g[1]-g[3])+(g[2]+g[4])*(g[3]-g[5])+(g[4]+g[6])*(g[5]-g[7]))/2:u==="rectangle"||u==="square"?i=g[2]*g[3]:u==="triangle"&&(i=Math.abs(g[0]*(g[3]-g[5])+g[2]*(g[5]-g[1])+g[4]*(g[1]-g[3]))/2),this.width*this._pixelDensity),h=this.height*this._pixelDensity,y=[new DOMPoint(0,0),new DOMPoint(a,0),new DOMPoint(a,h),new DOMPoint(0,h)],l=(this._renderer.isP3D?new DOMMatrix(this._renderer.uMVMatrix.mat4):this.drawingContext.getTransform()).inverse(),f=y.map(function(b){return b.matrixTransform(l)}),m=Math.abs((f[3].x+f[0].x)*(f[3].y-f[0].y)+(f[0].x+f[1].x)*(f[0].y-f[1].y)+(f[1].x+f[2].x)*(f[1].y-f[2].y)+(f[2].x+f[3].x)*(f[2].y-f[3].y))/2;return Math.round(100*i/m)},t=s.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.fill":155,"core-js/modules/es.array.from":161,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.map":167,"core-js/modules/es.number.to-fixed":180,"core-js/modules/es.object.to-string":187,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/web.dom-collections.iterator":243}],263:[function(t,x,v){t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.concat"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t},t.default.prototype._updateTextOutput=function(s){var c,o,u,g;this.dummyDOM.querySelector("#".concat(s,"_summary"))&&(c=this._accessibleOutputs[s],u=function(p,n,i,a){return i="Your output is a, ".concat(i," by ").concat(a," pixels, ").concat(n," canvas containing the following"),i=p===1?"".concat(i," shape:"):"".concat(i," ").concat(p," shapes:"),i}((o=function(p,n){var i,a="",h=0;for(i in n)for(var y in n[i]){var l='
          • ').concat(n[i][y].color," ").concat(i,"");i==="line"?l+=", ".concat(n[i][y].pos,", ").concat(n[i][y].length," pixels long.
          • "):(l+=", at ".concat(n[i][y].pos),i!=="point"&&(l+=", covering ".concat(n[i][y].area,"% of the canvas")),l+="."),a+=l,h++}return{numShapes:h,listShapes:a}}(s,this.ingredients.shapes)).numShapes,this.ingredients.colors.background,this.width,this.height),g=function(p,n){var i,a="",h=0;for(i in n)for(var y in n[i]){var l='').concat(n[i][y].color," ").concat(i,"");i==="line"?l+="location = ".concat(n[i][y].pos,"length = ").concat(n[i][y].length," pixels"):(l+="location = ".concat(n[i][y].pos,""),i!=="point"&&(l+=" area = ".concat(n[i][y].area,"%")),l+=""),a+=l,h++}return a}(s,this.ingredients.shapes),u!==c.summary.innerHTML&&(c.summary.innerHTML=u),o.listShapes!==c.list.innerHTML&&(c.list.innerHTML=o.listShapes),g!==c.shapeDetails.innerHTML&&(c.shapeDetails.innerHTML=g),this._accessibleOutputs[s]=c)},t=t.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.concat":152}],264:[function(t,x,v){var s=(s=t("./core/main"))&&s.__esModule?s:{default:s};t("./core/constants"),t("./core/environment"),t("./core/friendly_errors/stacktrace"),t("./core/friendly_errors/validate_params"),t("./core/friendly_errors/file_errors"),t("./core/friendly_errors/fes_core"),t("./core/friendly_errors/sketch_reader"),t("./core/helpers"),t("./core/legacy"),t("./core/preload"),t("./core/p5.Element"),t("./core/p5.Graphics"),t("./core/p5.Renderer"),t("./core/p5.Renderer2D"),t("./core/rendering"),t("./core/shim"),t("./core/structure"),t("./core/transform"),t("./core/shape/2d_primitives"),t("./core/shape/attributes"),t("./core/shape/curves"),t("./core/shape/vertex"),t("./accessibility/outputs"),t("./accessibility/textOutput"),t("./accessibility/gridOutput"),t("./accessibility/color_namer"),t("./color/color_conversion"),t("./color/creating_reading"),t("./color/p5.Color"),t("./color/setting"),t("./data/p5.TypedDict"),t("./data/local_storage.js"),t("./dom/dom"),t("./accessibility/describe"),t("./events/acceleration"),t("./events/keyboard"),t("./events/mouse"),t("./events/touch"),t("./image/filters"),t("./image/image"),t("./image/loading_displaying"),t("./image/p5.Image"),t("./image/pixels"),t("./io/files"),t("./io/p5.Table"),t("./io/p5.TableRow"),t("./io/p5.XML"),t("./math/calculation"),t("./math/math"),t("./math/noise"),t("./math/p5.Vector"),t("./math/random"),t("./math/trigonometry"),t("./typography/attributes"),t("./typography/loading_displaying"),t("./typography/p5.Font"),t("./utilities/array_functions"),t("./utilities/conversion"),t("./utilities/string_functions"),t("./utilities/time_date"),t("./webgl/3d_primitives"),t("./webgl/interaction"),t("./webgl/light"),t("./webgl/loading"),t("./webgl/material"),t("./webgl/p5.Camera"),t("./webgl/p5.DataArray"),t("./webgl/p5.Geometry"),t("./webgl/p5.Matrix"),t("./webgl/p5.RendererGL.Immediate"),t("./webgl/p5.RendererGL"),t("./webgl/p5.RendererGL.Retained"),t("./webgl/p5.Framebuffer"),t("./webgl/p5.Shader"),t("./webgl/p5.RenderBuffer"),t("./webgl/p5.Texture"),t("./webgl/text"),t("./core/init"),x.exports=s.default},{"./accessibility/color_namer":259,"./accessibility/describe":260,"./accessibility/gridOutput":261,"./accessibility/outputs":262,"./accessibility/textOutput":263,"./color/color_conversion":265,"./color/creating_reading":266,"./color/p5.Color":267,"./color/setting":268,"./core/constants":269,"./core/environment":270,"./core/friendly_errors/fes_core":271,"./core/friendly_errors/file_errors":272,"./core/friendly_errors/sketch_reader":273,"./core/friendly_errors/stacktrace":274,"./core/friendly_errors/validate_params":275,"./core/helpers":276,"./core/init":277,"./core/legacy":279,"./core/main":280,"./core/p5.Element":281,"./core/p5.Graphics":282,"./core/p5.Renderer":283,"./core/p5.Renderer2D":284,"./core/preload":285,"./core/rendering":286,"./core/shape/2d_primitives":287,"./core/shape/attributes":288,"./core/shape/curves":289,"./core/shape/vertex":290,"./core/shim":291,"./core/structure":292,"./core/transform":293,"./data/local_storage.js":294,"./data/p5.TypedDict":295,"./dom/dom":296,"./events/acceleration":297,"./events/keyboard":298,"./events/mouse":299,"./events/touch":300,"./image/filters":301,"./image/image":302,"./image/loading_displaying":303,"./image/p5.Image":304,"./image/pixels":305,"./io/files":306,"./io/p5.Table":307,"./io/p5.TableRow":308,"./io/p5.XML":309,"./math/calculation":310,"./math/math":311,"./math/noise":312,"./math/p5.Vector":313,"./math/random":314,"./math/trigonometry":315,"./typography/attributes":316,"./typography/loading_displaying":317,"./typography/p5.Font":318,"./utilities/array_functions":319,"./utilities/conversion":320,"./utilities/string_functions":321,"./utilities/time_date":322,"./webgl/3d_primitives":323,"./webgl/interaction":325,"./webgl/light":326,"./webgl/loading":327,"./webgl/material":328,"./webgl/p5.Camera":329,"./webgl/p5.DataArray":330,"./webgl/p5.Framebuffer":331,"./webgl/p5.Geometry":332,"./webgl/p5.Matrix":333,"./webgl/p5.RenderBuffer":334,"./webgl/p5.RendererGL":337,"./webgl/p5.RendererGL.Immediate":335,"./webgl/p5.RendererGL.Retained":336,"./webgl/p5.Shader":338,"./webgl/p5.Texture":339,"./webgl/text":340}],265:[function(t,x,v){Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t},t.default.ColorConversion={_hsbaToHSLA:function(s){var c=s[0],o=s[1],u=s[2],g=(2-o)*u/2;return g!=0&&(g==1?o=0:g<.5?o/=2-o:o=o*u/(2-2*g)),[c,o,g,s[3]]},_hsbaToRGBA:function(s){var c,o,u,g,p,n=6*s[0],i=s[1],a=s[2];return i===0?[a,a,a,s[3]]:(o=a*(1-i),u=a*(1-i*(n-(c=Math.floor(n)))),i=a*(1-i*(1+c-n)),n=c===1?(g=u,p=a,o):c===2?(g=o,p=a,i):c===3?(g=o,p=u,a):c===4?(g=i,p=o,a):c===5?(g=a,p=o,u):(g=a,p=i,o),[g,p,n,s[3]])},_hslaToHSBA:function(s){var c=s[0],o=s[1],u=s[2],g=u<.5?(1+o)*u:u+o-u*o;return[c,o=2*(g-u)/g,g,s[3]]},_hslaToRGBA:function(s){var c,o=6*s[0],u=s[1],g=s[2];return u===0?[g,g,g,s[3]]:[(c=function(p,n,i){return p<0?p+=6:6<=p&&(p-=6),p<1?n+(i-n)*p:p<3?i:p<4?n+(i-n)*(4-p):n})(2+o,u=2*g-(g=g<.5?(1+u)*g:g+u-g*u),g),c(o,u,g),c(o-2,u,g),s[3]]},_rgbaToHSBA:function(s){var c,o,u=s[0],g=s[1],p=s[2],n=Math.max(u,g,p),i=n-Math.min(u,g,p);return i==0?o=c=0:(o=i/n,u===n?c=(g-p)/i:g===n?c=2+(p-u)/i:p===n&&(c=4+(u-g)/i),c<0?c+=6:6<=c&&(c-=6)),[c/6,o,n,s[3]]},_rgbaToHSLA:function(s){var c,o,u=s[0],g=s[1],p=s[2],n=Math.max(u,g,p),a=Math.min(u,g,p),i=n+a,a=n-a;return a==0?o=c=0:(o=i<1?a/i:a/(2-i),u===n?c=(g-p)/a:g===n?c=2+(p-u)/a:p===n&&(c=4+(u-g)/a),c<0?c+=6:6<=c&&(c-=6)),[c/6,o,i/2,s[3]]}},t=t.default.ColorConversion,v.default=t},{"../core/main":280}],266:[function(t,x,v){function s(n){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(i){return typeof i}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":typeof i})(n)}function c(n){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(i){return s(i)}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":s(i)})(n)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.map"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.map"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=(p=t("../core/main"))&&p.__esModule?p:{default:p},u=function(n){if(n&&n.__esModule)return n;if(n===null||c(n)!=="object"&&typeof n!="function")return{default:n};var i=g();if(i&&i.has(n))return i.get(n);var a,h={},y=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(a in n){var l;Object.prototype.hasOwnProperty.call(n,a)&&((l=y?Object.getOwnPropertyDescriptor(n,a):null)&&(l.get||l.set)?Object.defineProperty(h,a,l):h[a]=n[a])}return h.default=n,i&&i.set(n,h),h}(t("../core/constants"));function g(){var n;return typeof WeakMap!="function"?null:(n=new WeakMap,g=function(){return n},n)}t("./p5.Color"),t("../core/friendly_errors/validate_params"),t("../core/friendly_errors/file_errors"),t("../core/friendly_errors/fes_core"),o.default.prototype.alpha=function(n){return o.default._validateParameters("alpha",arguments),this.color(n)._getAlpha()},o.default.prototype.blue=function(n){return o.default._validateParameters("blue",arguments),this.color(n)._getBlue()},o.default.prototype.brightness=function(n){return o.default._validateParameters("brightness",arguments),this.color(n)._getBrightness()},o.default.prototype.color=function(){for(var n,i=arguments.length,a=new Array(i),h=0;hl[0]?l[0]+=1:y[0]+=1),1<=(h=this.lerp(y[0],l[0],a))&&--h),n=this.lerp(y[1],l[1],a),i=this.lerp(y[2],l[2],a),y=this.lerp(y[3],l[3],a),h*=m[f][0],n*=m[f][1],i*=m[f][2],y*=m[f][3],this.color(h,n,i,y)},o.default.prototype.lightness=function(n){return o.default._validateParameters("lightness",arguments),this.color(n)._getLightness()},o.default.prototype.red=function(n){return o.default._validateParameters("red",arguments),this.color(n)._getRed()},o.default.prototype.saturation=function(n){return o.default._validateParameters("saturation",arguments),this.color(n)._getSaturation()};var p=o.default;v.default=p},{"../core/constants":269,"../core/friendly_errors/fes_core":271,"../core/friendly_errors/file_errors":272,"../core/friendly_errors/validate_params":275,"../core/main":280,"./p5.Color":267,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.map":167,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.to-string":187,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}],267:[function(h,x,v){function s(b){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(j){return typeof j}:function(j){return j&&typeof Symbol=="function"&&j.constructor===Symbol&&j!==Symbol.prototype?"symbol":typeof j})(b)}function c(b){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(j){return s(j)}:function(j){return j&&typeof Symbol=="function"&&j.constructor===Symbol&&j!==Symbol.prototype?"symbol":s(j)})(b)}h("core-js/modules/es.symbol"),h("core-js/modules/es.symbol.description"),h("core-js/modules/es.symbol.iterator"),h("core-js/modules/es.array.includes"),h("core-js/modules/es.array.iterator"),h("core-js/modules/es.array.join"),h("core-js/modules/es.array.map"),h("core-js/modules/es.array.slice"),h("core-js/modules/es.object.get-own-property-descriptor"),h("core-js/modules/es.object.to-string"),h("core-js/modules/es.regexp.constructor"),h("core-js/modules/es.regexp.exec"),h("core-js/modules/es.regexp.to-string"),h("core-js/modules/es.string.includes"),h("core-js/modules/es.string.iterator"),h("core-js/modules/es.string.trim"),h("core-js/modules/es.weak-map"),h("core-js/modules/web.dom-collections.iterator"),h("core-js/modules/es.array.includes"),h("core-js/modules/es.array.join"),h("core-js/modules/es.array.map"),h("core-js/modules/es.array.slice"),h("core-js/modules/es.object.to-string"),h("core-js/modules/es.regexp.constructor"),h("core-js/modules/es.regexp.exec"),h("core-js/modules/es.regexp.to-string"),h("core-js/modules/es.string.includes"),h("core-js/modules/es.string.trim"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=n(h("../core/main")),u=function(b){if(b&&b.__esModule)return b;if(b===null||c(b)!=="object"&&typeof b!="function")return{default:b};var j=p();if(j&&j.has(b))return j.get(b);var k,E={},M=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(k in b){var P;Object.prototype.hasOwnProperty.call(b,k)&&((P=M?Object.getOwnPropertyDescriptor(b,k):null)&&(P.get||P.set)?Object.defineProperty(E,k,P):E[k]=b[k])}return E.default=b,j&&j.set(b,E),E}(h("../core/constants")),g=n(h("./color_conversion"));function p(){var b;return typeof WeakMap!="function"?null:(b=new WeakMap,p=function(){return b},b)}function n(b){return b&&b.__esModule?b:{default:b}}function i(b,j){for(var k=0;k"].indexOf(i[0])?void 0:i[0],lineNumber:i[1],columnNumber:i[2],source:p}},this)},parseFFOrSafari:function(g){return g.stack.split(` `).filter(function(p){return!p.match(u)},this).map(function(p){var n,i;return(p=-1 eval")?p.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1"):p).indexOf("@")===-1&&p.indexOf(":")===-1?{functionName:p}:{functionName:(i=p.match(n=/((.*".+"[^@]*)?[^@]*)(?:@)/))&&i[1]?i[1]:void 0,fileName:(i=this.extractLocation(p.replace(n,"")))[0],lineNumber:i[1],columnNumber:i[2],source:p}},this)},parseOpera:function(g){return!g.stacktrace||-1g.stacktrace.split(` `).length?this.parseOpera9(g):g.stack?this.parseOpera11(g):this.parseOpera10(g)},parseOpera9:function(g){for(var p=/Line (\d+).*script (?:in )?(\S+)/i,n=g.message.split(` -`),i=[],a=2,h=n.length;a/,"$2").replace(/\([^)]*\)/g,"")||void 0,args:(n=a.match(/\(([^)]*)\)/)?a.replace(/^[^(]+\(([^)]*)\)$/,"$1"):n)===void 0||n==="[arguments not available]"?void 0:n.split(","),fileName:i[0],lineNumber:i[1],columnNumber:i[2],source:p}},this)}}}t.default._getErrorStackParser=function(){return new s},t=t.default,v.default=t},{"../main":280,"core-js/modules/es.array.filter":156,"core-js/modules/es.array.index-of":163,"core-js/modules/es.array.join":165,"core-js/modules/es.array.map":167,"core-js/modules/es.array.slice":168,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.string.match":198,"core-js/modules/es.string.replace":201,"core-js/modules/es.string.split":203}],275:[function(t,x,v){function s(g){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(p){return typeof p}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":typeof p})(g)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.for-each"),t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.last-index-of"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.function.name"),t("core-js/modules/es.map"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.get-prototype-of"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.reflect.construct"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.set"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.for-each"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.for-each"),t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.last-index-of"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.function.name"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.set"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/web.dom-collections.for-each"),t("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var c=(c=t("../main"))&&c.__esModule?c:{default:c};(function(g){if(!(g&&g.__esModule)&&!(g===null||u(g)!=="object"&&typeof g!="function")){var p=o();if(p&&p.has(g))return p.get(g);var n,i={},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(n in g){var h;Object.prototype.hasOwnProperty.call(g,n)&&((h=a?Object.getOwnPropertyDescriptor(g,n):null)&&(h.get||h.set)?Object.defineProperty(i,n,h):i[n]=g[n])}i.default=g,p&&p.set(g,i)}})(t("../constants")),t("../internationalization");function o(){var g;return typeof WeakMap!="function"?null:(g=new WeakMap,o=function(){return g},g)}function u(g){return(u=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(p){return s(p)}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":s(p)})(g)}c.default._validateParameters=c.default._clearValidateParamsCache=function(){},t=c.default,v.default=t},{"../../../docs/parameterData.json":void 0,"../constants":269,"../internationalization":278,"../main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.for-each":160,"core-js/modules/es.array.includes":162,"core-js/modules/es.array.index-of":163,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.join":165,"core-js/modules/es.array.last-index-of":166,"core-js/modules/es.array.map":167,"core-js/modules/es.array.slice":168,"core-js/modules/es.function.name":173,"core-js/modules/es.map":174,"core-js/modules/es.number.constructor":178,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.get-prototype-of":185,"core-js/modules/es.object.keys":186,"core-js/modules/es.object.to-string":187,"core-js/modules/es.reflect.construct":189,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.set":194,"core-js/modules/es.string.includes":196,"core-js/modules/es.string.iterator":197,"core-js/modules/es.string.split":203,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.for-each":242,"core-js/modules/web.dom-collections.iterator":243}],276:[function(t,x,v){function s(g){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(p){return typeof p}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":typeof p})(g)}function c(g){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(p){return s(p)}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":s(p)})(g)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=function(g){if(g&&g.__esModule)return g;if(g===null||c(g)!=="object"&&typeof g!="function")return{default:g};var p=u();if(p&&p.has(g))return p.get(g);var n,i={},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(n in g){var h;Object.prototype.hasOwnProperty.call(g,n)&&((h=a?Object.getOwnPropertyDescriptor(g,n):null)&&(h.get||h.set)?Object.defineProperty(i,n,h):i[n]=g[n])}return i.default=g,p&&p.set(g,i),i}(t("./constants"));function u(){var g;return typeof WeakMap!="function"?null:(g=new WeakMap,u=function(){return g},g)}v.default={modeAdjust:function(g,p,n,i,a){return a===o.CORNER?{x:g,y:p,w:n,h:i}:a===o.CORNERS?{x:g,y:p,w:n-g,h:i-p}:a===o.RADIUS?{x:g-n,y:p-i,w:2*n,h:2*i}:a===o.CENTER?{x:g-.5*n,y:p-.5*i,w:n,h:i}:void 0}}},{"./constants":269,"core-js/modules/es.array.iterator":164,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.to-string":187,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}],277:[function(t,x,v){t("core-js/modules/es.array.iterator"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.string.iterator"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.string.iterator"),t("core-js/modules/web.dom-collections.iterator");var s=(c=t("../core/main"))&&c.__esModule?c:{default:c};t("./internationalization");var c=Promise.resolve();Promise.all([new Promise(function(o,u){document.readyState==="complete"?o():window.addEventListener("load",o,!1)}),c]).then(function(){window._setupDone!==void 0?console.warn("p5.js seems to have been imported multiple times. Please remove the duplicate import"):window.mocha||(window.setup&&typeof window.setup=="function"||window.draw&&typeof window.draw=="function")&&!s.default.instance&&new s.default})},{"../core/main":280,"./internationalization":278,"core-js/modules/es.array.iterator":164,"core-js/modules/es.object.to-string":187,"core-js/modules/es.promise":188,"core-js/modules/es.string.iterator":197,"core-js/modules/web.dom-collections.iterator":243}],278:[function(t,x,v){t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.setTranslatorLanguage=v.currentTranslatorLanguage=v.availableTranslatorLanguages=v.initialize=v.translator=void 0;var s,c,o=g(t("i18next")),u=g(t("i18next-browser-languagedetector"));function g(i){return i&&i.__esModule?i:{default:i}}function p(i,a){for(var h=0;h=I.width||E>=I.height?[0,0,0,0]:this._getPixel(k,E);return L=new c.default.Image(M*C,P*C),L.pixelDensity(C),L.canvas.getContext("2d").drawImage(I,k,E,M*C,P*C,0,0,M*C,P*C),L}},{key:"textLeading",value:function(k){return typeof k=="number"?(this._setProperty("_leadingSet",!0),this._setProperty("_textLeading",k),this._pInst):this._textLeading}},{key:"textStyle",value:function(k){return k?(k!==o.NORMAL&&k!==o.ITALIC&&k!==o.BOLD&&k!==o.BOLDITALIC||this._setProperty("_textStyle",k),this._applyTextProperties()):this._textStyle}},{key:"textAscent",value:function(){return this._textAscent===null&&this._updateTextMetrics(),this._textAscent}},{key:"textDescent",value:function(){return this._textDescent===null&&this._updateTextMetrics(),this._textDescent}},{key:"textAlign",value:function(k,E){return k!==void 0?(this._setProperty("_textAlign",k),E!==void 0&&this._setProperty("_textBaseline",E),this._applyTextProperties()):{horizontal:this._textAlign,vertical:this._textBaseline}}},{key:"textWrap",value:function(k){return this._setProperty("_textWrap",k),this._textWrap}},{key:"text",value:function(k,E,M,P,L){var C,I,A,N,F=this._pInst,B=this._textWrap,q=Number.MAX_VALUE,V=M;if((this._doFill||this._doStroke)&&k!==void 0){if(C=(k=(k=typeof k!="string"?k.toString():k).replace(/(\t)/g," ")).split(` -`),P!==void 0){switch(this._rectMode===o.CENTER&&(E-=P/2),this._textAlign){case o.CENTER:E+=P/2;break;case o.RIGHT:E+=P}if(L!==void 0){this._rectMode===o.CENTER&&(M-=L/2,V-=L/2);var k=M,H=F.textAscent();switch(this._textBaseline){case o.BOTTOM:N=M+L,M=Math.max(N,M),V+=H;break;case o.CENTER:N=M+L/2,M=Math.max(N,M),V+=H/2}q=M+L-H,this._textBaseline===o.CENTER&&(q=k+L-H/2)}else this._textBaseline!==o.BOTTOM&&this._textBaseline!==o.CENTER||(V=M-(k=F.textSize()*this._textLeading)/2,q=M+k/2);if(B===o.WORD){for(var Z=[],ee=0;eeu.HALF_PI&&a<=3*u.HALF_PI?Math.atan(m/l*Math.tan(a))+u.PI:Math.atan(m/l*Math.tan(a))+u.TWO_PI,h=h<=u.HALF_PI?Math.atan(m/l*Math.tan(h)):h>u.HALF_PI&&h<=3*u.HALF_PI?Math.atan(m/l*Math.tan(h))+u.PI:Math.atan(m/l*Math.tan(h))+u.TWO_PI),hi||Math.abs(this.accelerationY-this.pAccelerationY)>i||Math.abs(this.accelerationZ-this.pAccelerationZ)>i)&&j.deviceMoved(),typeof j.deviceTurned=="function"&&(l=this._toDegrees(this.rotationX)+180,f=this._toDegrees(this.pRotationX)+180,m=c+180,0>>16,p[1+i]=(65280&n[a])>>>8,p[2+i]=255&n[a],p[3+i]=(4278190080&n[a])>>>24},_toImageData:function(p){return p instanceof ImageData?p:p.getContext("2d").getImageData(0,0,p.width,p.height)},_createImageData:function(p,n){return g._tmpCanvas=document.createElement("canvas"),g._tmpCtx=g._tmpCanvas.getContext("2d"),this._tmpCtx.createImageData(p,n)},apply:function(p,m,i){var a=p.getContext("2d"),h=a.getImageData(0,0,p.width,p.height),m=m(h,i);m instanceof ImageData?a.putImageData(m,0,0,0,0,p.width,p.height):a.putImageData(h,0,0,0,0,p.width,p.height)},threshold:function(p){for(var n=1>8)/a,i[h+1]=255*(l*n>>8)/a,i[h+2]=255*(f*n>>8)/a}},dilate:function(p){for(var n,i,a,h,m,l,f,y,b,j=g._toPixels(p),k=0,E=j.length?j.length/4:0,M=new Int32Array(E);k>16&255)+151*(h>>8&255)+28*(255&h))<(f=77*(b>>16&255)+151*(b>>8&255)+28*(255&b))&&(a=b,h=f),h<(f=77*((b=g._getARGB(j,y))>>16&255)+151*(b>>8&255)+28*(255&b))&&(a=b,h=f),h<(y=77*(m>>16&255)+151*(m>>8&255)+28*(255&m))&&(a=m,h=y),h<(b=77*(l>>16&255)+151*(l>>8&255)+28*(255&l))&&(a=l,h=b),M[k++]=a;g._setPixels(j,M)},erode:function(p){for(var n,i,a,h,m,l,f,y,b,j=g._toPixels(p),k=0,E=j.length?j.length/4:0,M=new Int32Array(E);k>16&255)+151*(b>>8&255)+28*(255&b))<(h=77*(h>>16&255)+151*(h>>8&255)+28*(255&h))&&(a=b,h=f),(f=77*((b=g._getARGB(j,y))>>16&255)+151*(b>>8&255)+28*(255&b))>16&255)+151*(m>>8&255)+28*(255&m))>16&255)+151*(l>>8&255)+28*(255&l))>>24],a+=B[(16711680&pe)>>16],h+=B[(65280&pe)>>8],m+=B[255&pe],i+=o[F],f++}ee[y=G+A]=l/i,ue[y]=a/i,T[y]=h/i,D[y]=m/i}G+=M}for(j=(b=-s)*M,N=G=0;N"+V.length.toString()+" out of "+N.toString()),z.next=48,new Promise(function(te){return setTimeout(te,0)});z.next=50;break;case 48:z.next=39;break;case 50:L||H.html("Frames processed, generating color palette..."),this.loop(),this.pixelDensity(q),ue=(0,n.GIFEncoder)(),T=function(te){for(var le=new Uint8Array(te.length*te[0].length),me=0;me"+J.toString()+" out of "+N.toString()),z.next=68,new Promise(function(te){return setTimeout(te,0)});case 68:J++,z.next=60;break;case 71:ue.finish(),pe=ue.bytesView(),pe=new Blob([pe],{type:"image/gif"}),V=[],this._recording=!1,this.loop(),L||(H.html("Done. Downloading your gif!🌸"),0=a&&(a=Math.floor(h.timeDisplayed/a),h.timeDisplayed=0,h.lastChangeTime=m,h.displayIndex+=a,h.loopCount=Math.floor(h.displayIndex/h.numFrames),h.loopLimit!==null&&h.loopCount>=h.loopLimit?h.playing=!1:(m=h.displayIndex%h.numFrames,this.drawingContext.putImageData(h.frames[m].image,0,0),h.displayIndex=m,this.setModified(!0))))}},{key:"_setProperty",value:function(i,a){this[i]=a,this.setModified(!0)}},{key:"loadPixels",value:function(){s.default.Renderer2D.prototype.loadPixels.call(this),this.setModified(!0)}},{key:"updatePixels",value:function(i,a,h,m){s.default.Renderer2D.prototype.updatePixels.call(this,i,a,h,m),this.setModified(!0)}},{key:"get",value:function(i,a,h,m){return s.default._validateParameters("p5.Image.get",arguments),s.default.Renderer2D.prototype.get.apply(this,arguments)}},{key:"_getPixel",value:function(){for(var i=arguments.length,a=new Array(i),h=0;h/g,">").replace(/"/g,""").replace(/'/g,"'")}function i(a,h){h&&h!==!0&&h!=="true"||(h="");var m="";return(a=a||"untitled")&&a.includes(".")&&(m=a.split(".").pop()),h&&m!==h&&(m=h,a="".concat(a,".").concat(m)),[a,m]}t("../core/friendly_errors/validate_params"),t("../core/friendly_errors/file_errors"),t("../core/friendly_errors/fes_core"),c.default.prototype.loadJSON=function(){for(var a=arguments.length,h=new Array(a),m=0;m/,"$2").replace(/\([^)]*\)/g,"")||void 0,args:(n=a.match(/\(([^)]*)\)/)?a.replace(/^[^(]+\(([^)]*)\)$/,"$1"):n)===void 0||n==="[arguments not available]"?void 0:n.split(","),fileName:i[0],lineNumber:i[1],columnNumber:i[2],source:p}},this)}}}t.default._getErrorStackParser=function(){return new s},t=t.default,v.default=t},{"../main":280,"core-js/modules/es.array.filter":156,"core-js/modules/es.array.index-of":163,"core-js/modules/es.array.join":165,"core-js/modules/es.array.map":167,"core-js/modules/es.array.slice":168,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.string.match":198,"core-js/modules/es.string.replace":201,"core-js/modules/es.string.split":203}],275:[function(t,x,v){function s(g){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(p){return typeof p}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":typeof p})(g)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.for-each"),t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.last-index-of"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.function.name"),t("core-js/modules/es.map"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.get-prototype-of"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.reflect.construct"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.set"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.for-each"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.for-each"),t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.last-index-of"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.function.name"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.set"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/web.dom-collections.for-each"),t("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var c=(c=t("../main"))&&c.__esModule?c:{default:c};(function(g){if(!(g&&g.__esModule)&&!(g===null||u(g)!=="object"&&typeof g!="function")){var p=o();if(p&&p.has(g))return p.get(g);var n,i={},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(n in g){var h;Object.prototype.hasOwnProperty.call(g,n)&&((h=a?Object.getOwnPropertyDescriptor(g,n):null)&&(h.get||h.set)?Object.defineProperty(i,n,h):i[n]=g[n])}i.default=g,p&&p.set(g,i)}})(t("../constants")),t("../internationalization");function o(){var g;return typeof WeakMap!="function"?null:(g=new WeakMap,o=function(){return g},g)}function u(g){return(u=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(p){return s(p)}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":s(p)})(g)}c.default._validateParameters=c.default._clearValidateParamsCache=function(){},t=c.default,v.default=t},{"../../../docs/parameterData.json":void 0,"../constants":269,"../internationalization":278,"../main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.for-each":160,"core-js/modules/es.array.includes":162,"core-js/modules/es.array.index-of":163,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.join":165,"core-js/modules/es.array.last-index-of":166,"core-js/modules/es.array.map":167,"core-js/modules/es.array.slice":168,"core-js/modules/es.function.name":173,"core-js/modules/es.map":174,"core-js/modules/es.number.constructor":178,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.get-prototype-of":185,"core-js/modules/es.object.keys":186,"core-js/modules/es.object.to-string":187,"core-js/modules/es.reflect.construct":189,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.set":194,"core-js/modules/es.string.includes":196,"core-js/modules/es.string.iterator":197,"core-js/modules/es.string.split":203,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.for-each":242,"core-js/modules/web.dom-collections.iterator":243}],276:[function(t,x,v){function s(g){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(p){return typeof p}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":typeof p})(g)}function c(g){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(p){return s(p)}:function(p){return p&&typeof Symbol=="function"&&p.constructor===Symbol&&p!==Symbol.prototype?"symbol":s(p)})(g)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=function(g){if(g&&g.__esModule)return g;if(g===null||c(g)!=="object"&&typeof g!="function")return{default:g};var p=u();if(p&&p.has(g))return p.get(g);var n,i={},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(n in g){var h;Object.prototype.hasOwnProperty.call(g,n)&&((h=a?Object.getOwnPropertyDescriptor(g,n):null)&&(h.get||h.set)?Object.defineProperty(i,n,h):i[n]=g[n])}return i.default=g,p&&p.set(g,i),i}(t("./constants"));function u(){var g;return typeof WeakMap!="function"?null:(g=new WeakMap,u=function(){return g},g)}v.default={modeAdjust:function(g,p,n,i,a){return a===o.CORNER?{x:g,y:p,w:n,h:i}:a===o.CORNERS?{x:g,y:p,w:n-g,h:i-p}:a===o.RADIUS?{x:g-n,y:p-i,w:2*n,h:2*i}:a===o.CENTER?{x:g-.5*n,y:p-.5*i,w:n,h:i}:void 0}}},{"./constants":269,"core-js/modules/es.array.iterator":164,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.to-string":187,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}],277:[function(t,x,v){t("core-js/modules/es.array.iterator"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.string.iterator"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.string.iterator"),t("core-js/modules/web.dom-collections.iterator");var s=(c=t("../core/main"))&&c.__esModule?c:{default:c};t("./internationalization");var c=Promise.resolve();Promise.all([new Promise(function(o,u){document.readyState==="complete"?o():window.addEventListener("load",o,!1)}),c]).then(function(){window._setupDone!==void 0?console.warn("p5.js seems to have been imported multiple times. Please remove the duplicate import"):window.mocha||(window.setup&&typeof window.setup=="function"||window.draw&&typeof window.draw=="function")&&!s.default.instance&&new s.default})},{"../core/main":280,"./internationalization":278,"core-js/modules/es.array.iterator":164,"core-js/modules/es.object.to-string":187,"core-js/modules/es.promise":188,"core-js/modules/es.string.iterator":197,"core-js/modules/web.dom-collections.iterator":243}],278:[function(t,x,v){t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.includes"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.object.keys"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.promise"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.string.includes"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.split"),t("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.setTranslatorLanguage=v.currentTranslatorLanguage=v.availableTranslatorLanguages=v.initialize=v.translator=void 0;var s,c,o=g(t("i18next")),u=g(t("i18next-browser-languagedetector"));function g(i){return i&&i.__esModule?i:{default:i}}function p(i,a){for(var h=0;h=I.width||E>=I.height?[0,0,0,0]:this._getPixel(k,E);return L=new c.default.Image(M*C,P*C),L.pixelDensity(C),L.canvas.getContext("2d").drawImage(I,k,E,M*C,P*C,0,0,M*C,P*C),L}},{key:"textLeading",value:function(k){return typeof k=="number"?(this._setProperty("_leadingSet",!0),this._setProperty("_textLeading",k),this._pInst):this._textLeading}},{key:"textStyle",value:function(k){return k?(k!==o.NORMAL&&k!==o.ITALIC&&k!==o.BOLD&&k!==o.BOLDITALIC||this._setProperty("_textStyle",k),this._applyTextProperties()):this._textStyle}},{key:"textAscent",value:function(){return this._textAscent===null&&this._updateTextMetrics(),this._textAscent}},{key:"textDescent",value:function(){return this._textDescent===null&&this._updateTextMetrics(),this._textDescent}},{key:"textAlign",value:function(k,E){return k!==void 0?(this._setProperty("_textAlign",k),E!==void 0&&this._setProperty("_textBaseline",E),this._applyTextProperties()):{horizontal:this._textAlign,vertical:this._textBaseline}}},{key:"textWrap",value:function(k){return this._setProperty("_textWrap",k),this._textWrap}},{key:"text",value:function(k,E,M,P,L){var C,I,A,N,F=this._pInst,B=this._textWrap,q=Number.MAX_VALUE,V=M;if((this._doFill||this._doStroke)&&k!==void 0){if(C=(k=(k=typeof k!="string"?k.toString():k).replace(/(\t)/g," ")).split(` +`),P!==void 0){switch(this._rectMode===o.CENTER&&(E-=P/2),this._textAlign){case o.CENTER:E+=P/2;break;case o.RIGHT:E+=P}if(L!==void 0){this._rectMode===o.CENTER&&(M-=L/2,V-=L/2);var k=M,H=F.textAscent();switch(this._textBaseline){case o.BOTTOM:N=M+L,M=Math.max(N,M),V+=H;break;case o.CENTER:N=M+L/2,M=Math.max(N,M),V+=H/2}q=M+L-H,this._textBaseline===o.CENTER&&(q=k+L-H/2)}else this._textBaseline!==o.BOTTOM&&this._textBaseline!==o.CENTER||(V=M-(k=F.textSize()*this._textLeading)/2,q=M+k/2);if(B===o.WORD){for(var Z=[],ee=0;eeu.HALF_PI&&a<=3*u.HALF_PI?Math.atan(y/l*Math.tan(a))+u.PI:Math.atan(y/l*Math.tan(a))+u.TWO_PI,h=h<=u.HALF_PI?Math.atan(y/l*Math.tan(h)):h>u.HALF_PI&&h<=3*u.HALF_PI?Math.atan(y/l*Math.tan(h))+u.PI:Math.atan(y/l*Math.tan(h))+u.TWO_PI),hi||Math.abs(this.accelerationY-this.pAccelerationY)>i||Math.abs(this.accelerationZ-this.pAccelerationZ)>i)&&j.deviceMoved(),typeof j.deviceTurned=="function"&&(l=this._toDegrees(this.rotationX)+180,f=this._toDegrees(this.pRotationX)+180,y=c+180,0>>16,p[1+i]=(65280&n[a])>>>8,p[2+i]=255&n[a],p[3+i]=(4278190080&n[a])>>>24},_toImageData:function(p){return p instanceof ImageData?p:p.getContext("2d").getImageData(0,0,p.width,p.height)},_createImageData:function(p,n){return g._tmpCanvas=document.createElement("canvas"),g._tmpCtx=g._tmpCanvas.getContext("2d"),this._tmpCtx.createImageData(p,n)},apply:function(p,y,i){var a=p.getContext("2d"),h=a.getImageData(0,0,p.width,p.height),y=y(h,i);y instanceof ImageData?a.putImageData(y,0,0,0,0,p.width,p.height):a.putImageData(h,0,0,0,0,p.width,p.height)},threshold:function(p){for(var n=1>8)/a,i[h+1]=255*(l*n>>8)/a,i[h+2]=255*(f*n>>8)/a}},dilate:function(p){for(var n,i,a,h,y,l,f,m,b,j=g._toPixels(p),k=0,E=j.length?j.length/4:0,M=new Int32Array(E);k>16&255)+151*(h>>8&255)+28*(255&h))<(f=77*(b>>16&255)+151*(b>>8&255)+28*(255&b))&&(a=b,h=f),h<(f=77*((b=g._getARGB(j,m))>>16&255)+151*(b>>8&255)+28*(255&b))&&(a=b,h=f),h<(m=77*(y>>16&255)+151*(y>>8&255)+28*(255&y))&&(a=y,h=m),h<(b=77*(l>>16&255)+151*(l>>8&255)+28*(255&l))&&(a=l,h=b),M[k++]=a;g._setPixels(j,M)},erode:function(p){for(var n,i,a,h,y,l,f,m,b,j=g._toPixels(p),k=0,E=j.length?j.length/4:0,M=new Int32Array(E);k>16&255)+151*(b>>8&255)+28*(255&b))<(h=77*(h>>16&255)+151*(h>>8&255)+28*(255&h))&&(a=b,h=f),(f=77*((b=g._getARGB(j,m))>>16&255)+151*(b>>8&255)+28*(255&b))>16&255)+151*(y>>8&255)+28*(255&y))>16&255)+151*(l>>8&255)+28*(255&l))>>24],a+=B[(16711680&pe)>>16],h+=B[(65280&pe)>>8],y+=B[255&pe],i+=o[F],f++}ee[m=G+A]=l/i,ue[m]=a/i,T[m]=h/i,D[m]=y/i}G+=M}for(j=(b=-s)*M,N=G=0;N"+V.length.toString()+" out of "+N.toString()),z.next=48,new Promise(function(te){return setTimeout(te,0)});z.next=50;break;case 48:z.next=39;break;case 50:L||H.html("Frames processed, generating color palette..."),this.loop(),this.pixelDensity(q),ue=(0,n.GIFEncoder)(),T=function(te){for(var le=new Uint8Array(te.length*te[0].length),me=0;me"+J.toString()+" out of "+N.toString()),z.next=68,new Promise(function(te){return setTimeout(te,0)});case 68:J++,z.next=60;break;case 71:ue.finish(),pe=ue.bytesView(),pe=new Blob([pe],{type:"image/gif"}),V=[],this._recording=!1,this.loop(),L||(H.html("Done. Downloading your gif!🌸"),0=a&&(a=Math.floor(h.timeDisplayed/a),h.timeDisplayed=0,h.lastChangeTime=y,h.displayIndex+=a,h.loopCount=Math.floor(h.displayIndex/h.numFrames),h.loopLimit!==null&&h.loopCount>=h.loopLimit?h.playing=!1:(y=h.displayIndex%h.numFrames,this.drawingContext.putImageData(h.frames[y].image,0,0),h.displayIndex=y,this.setModified(!0))))}},{key:"_setProperty",value:function(i,a){this[i]=a,this.setModified(!0)}},{key:"loadPixels",value:function(){s.default.Renderer2D.prototype.loadPixels.call(this),this.setModified(!0)}},{key:"updatePixels",value:function(i,a,h,y){s.default.Renderer2D.prototype.updatePixels.call(this,i,a,h,y),this.setModified(!0)}},{key:"get",value:function(i,a,h,y){return s.default._validateParameters("p5.Image.get",arguments),s.default.Renderer2D.prototype.get.apply(this,arguments)}},{key:"_getPixel",value:function(){for(var i=arguments.length,a=new Array(i),h=0;h/g,">").replace(/"/g,""").replace(/'/g,"'")}function i(a,h){h&&h!==!0&&h!=="true"||(h="");var y="";return(a=a||"untitled")&&a.includes(".")&&(y=a.split(".").pop()),h&&y!==h&&(y=h,a="".concat(a,".").concat(y)),[a,y]}t("../core/friendly_errors/validate_params"),t("../core/friendly_errors/file_errors"),t("../core/friendly_errors/fes_core"),c.default.prototype.loadJSON=function(){for(var a=arguments.length,h=new Array(a),y=0;y"),f.print(""),f.print(' '),f.print(""),f.print(""),f.print(" "),y[0]!=="0"){f.print(" ");for(var M=0;M".concat(P)),f.print(" ")}f.print(" ")}for(var L=0;L");for(var C=0;C".concat(I)),f.print(" ")}f.print(" ")}f.print("
            "),f.print(""),f.print("")}f.close(),f.clear()},c.default.prototype.writeFile=function(f,h,m){var l="application/octet-stream",f=(c.default.prototype._isSafari()&&(l="text/plain"),new Blob(f,{type:l}));c.default.prototype.downloadFile(f,h,m)},c.default.prototype.downloadFile=function(a,f,y){var l,f=i(f,y),y=f[0];a instanceof Blob?u.default.saveAs(a,y):((l=document.createElement("a")).href=a,l.download=y,l.onclick=function(b){document.body.removeChild(b.target),b.stopPropagation()},l.style.display="none",document.body.appendChild(l),c.default.prototype._isSafari()&&(a=(a=`Hello, Safari user! To download this file... +`)}}else{if(f.print(""),f.print(""),f.print(' '),f.print(""),f.print(""),f.print(" "),m[0]!=="0"){f.print(" ");for(var M=0;M".concat(P)),f.print(" ")}f.print(" ")}for(var L=0;L");for(var C=0;C".concat(I)),f.print(" ")}f.print(" ")}f.print("
            "),f.print(""),f.print("")}f.close(),f.clear()},c.default.prototype.writeFile=function(f,h,y){var l="application/octet-stream",f=(c.default.prototype._isSafari()&&(l="text/plain"),new Blob(f,{type:l}));c.default.prototype.downloadFile(f,h,y)},c.default.prototype.downloadFile=function(a,f,m){var l,f=i(f,m),m=f[0];a instanceof Blob?u.default.saveAs(a,m):((l=document.createElement("a")).href=a,l.download=m,l.onclick=function(b){document.body.removeChild(b.target),b.stopPropagation()},l.style.display="none",document.body.appendChild(l),c.default.prototype._isSafari()&&(a=(a=`Hello, Safari user! To download this file... 1. Go to File --> Save As. 2. Choose "Page Source" as the Format. -`)+'3. Name it with this extension: ."'.concat(f[1],'"'),alert(a)),l.click())},c.default.prototype._checkFileExtension=i,c.default.prototype._isSafari=function(){return window.HTMLElement.toString().includes("Constructor")},t=c.default,v.default=t},{"../core/friendly_errors/fes_core":271,"../core/friendly_errors/file_errors":272,"../core/friendly_errors/validate_params":275,"../core/main":280,"core-js/modules/es.array.concat":152,"core-js/modules/es.array.includes":162,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.last-index-of":166,"core-js/modules/es.array.map":167,"core-js/modules/es.array.slice":168,"core-js/modules/es.array.splice":170,"core-js/modules/es.function.name":173,"core-js/modules/es.object.from-entries":182,"core-js/modules/es.object.to-string":187,"core-js/modules/es.promise":188,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.string.includes":196,"core-js/modules/es.string.iterator":197,"core-js/modules/es.string.replace":201,"core-js/modules/es.string.split":203,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.typed-array.copy-within":210,"core-js/modules/es.typed-array.every":211,"core-js/modules/es.typed-array.fill":212,"core-js/modules/es.typed-array.filter":213,"core-js/modules/es.typed-array.find":215,"core-js/modules/es.typed-array.find-index":214,"core-js/modules/es.typed-array.for-each":218,"core-js/modules/es.typed-array.includes":219,"core-js/modules/es.typed-array.index-of":220,"core-js/modules/es.typed-array.iterator":223,"core-js/modules/es.typed-array.join":224,"core-js/modules/es.typed-array.last-index-of":225,"core-js/modules/es.typed-array.map":226,"core-js/modules/es.typed-array.reduce":228,"core-js/modules/es.typed-array.reduce-right":227,"core-js/modules/es.typed-array.reverse":229,"core-js/modules/es.typed-array.set":230,"core-js/modules/es.typed-array.slice":231,"core-js/modules/es.typed-array.some":232,"core-js/modules/es.typed-array.sort":233,"core-js/modules/es.typed-array.subarray":234,"core-js/modules/es.typed-array.to-locale-string":235,"core-js/modules/es.typed-array.to-string":236,"core-js/modules/es.typed-array.uint8-array":239,"core-js/modules/web.dom-collections.iterator":243,"core-js/modules/web.url":245,"es6-promise/auto":246,"fetch-jsonp":248,"file-saver":249,"whatwg-fetch":258}],307:[function(t,x,v){t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.splice"),t("core-js/modules/es.regexp.constructor"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.match"),t("core-js/modules/es.string.replace"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.splice"),t("core-js/modules/es.regexp.constructor"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.match"),t("core-js/modules/es.string.replace"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var s=(t=t("../core/main"))&&t.__esModule?t:{default:t};function c(o,u){for(var g=0;g>>0},getSeed:function(){return i},rand:function(){return(a=(1664525*a+1013904223)%h)/h}};m.setSeed(n),c=new Array(4096);for(var l=0;l<4096;l++)c[l]=m.rand()},p.default);v.default=p},{"../core/main":280}],313:[function(t,x,v){function s(i){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a})(i)}function c(i){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(a){return s(a)}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":s(a)})(i)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.every"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.some"),t("core-js/modules/es.math.sign"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.number.is-finite"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.sub"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.every"),t("core-js/modules/es.array.some"),t("core-js/modules/es.math.sign"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.number.is-finite"),t("core-js/modules/es.string.sub"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=(n=t("../core/main"))&&n.__esModule?n:{default:n},u=function(i){if(i&&i.__esModule)return i;if(i===null||c(i)!=="object"&&typeof i!="function")return{default:i};var a=g();if(a&&a.has(i))return a.get(i);var h,m={},l=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(h in i){var f;Object.prototype.hasOwnProperty.call(i,h)&&((f=l?Object.getOwnPropertyDescriptor(i,h):null)&&(f.get||f.set)?Object.defineProperty(m,h,f):m[h]=i[h])}return m.default=i,a&&a.set(i,m),m}(t("../core/constants"));function g(){var i;return typeof WeakMap!="function"?null:(i=new WeakMap,g=function(){return i},i)}function p(i,a){for(var h=0;h>>0},s.default.prototype.randomSeed=function(p){this._lcgSetSeed(c,p),this._gaussian_previous=!1},s.default.prototype.random=function(p,n){var i,a;return s.default._validateParameters("random",arguments),i=this[c]!=null?this._lcg(c):Math.random(),p===void 0?i:n===void 0?Array.isArray(p)?p[Math.floor(i*p.length)]:i*p:(n>>0},getSeed:function(){return i},rand:function(){return(a=(1664525*a+1013904223)%h)/h}};y.setSeed(n),c=new Array(4096);for(var l=0;l<4096;l++)c[l]=y.rand()},p.default);v.default=p},{"../core/main":280}],313:[function(t,x,v){function s(i){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a})(i)}function c(i){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(a){return s(a)}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":s(a)})(i)}t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.every"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.some"),t("core-js/modules/es.math.sign"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.number.is-finite"),t("core-js/modules/es.object.get-own-property-descriptor"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.sub"),t("core-js/modules/es.weak-map"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.concat"),t("core-js/modules/es.array.every"),t("core-js/modules/es.array.some"),t("core-js/modules/es.math.sign"),t("core-js/modules/es.number.constructor"),t("core-js/modules/es.number.is-finite"),t("core-js/modules/es.string.sub"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var o=(n=t("../core/main"))&&n.__esModule?n:{default:n},u=function(i){if(i&&i.__esModule)return i;if(i===null||c(i)!=="object"&&typeof i!="function")return{default:i};var a=g();if(a&&a.has(i))return a.get(i);var h,y={},l=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(h in i){var f;Object.prototype.hasOwnProperty.call(i,h)&&((f=l?Object.getOwnPropertyDescriptor(i,h):null)&&(f.get||f.set)?Object.defineProperty(y,h,f):y[h]=i[h])}return y.default=i,a&&a.set(i,y),y}(t("../core/constants"));function g(){var i;return typeof WeakMap!="function"?null:(i=new WeakMap,g=function(){return i},i)}function p(i,a){for(var h=0;h>>0},s.default.prototype.randomSeed=function(p){this._lcgSetSeed(c,p),this._gaussian_previous=!1},s.default.prototype.random=function(p,n){var i,a;return s.default._validateParameters("random",arguments),i=this[c]!=null?this._lcg(c):Math.random(),p===void 0?i:n===void 0?Array.isArray(p)?p[Math.floor(i*p.length)]:i*p:(nG&&(ce=H,J=F,ne=B,H=K+G*($&&K=o?u.substring(u.length-o,u.length):u}},s.default.prototype.unhex=function(c){return c instanceof Array?c.map(s.default.prototype.unhex):parseInt("0x".concat(c),16)},t=s.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.map":167,"core-js/modules/es.number.constructor":178,"core-js/modules/es.object.to-string":187,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.string.repeat":200}],321:[function(t,x,v){t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.filter"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.number.to-fixed"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.constructor"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.match"),t("core-js/modules/es.string.pad-start"),t("core-js/modules/es.string.replace"),t("core-js/modules/es.string.split"),t("core-js/modules/es.string.trim"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.filter"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.number.to-fixed"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.constructor"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.match"),t("core-js/modules/es.string.pad-start"),t("core-js/modules/es.string.replace"),t("core-js/modules/es.string.split"),t("core-js/modules/es.string.trim"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var s=(n=t("../core/main"))&&n.__esModule?n:{default:n};function c(i,a){return function(h){if(Array.isArray(h))return h}(i)||function(h,m){if(Symbol.iterator in Object(h)||Object.prototype.toString.call(h)==="[object Arguments]"){var l=[],f=!0,y=!1,b=void 0;try{for(var j,k=h[Symbol.iterator]();!(f=(j=k.next()).done)&&(l.push(j.value),!m||l.length!==m);f=!0);}catch(E){y=!0,b=E}finally{try{f||k.return==null||k.return()}finally{if(y)throw b}}return l}}(i,a)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function o(i,a,h){var l=c(i.toString().split("."),2),m=l[0],l=l[1];return h===void 0?(m=m.padStart(a,"0"),l?m+"."+l:m):(m=(i=c(i.toFixed(h).toString().split("."),2))[0],l=i[1],m=m.padStart(a,"0"),l===void 0?m:m+"."+l)}function u(l,a){var h=(l=l.toString()).indexOf("."),m=h!==-1?l.substring(h):"",l=(l=h!==-1?l.substring(0,h):l).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");if(a===0)m="";else if(a!==void 0)if(a>m.length)for(var f=a-(m+=h===-1?".":"").length+1,y=0;y=u.TWO_PI?"".concat(E="ellipse","|"):"".concat(E="arc","|").concat(f,"|").concat(y,"|").concat(b,"|")).concat(j,"|"),E=(this.geometryInHash(k)||((i=new o.default.Geometry(j,1,function(){if(f.toFixed(10)!==y.toFixed(10)){b!==u.PIE&&b!==void 0||(this.vertices.push(new o.default.Vector(.5,.5,0)),this.uvs.push([.5,.5]));for(var M=0;M<=j;M++){var L=(y-f)*(M/j)+f,P=.5+Math.cos(L)/2,L=.5+Math.sin(L)/2;this.vertices.push(new o.default.Vector(P,L,0)),this.uvs.push([P,L]),M>5&31)/31,(W>>10&31)/31)),new c.default.Vector(J,ne,ce)),pe=1;pe<=3;pe++){var K=$+12*pe,K=new c.default.Vector(ee.getFloat32(K,!0),ee.getFloat32(4+K,!0),ee.getFloat32(8+K,!0));I.vertices.push(K),I.vertexNormals.push(ie),T&&q.push(N,F,B)}I.faces.push([3*G,3*G+1,3*G+2]),I.uvs.push([0,0],[0,0],[0,0])}})(L,C);else{if(C=new DataView(C),!("TextDecoder"in window))return console.warn("Sorry, ASCII STL loading only works in browsers that support TextDecoder (https://caniuse.com/#feat=textencoder)");C=new TextDecoder("utf-8").decode(C).split(` -`),function(I,A){for(var N,F,B="",q=[],V=0;VG&&(ce=H,J=F,ne=B,H=K+G*($&&K=o?u.substring(u.length-o,u.length):u}},s.default.prototype.unhex=function(c){return c instanceof Array?c.map(s.default.prototype.unhex):parseInt("0x".concat(c),16)},t=s.default,v.default=t},{"../core/main":280,"core-js/modules/es.array.map":167,"core-js/modules/es.number.constructor":178,"core-js/modules/es.object.to-string":187,"core-js/modules/es.regexp.to-string":193,"core-js/modules/es.string.repeat":200}],321:[function(t,x,v){t("core-js/modules/es.symbol"),t("core-js/modules/es.symbol.description"),t("core-js/modules/es.symbol.iterator"),t("core-js/modules/es.array.filter"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.number.to-fixed"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.constructor"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.iterator"),t("core-js/modules/es.string.match"),t("core-js/modules/es.string.pad-start"),t("core-js/modules/es.string.replace"),t("core-js/modules/es.string.split"),t("core-js/modules/es.string.trim"),t("core-js/modules/web.dom-collections.iterator"),t("core-js/modules/es.array.filter"),t("core-js/modules/es.array.index-of"),t("core-js/modules/es.array.join"),t("core-js/modules/es.array.map"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.number.to-fixed"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.regexp.constructor"),t("core-js/modules/es.regexp.exec"),t("core-js/modules/es.regexp.to-string"),t("core-js/modules/es.string.match"),t("core-js/modules/es.string.pad-start"),t("core-js/modules/es.string.replace"),t("core-js/modules/es.string.split"),t("core-js/modules/es.string.trim"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0;var s=(n=t("../core/main"))&&n.__esModule?n:{default:n};function c(i,a){return function(h){if(Array.isArray(h))return h}(i)||function(h,y){if(Symbol.iterator in Object(h)||Object.prototype.toString.call(h)==="[object Arguments]"){var l=[],f=!0,m=!1,b=void 0;try{for(var j,k=h[Symbol.iterator]();!(f=(j=k.next()).done)&&(l.push(j.value),!y||l.length!==y);f=!0);}catch(E){m=!0,b=E}finally{try{f||k.return==null||k.return()}finally{if(m)throw b}}return l}}(i,a)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function o(i,a,h){var l=c(i.toString().split("."),2),y=l[0],l=l[1];return h===void 0?(y=y.padStart(a,"0"),l?y+"."+l:y):(y=(i=c(i.toFixed(h).toString().split("."),2))[0],l=i[1],y=y.padStart(a,"0"),l===void 0?y:y+"."+l)}function u(l,a){var h=(l=l.toString()).indexOf("."),y=h!==-1?l.substring(h):"",l=(l=h!==-1?l.substring(0,h):l).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");if(a===0)y="";else if(a!==void 0)if(a>y.length)for(var f=a-(y+=h===-1?".":"").length+1,m=0;m=u.TWO_PI?"".concat(E="ellipse","|"):"".concat(E="arc","|").concat(f,"|").concat(m,"|").concat(b,"|")).concat(j,"|"),E=(this.geometryInHash(k)||((i=new o.default.Geometry(j,1,function(){if(f.toFixed(10)!==m.toFixed(10)){b!==u.PIE&&b!==void 0||(this.vertices.push(new o.default.Vector(.5,.5,0)),this.uvs.push([.5,.5]));for(var M=0;M<=j;M++){var L=(m-f)*(M/j)+f,P=.5+Math.cos(L)/2,L=.5+Math.sin(L)/2;this.vertices.push(new o.default.Vector(P,L,0)),this.uvs.push([P,L]),M>5&31)/31,(W>>10&31)/31)),new c.default.Vector(J,ne,ce)),pe=1;pe<=3;pe++){var K=$+12*pe,K=new c.default.Vector(ee.getFloat32(K,!0),ee.getFloat32(4+K,!0),ee.getFloat32(8+K,!0));I.vertices.push(K),I.vertexNormals.push(ie),T&&q.push(N,F,B)}I.faces.push([3*G,3*G+1,3*G+2]),I.uvs.push([0,0],[0,0],[0,0])}})(L,C);else{if(C=new DataView(C),!("TextDecoder"in window))return console.warn("Sorry, ASCII STL loading only works in browsers that support TextDecoder (https://caniuse.com/#feat=textencoder)");C=new TextDecoder("utf-8").decode(C).split(` +`),function(I,A){for(var N,F,B="",q=[],V=0;Vthis.cameraFar&&(a=this.cameraFar),Math.acos(Math.max(-1,Math.min(1,s.default.Vector.dot(h,m))))+b),b=p;(y<=0||y>=Math.PI)&&(this.upX*=-1,this.upY*=-1,this.upZ*=-1),m.mult(Math.cos(y)),f.mult(Math.cos(b)*Math.sin(y)),l.mult(Math.sin(b)*Math.sin(y)),h.set(m).add(f).add(l),this.eyeX=a*h.x+this.centerX,this.eyeY=a*h.y+this.centerY,this.eyeZ=a*h.z+this.centerZ,this.camera(this.eyeX,this.eyeY,this.eyeZ,this.centerX,this.centerY,this.centerZ,this.upX,this.upY,this.upZ)}},{key:"_orbitFree",value:function(y,b,k){var h=this.eyeX-this.centerX,m=this.eyeY-this.centerY,l=this.eyeZ-this.centerZ,a=Math.hypot(h,m,l),h=new s.default.Vector(h,m,l).normalize(),m=new s.default.Vector(this.upX,this.upY,this.upZ),l=s.default.Vector.cross(m,h).normalize(),f=s.default.Vector.cross(h,l),E=Math.atan2(b,y),E=(f.mult(Math.sin(E)),l.mult(Math.cos(E)).add(f),Math.sqrt(y*y+b*b)),f=s.default.Vector.cross(h,l),y=((a=(a*=Math.pow(10,k))this.cameraFar&&(a=this.cameraFar),Math.cos(E)),b=Math.sin(E),k=m.dot(h),E=m.dot(l),j=k*y+E*b,k=-k*b+E*y,E=m.dot(f);m.x=j*h.x+k*l.x+E*f.x,m.y=j*h.y+k*l.y+E*f.y,m.z=j*h.z+k*l.z+E*f.z,l.mult(-b),h.mult(y).add(l).mult(a),this.camera(h.x+this.centerX,h.y+this.centerY,h.z+this.centerZ,this.centerX,this.centerY,this.centerZ,m.x,m.y,m.z)}},{key:"_isActive",value:function(){return this===this._renderer._curCamera}}])&&c(u.prototype,g),o}(),s.default.prototype.setCamera=function(o){this._renderer._curCamera=o,this._renderer.uPMatrix.set(o.projMatrix)},t=s.default.Camera,v.default=t},{"../core/main":280,"core-js/modules/es.array.slice":168,"core-js/modules/es.math.hypot":175,"core-js/modules/es.string.sub":205}],330:[function(t,x,v){t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.math.log2"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.typed-array.float32-array"),t("core-js/modules/es.typed-array.copy-within"),t("core-js/modules/es.typed-array.every"),t("core-js/modules/es.typed-array.fill"),t("core-js/modules/es.typed-array.filter"),t("core-js/modules/es.typed-array.find"),t("core-js/modules/es.typed-array.find-index"),t("core-js/modules/es.typed-array.for-each"),t("core-js/modules/es.typed-array.includes"),t("core-js/modules/es.typed-array.index-of"),t("core-js/modules/es.typed-array.iterator"),t("core-js/modules/es.typed-array.join"),t("core-js/modules/es.typed-array.last-index-of"),t("core-js/modules/es.typed-array.map"),t("core-js/modules/es.typed-array.reduce"),t("core-js/modules/es.typed-array.reduce-right"),t("core-js/modules/es.typed-array.reverse"),t("core-js/modules/es.typed-array.set"),t("core-js/modules/es.typed-array.slice"),t("core-js/modules/es.typed-array.some"),t("core-js/modules/es.typed-array.sort"),t("core-js/modules/es.typed-array.subarray"),t("core-js/modules/es.typed-array.to-locale-string"),t("core-js/modules/es.typed-array.to-string"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.math.log2"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.typed-array.float32-array"),t("core-js/modules/es.typed-array.copy-within"),t("core-js/modules/es.typed-array.every"),t("core-js/modules/es.typed-array.fill"),t("core-js/modules/es.typed-array.filter"),t("core-js/modules/es.typed-array.find"),t("core-js/modules/es.typed-array.find-index"),t("core-js/modules/es.typed-array.for-each"),t("core-js/modules/es.typed-array.includes"),t("core-js/modules/es.typed-array.index-of"),t("core-js/modules/es.typed-array.iterator"),t("core-js/modules/es.typed-array.join"),t("core-js/modules/es.typed-array.last-index-of"),t("core-js/modules/es.typed-array.map"),t("core-js/modules/es.typed-array.reduce"),t("core-js/modules/es.typed-array.reduce-right"),t("core-js/modules/es.typed-array.reverse"),t("core-js/modules/es.typed-array.set"),t("core-js/modules/es.typed-array.slice"),t("core-js/modules/es.typed-array.some"),t("core-js/modules/es.typed-array.sort"),t("core-js/modules/es.typed-array.subarray"),t("core-js/modules/es.typed-array.to-locale-string"),t("core-js/modules/es.typed-array.to-string"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t};function s(c,o){for(var u=0;u=this.width||I>=this.height)&&(console.warn("The x and y values passed to p5.Framebuffer.get are outside of its range and will be clamped."),C=this.target.constrain(C,0,this.width-1),I=this.target.constrain(I,0,this.height-1)),(0,p.readPixelWebGL)(this.gl,this.framebuffer,C*this.density,I*this.density,F.format,F.type);C=this.target.constrain(C,0,this.width-1),I=this.target.constrain(I,0,this.height-1),A=this.target.constrain(A,1,this.width-C),N=this.target.constrain(N,1,this.height-I);for(var B=(0,p.readPixelsWebGL)(void 0,this.gl,this.framebuffer,C*this.density,I*this.density,A*this.density,N*this.density,F.format,F.type),q=new Uint8ClampedArray(A*N*this.density*this.density*4),V=(q.fill(255),F.type===this.gl.RGB?3:4),H=0;Hthis.vertices.length-1-this.detailX;b--)l.add(this.vertexNormals[b]);l=o.default.Vector.div(l,this.detailX);for(var j=this.vertices.length-1;j>this.vertices.length-1-this.detailX;j--)this.vertexNormals[j]=l;return this}},{key:"_makeTriangleEdges",value:function(){for(var l=this.edges.length=0;l 65535 triangles. Your web browser does not support the WebGL Extension OES_element_index_uint.");h.drawElements(h.TRIANGLES,a.vertexCount,a.indexBufferType,0)}else h.drawArrays(n||h.TRIANGLES,0,a.vertexCount)},o.default.RendererGL.prototype._drawPoints=function(n,i){var a=this.GL,h=this._getImmediatePointShader();this._setPointUniforms(h),this._bindBuffer(i,a.ARRAY_BUFFER,this._vToNArray(n),Float32Array,a.STATIC_DRAW),h.enableAttrib(h.attributes.aPosition,3),this._applyColorBlend(this.curStrokeColor),a.drawArrays(a.Points,0,n.length),h.unbindShader()};var p=o.default.RendererGL;v.default=p},{"../core/constants":269,"../core/main":280,"./p5.RenderBuffer":334,"./p5.RendererGL":337,"core-js/modules/es.array.fill":155,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.some":169,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.keys":186,"core-js/modules/es.object.to-string":187,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.typed-array.copy-within":210,"core-js/modules/es.typed-array.every":211,"core-js/modules/es.typed-array.fill":212,"core-js/modules/es.typed-array.filter":213,"core-js/modules/es.typed-array.find":215,"core-js/modules/es.typed-array.find-index":214,"core-js/modules/es.typed-array.float32-array":216,"core-js/modules/es.typed-array.for-each":218,"core-js/modules/es.typed-array.includes":219,"core-js/modules/es.typed-array.index-of":220,"core-js/modules/es.typed-array.iterator":223,"core-js/modules/es.typed-array.join":224,"core-js/modules/es.typed-array.last-index-of":225,"core-js/modules/es.typed-array.map":226,"core-js/modules/es.typed-array.reduce":228,"core-js/modules/es.typed-array.reduce-right":227,"core-js/modules/es.typed-array.reverse":229,"core-js/modules/es.typed-array.set":230,"core-js/modules/es.typed-array.slice":231,"core-js/modules/es.typed-array.some":232,"core-js/modules/es.typed-array.sort":233,"core-js/modules/es.typed-array.subarray":234,"core-js/modules/es.typed-array.to-locale-string":235,"core-js/modules/es.typed-array.to-string":236,"core-js/modules/es.typed-array.uint16-array":237,"core-js/modules/es.typed-array.uint32-array":238,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}],337:[function(A,x,v){function s(H){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(Z){return typeof Z}:function(Z){return Z&&typeof Symbol=="function"&&Z.constructor===Symbol&&Z!==Symbol.prototype?"symbol":typeof Z})(H)}function c(H){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(Z){return s(Z)}:function(Z){return Z&&typeof Symbol=="function"&&Z.constructor===Symbol&&Z!==Symbol.prototype?"symbol":s(Z)})(H)}A("core-js/modules/es.symbol"),A("core-js/modules/es.symbol.description"),A("core-js/modules/es.symbol.iterator"),A("core-js/modules/es.array.concat"),A("core-js/modules/es.array.copy-within"),A("core-js/modules/es.array.every"),A("core-js/modules/es.array.fill"),A("core-js/modules/es.array.flat"),A("core-js/modules/es.array.flat-map"),A("core-js/modules/es.array.from"),A("core-js/modules/es.array.includes"),A("core-js/modules/es.array.iterator"),A("core-js/modules/es.array.map"),A("core-js/modules/es.array.slice"),A("core-js/modules/es.array.some"),A("core-js/modules/es.array.unscopables.flat"),A("core-js/modules/es.array.unscopables.flat-map"),A("core-js/modules/es.map"),A("core-js/modules/es.object.assign"),A("core-js/modules/es.object.get-own-property-descriptor"),A("core-js/modules/es.object.get-prototype-of"),A("core-js/modules/es.object.to-string"),A("core-js/modules/es.reflect.construct"),A("core-js/modules/es.reflect.get"),A("core-js/modules/es.regexp.to-string"),A("core-js/modules/es.set"),A("core-js/modules/es.string.includes"),A("core-js/modules/es.string.iterator"),A("core-js/modules/es.typed-array.float32-array"),A("core-js/modules/es.typed-array.float64-array"),A("core-js/modules/es.typed-array.int16-array"),A("core-js/modules/es.typed-array.uint8-array"),A("core-js/modules/es.typed-array.uint16-array"),A("core-js/modules/es.typed-array.uint32-array"),A("core-js/modules/es.typed-array.copy-within"),A("core-js/modules/es.typed-array.every"),A("core-js/modules/es.typed-array.fill"),A("core-js/modules/es.typed-array.filter"),A("core-js/modules/es.typed-array.find"),A("core-js/modules/es.typed-array.find-index"),A("core-js/modules/es.typed-array.for-each"),A("core-js/modules/es.typed-array.includes"),A("core-js/modules/es.typed-array.index-of"),A("core-js/modules/es.typed-array.iterator"),A("core-js/modules/es.typed-array.join"),A("core-js/modules/es.typed-array.last-index-of"),A("core-js/modules/es.typed-array.map"),A("core-js/modules/es.typed-array.reduce"),A("core-js/modules/es.typed-array.reduce-right"),A("core-js/modules/es.typed-array.reverse"),A("core-js/modules/es.typed-array.set"),A("core-js/modules/es.typed-array.slice"),A("core-js/modules/es.typed-array.some"),A("core-js/modules/es.typed-array.sort"),A("core-js/modules/es.typed-array.subarray"),A("core-js/modules/es.typed-array.to-locale-string"),A("core-js/modules/es.typed-array.to-string"),A("core-js/modules/es.weak-map"),A("core-js/modules/web.dom-collections.iterator"),A("core-js/modules/es.symbol"),A("core-js/modules/es.symbol.description"),A("core-js/modules/es.symbol.iterator"),A("core-js/modules/es.array.concat"),A("core-js/modules/es.array.copy-within"),A("core-js/modules/es.array.every"),A("core-js/modules/es.array.fill"),A("core-js/modules/es.array.flat"),A("core-js/modules/es.array.flat-map"),A("core-js/modules/es.array.from"),A("core-js/modules/es.array.includes"),A("core-js/modules/es.array.iterator"),A("core-js/modules/es.array.map"),A("core-js/modules/es.array.slice"),A("core-js/modules/es.array.some"),A("core-js/modules/es.array.unscopables.flat"),A("core-js/modules/es.array.unscopables.flat-map"),A("core-js/modules/es.map"),A("core-js/modules/es.object.assign"),A("core-js/modules/es.object.to-string"),A("core-js/modules/es.set"),A("core-js/modules/es.string.includes"),A("core-js/modules/es.string.iterator"),A("core-js/modules/es.typed-array.float32-array"),A("core-js/modules/es.typed-array.float64-array"),A("core-js/modules/es.typed-array.int16-array"),A("core-js/modules/es.typed-array.uint8-array"),A("core-js/modules/es.typed-array.uint16-array"),A("core-js/modules/es.typed-array.uint32-array"),A("core-js/modules/es.typed-array.copy-within"),A("core-js/modules/es.typed-array.every"),A("core-js/modules/es.typed-array.fill"),A("core-js/modules/es.typed-array.filter"),A("core-js/modules/es.typed-array.find"),A("core-js/modules/es.typed-array.find-index"),A("core-js/modules/es.typed-array.for-each"),A("core-js/modules/es.typed-array.includes"),A("core-js/modules/es.typed-array.index-of"),A("core-js/modules/es.typed-array.iterator"),A("core-js/modules/es.typed-array.join"),A("core-js/modules/es.typed-array.last-index-of"),A("core-js/modules/es.typed-array.map"),A("core-js/modules/es.typed-array.reduce"),A("core-js/modules/es.typed-array.reduce-right"),A("core-js/modules/es.typed-array.reverse"),A("core-js/modules/es.typed-array.set"),A("core-js/modules/es.typed-array.slice"),A("core-js/modules/es.typed-array.some"),A("core-js/modules/es.typed-array.sort"),A("core-js/modules/es.typed-array.subarray"),A("core-js/modules/es.typed-array.to-locale-string"),A("core-js/modules/es.typed-array.to-string"),A("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.readPixelsWebGL=q,v.readPixelWebGL=V,v.default=void 0;var o=a(A("../core/main")),u=function(H){if(H&&H.__esModule)return H;if(H===null||c(H)!=="object"&&typeof H!="function")return{default:H};var Z=i();if(Z&&Z.has(H))return Z.get(H);var ee,ue={},T=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(ee in H){var D;Object.prototype.hasOwnProperty.call(H,ee)&&((D=T?Object.getOwnPropertyDescriptor(H,ee):null)&&(D.get||D.set)?Object.defineProperty(ue,ee,D):ue[ee]=H[ee])}return ue.default=H,Z&&Z.set(H,ue),ue}(A("../core/constants")),g=a(A("./GeometryBuilder")),p=a(A("libtess")),n=(A("./p5.Shader"),A("./p5.Camera"),A("../core/p5.Renderer"),A("./p5.Matrix"),A("./p5.Framebuffer"),A("path"),A("./p5.Texture"));function i(){var H;return typeof WeakMap!="function"?null:(H=new WeakMap,i=function(){return H},H)}function a(H){return H&&H.__esModule?H:{default:H}}function h(H){return function(Z){if(Array.isArray(Z)){for(var ee=0,ue=new Array(Z.length);eethis.cameraFar&&(a=this.cameraFar),Math.acos(Math.max(-1,Math.min(1,s.default.Vector.dot(h,y))))+b),b=p;(m<=0||m>=Math.PI)&&(this.upX*=-1,this.upY*=-1,this.upZ*=-1),y.mult(Math.cos(m)),f.mult(Math.cos(b)*Math.sin(m)),l.mult(Math.sin(b)*Math.sin(m)),h.set(y).add(f).add(l),this.eyeX=a*h.x+this.centerX,this.eyeY=a*h.y+this.centerY,this.eyeZ=a*h.z+this.centerZ,this.camera(this.eyeX,this.eyeY,this.eyeZ,this.centerX,this.centerY,this.centerZ,this.upX,this.upY,this.upZ)}},{key:"_orbitFree",value:function(m,b,k){var h=this.eyeX-this.centerX,y=this.eyeY-this.centerY,l=this.eyeZ-this.centerZ,a=Math.hypot(h,y,l),h=new s.default.Vector(h,y,l).normalize(),y=new s.default.Vector(this.upX,this.upY,this.upZ),l=s.default.Vector.cross(y,h).normalize(),f=s.default.Vector.cross(h,l),E=Math.atan2(b,m),E=(f.mult(Math.sin(E)),l.mult(Math.cos(E)).add(f),Math.sqrt(m*m+b*b)),f=s.default.Vector.cross(h,l),m=((a=(a*=Math.pow(10,k))this.cameraFar&&(a=this.cameraFar),Math.cos(E)),b=Math.sin(E),k=y.dot(h),E=y.dot(l),j=k*m+E*b,k=-k*b+E*m,E=y.dot(f);y.x=j*h.x+k*l.x+E*f.x,y.y=j*h.y+k*l.y+E*f.y,y.z=j*h.z+k*l.z+E*f.z,l.mult(-b),h.mult(m).add(l).mult(a),this.camera(h.x+this.centerX,h.y+this.centerY,h.z+this.centerZ,this.centerX,this.centerY,this.centerZ,y.x,y.y,y.z)}},{key:"_isActive",value:function(){return this===this._renderer._curCamera}}])&&c(u.prototype,g),o}(),s.default.prototype.setCamera=function(o){this._renderer._curCamera=o,this._renderer.uPMatrix.set(o.projMatrix)},t=s.default.Camera,v.default=t},{"../core/main":280,"core-js/modules/es.array.slice":168,"core-js/modules/es.math.hypot":175,"core-js/modules/es.string.sub":205}],330:[function(t,x,v){t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.math.log2"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.typed-array.float32-array"),t("core-js/modules/es.typed-array.copy-within"),t("core-js/modules/es.typed-array.every"),t("core-js/modules/es.typed-array.fill"),t("core-js/modules/es.typed-array.filter"),t("core-js/modules/es.typed-array.find"),t("core-js/modules/es.typed-array.find-index"),t("core-js/modules/es.typed-array.for-each"),t("core-js/modules/es.typed-array.includes"),t("core-js/modules/es.typed-array.index-of"),t("core-js/modules/es.typed-array.iterator"),t("core-js/modules/es.typed-array.join"),t("core-js/modules/es.typed-array.last-index-of"),t("core-js/modules/es.typed-array.map"),t("core-js/modules/es.typed-array.reduce"),t("core-js/modules/es.typed-array.reduce-right"),t("core-js/modules/es.typed-array.reverse"),t("core-js/modules/es.typed-array.set"),t("core-js/modules/es.typed-array.slice"),t("core-js/modules/es.typed-array.some"),t("core-js/modules/es.typed-array.sort"),t("core-js/modules/es.typed-array.subarray"),t("core-js/modules/es.typed-array.to-locale-string"),t("core-js/modules/es.typed-array.to-string"),t("core-js/modules/es.array.iterator"),t("core-js/modules/es.array.slice"),t("core-js/modules/es.math.log2"),t("core-js/modules/es.object.to-string"),t("core-js/modules/es.typed-array.float32-array"),t("core-js/modules/es.typed-array.copy-within"),t("core-js/modules/es.typed-array.every"),t("core-js/modules/es.typed-array.fill"),t("core-js/modules/es.typed-array.filter"),t("core-js/modules/es.typed-array.find"),t("core-js/modules/es.typed-array.find-index"),t("core-js/modules/es.typed-array.for-each"),t("core-js/modules/es.typed-array.includes"),t("core-js/modules/es.typed-array.index-of"),t("core-js/modules/es.typed-array.iterator"),t("core-js/modules/es.typed-array.join"),t("core-js/modules/es.typed-array.last-index-of"),t("core-js/modules/es.typed-array.map"),t("core-js/modules/es.typed-array.reduce"),t("core-js/modules/es.typed-array.reduce-right"),t("core-js/modules/es.typed-array.reverse"),t("core-js/modules/es.typed-array.set"),t("core-js/modules/es.typed-array.slice"),t("core-js/modules/es.typed-array.some"),t("core-js/modules/es.typed-array.sort"),t("core-js/modules/es.typed-array.subarray"),t("core-js/modules/es.typed-array.to-locale-string"),t("core-js/modules/es.typed-array.to-string"),Object.defineProperty(v,"__esModule",{value:!0}),v.default=void 0,t=(t=t("../core/main"))&&t.__esModule?t:{default:t};function s(c,o){for(var u=0;u=this.width||I>=this.height)&&(console.warn("The x and y values passed to p5.Framebuffer.get are outside of its range and will be clamped."),C=this.target.constrain(C,0,this.width-1),I=this.target.constrain(I,0,this.height-1)),(0,p.readPixelWebGL)(this.gl,this.framebuffer,C*this.density,I*this.density,F.format,F.type);C=this.target.constrain(C,0,this.width-1),I=this.target.constrain(I,0,this.height-1),A=this.target.constrain(A,1,this.width-C),N=this.target.constrain(N,1,this.height-I);for(var B=(0,p.readPixelsWebGL)(void 0,this.gl,this.framebuffer,C*this.density,I*this.density,A*this.density,N*this.density,F.format,F.type),q=new Uint8ClampedArray(A*N*this.density*this.density*4),V=(q.fill(255),F.type===this.gl.RGB?3:4),H=0;Hthis.vertices.length-1-this.detailX;b--)l.add(this.vertexNormals[b]);l=o.default.Vector.div(l,this.detailX);for(var j=this.vertices.length-1;j>this.vertices.length-1-this.detailX;j--)this.vertexNormals[j]=l;return this}},{key:"_makeTriangleEdges",value:function(){for(var l=this.edges.length=0;l 65535 triangles. Your web browser does not support the WebGL Extension OES_element_index_uint.");h.drawElements(h.TRIANGLES,a.vertexCount,a.indexBufferType,0)}else h.drawArrays(n||h.TRIANGLES,0,a.vertexCount)},o.default.RendererGL.prototype._drawPoints=function(n,i){var a=this.GL,h=this._getImmediatePointShader();this._setPointUniforms(h),this._bindBuffer(i,a.ARRAY_BUFFER,this._vToNArray(n),Float32Array,a.STATIC_DRAW),h.enableAttrib(h.attributes.aPosition,3),this._applyColorBlend(this.curStrokeColor),a.drawArrays(a.Points,0,n.length),h.unbindShader()};var p=o.default.RendererGL;v.default=p},{"../core/constants":269,"../core/main":280,"./p5.RenderBuffer":334,"./p5.RendererGL":337,"core-js/modules/es.array.fill":155,"core-js/modules/es.array.iterator":164,"core-js/modules/es.array.some":169,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.keys":186,"core-js/modules/es.object.to-string":187,"core-js/modules/es.string.iterator":197,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.typed-array.copy-within":210,"core-js/modules/es.typed-array.every":211,"core-js/modules/es.typed-array.fill":212,"core-js/modules/es.typed-array.filter":213,"core-js/modules/es.typed-array.find":215,"core-js/modules/es.typed-array.find-index":214,"core-js/modules/es.typed-array.float32-array":216,"core-js/modules/es.typed-array.for-each":218,"core-js/modules/es.typed-array.includes":219,"core-js/modules/es.typed-array.index-of":220,"core-js/modules/es.typed-array.iterator":223,"core-js/modules/es.typed-array.join":224,"core-js/modules/es.typed-array.last-index-of":225,"core-js/modules/es.typed-array.map":226,"core-js/modules/es.typed-array.reduce":228,"core-js/modules/es.typed-array.reduce-right":227,"core-js/modules/es.typed-array.reverse":229,"core-js/modules/es.typed-array.set":230,"core-js/modules/es.typed-array.slice":231,"core-js/modules/es.typed-array.some":232,"core-js/modules/es.typed-array.sort":233,"core-js/modules/es.typed-array.subarray":234,"core-js/modules/es.typed-array.to-locale-string":235,"core-js/modules/es.typed-array.to-string":236,"core-js/modules/es.typed-array.uint16-array":237,"core-js/modules/es.typed-array.uint32-array":238,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}],337:[function(A,x,v){function s(H){return(s=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(Z){return typeof Z}:function(Z){return Z&&typeof Symbol=="function"&&Z.constructor===Symbol&&Z!==Symbol.prototype?"symbol":typeof Z})(H)}function c(H){return(c=typeof Symbol=="function"&&s(Symbol.iterator)==="symbol"?function(Z){return s(Z)}:function(Z){return Z&&typeof Symbol=="function"&&Z.constructor===Symbol&&Z!==Symbol.prototype?"symbol":s(Z)})(H)}A("core-js/modules/es.symbol"),A("core-js/modules/es.symbol.description"),A("core-js/modules/es.symbol.iterator"),A("core-js/modules/es.array.concat"),A("core-js/modules/es.array.copy-within"),A("core-js/modules/es.array.every"),A("core-js/modules/es.array.fill"),A("core-js/modules/es.array.flat"),A("core-js/modules/es.array.flat-map"),A("core-js/modules/es.array.from"),A("core-js/modules/es.array.includes"),A("core-js/modules/es.array.iterator"),A("core-js/modules/es.array.map"),A("core-js/modules/es.array.slice"),A("core-js/modules/es.array.some"),A("core-js/modules/es.array.unscopables.flat"),A("core-js/modules/es.array.unscopables.flat-map"),A("core-js/modules/es.map"),A("core-js/modules/es.object.assign"),A("core-js/modules/es.object.get-own-property-descriptor"),A("core-js/modules/es.object.get-prototype-of"),A("core-js/modules/es.object.to-string"),A("core-js/modules/es.reflect.construct"),A("core-js/modules/es.reflect.get"),A("core-js/modules/es.regexp.to-string"),A("core-js/modules/es.set"),A("core-js/modules/es.string.includes"),A("core-js/modules/es.string.iterator"),A("core-js/modules/es.typed-array.float32-array"),A("core-js/modules/es.typed-array.float64-array"),A("core-js/modules/es.typed-array.int16-array"),A("core-js/modules/es.typed-array.uint8-array"),A("core-js/modules/es.typed-array.uint16-array"),A("core-js/modules/es.typed-array.uint32-array"),A("core-js/modules/es.typed-array.copy-within"),A("core-js/modules/es.typed-array.every"),A("core-js/modules/es.typed-array.fill"),A("core-js/modules/es.typed-array.filter"),A("core-js/modules/es.typed-array.find"),A("core-js/modules/es.typed-array.find-index"),A("core-js/modules/es.typed-array.for-each"),A("core-js/modules/es.typed-array.includes"),A("core-js/modules/es.typed-array.index-of"),A("core-js/modules/es.typed-array.iterator"),A("core-js/modules/es.typed-array.join"),A("core-js/modules/es.typed-array.last-index-of"),A("core-js/modules/es.typed-array.map"),A("core-js/modules/es.typed-array.reduce"),A("core-js/modules/es.typed-array.reduce-right"),A("core-js/modules/es.typed-array.reverse"),A("core-js/modules/es.typed-array.set"),A("core-js/modules/es.typed-array.slice"),A("core-js/modules/es.typed-array.some"),A("core-js/modules/es.typed-array.sort"),A("core-js/modules/es.typed-array.subarray"),A("core-js/modules/es.typed-array.to-locale-string"),A("core-js/modules/es.typed-array.to-string"),A("core-js/modules/es.weak-map"),A("core-js/modules/web.dom-collections.iterator"),A("core-js/modules/es.symbol"),A("core-js/modules/es.symbol.description"),A("core-js/modules/es.symbol.iterator"),A("core-js/modules/es.array.concat"),A("core-js/modules/es.array.copy-within"),A("core-js/modules/es.array.every"),A("core-js/modules/es.array.fill"),A("core-js/modules/es.array.flat"),A("core-js/modules/es.array.flat-map"),A("core-js/modules/es.array.from"),A("core-js/modules/es.array.includes"),A("core-js/modules/es.array.iterator"),A("core-js/modules/es.array.map"),A("core-js/modules/es.array.slice"),A("core-js/modules/es.array.some"),A("core-js/modules/es.array.unscopables.flat"),A("core-js/modules/es.array.unscopables.flat-map"),A("core-js/modules/es.map"),A("core-js/modules/es.object.assign"),A("core-js/modules/es.object.to-string"),A("core-js/modules/es.set"),A("core-js/modules/es.string.includes"),A("core-js/modules/es.string.iterator"),A("core-js/modules/es.typed-array.float32-array"),A("core-js/modules/es.typed-array.float64-array"),A("core-js/modules/es.typed-array.int16-array"),A("core-js/modules/es.typed-array.uint8-array"),A("core-js/modules/es.typed-array.uint16-array"),A("core-js/modules/es.typed-array.uint32-array"),A("core-js/modules/es.typed-array.copy-within"),A("core-js/modules/es.typed-array.every"),A("core-js/modules/es.typed-array.fill"),A("core-js/modules/es.typed-array.filter"),A("core-js/modules/es.typed-array.find"),A("core-js/modules/es.typed-array.find-index"),A("core-js/modules/es.typed-array.for-each"),A("core-js/modules/es.typed-array.includes"),A("core-js/modules/es.typed-array.index-of"),A("core-js/modules/es.typed-array.iterator"),A("core-js/modules/es.typed-array.join"),A("core-js/modules/es.typed-array.last-index-of"),A("core-js/modules/es.typed-array.map"),A("core-js/modules/es.typed-array.reduce"),A("core-js/modules/es.typed-array.reduce-right"),A("core-js/modules/es.typed-array.reverse"),A("core-js/modules/es.typed-array.set"),A("core-js/modules/es.typed-array.slice"),A("core-js/modules/es.typed-array.some"),A("core-js/modules/es.typed-array.sort"),A("core-js/modules/es.typed-array.subarray"),A("core-js/modules/es.typed-array.to-locale-string"),A("core-js/modules/es.typed-array.to-string"),A("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(v,"__esModule",{value:!0}),v.readPixelsWebGL=q,v.readPixelWebGL=V,v.default=void 0;var o=a(A("../core/main")),u=function(H){if(H&&H.__esModule)return H;if(H===null||c(H)!=="object"&&typeof H!="function")return{default:H};var Z=i();if(Z&&Z.has(H))return Z.get(H);var ee,ue={},T=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(ee in H){var D;Object.prototype.hasOwnProperty.call(H,ee)&&((D=T?Object.getOwnPropertyDescriptor(H,ee):null)&&(D.get||D.set)?Object.defineProperty(ue,ee,D):ue[ee]=H[ee])}return ue.default=H,Z&&Z.set(H,ue),ue}(A("../core/constants")),g=a(A("./GeometryBuilder")),p=a(A("libtess")),n=(A("./p5.Shader"),A("./p5.Camera"),A("../core/p5.Renderer"),A("./p5.Matrix"),A("./p5.Framebuffer"),A("path"),A("./p5.Texture"));function i(){var H;return typeof WeakMap!="function"?null:(H=new WeakMap,i=function(){return H},H)}function a(H){return H&&H.__esModule?H:{default:H}}function h(H){return function(Z){if(Array.isArray(Z)){for(var ee=0,ue=new Array(Z.length);ee>7,127&we,ae>>7,127&ae);for(var Se=0;Se>7,127&Pe,0,0)}}return{cellImageInfo:re,dimOffset:Le,dimImageInfo:xe}}}}]),y}();u.default.RendererGL.prototype._renderText=function(y,b,j,k,E){if(this._textFont&&typeof this._textFont!="string"){if(!(E<=k)&&this._doFill){if(this._isOpenType()){y.push();var E=this._doStroke,M=this.drawMode,P=(this._doStroke=!1,this.drawMode=g.TEXTURE,this._textFont.font),L=(L=this._textFont._fontInfo)||(this._textFont._fontInfo=new f(P)),j=this._textFont._handleAlignment(this,b,j,k),k=this._textSize/P.unitsPerEm,C=(this.translate(j.x,j.y,0),this.scale(k,k,1),this.GL),j=!this._defaultFontShader,I=this._getFontShader(),A=(I.init(),I.bindShader(),j&&(I.setUniform("uGridImageSize",[64,64]),I.setUniform("uCellsImageSize",[64,64]),I.setUniform("uStrokeImageSize",[64,64]),I.setUniform("uGridSize",[9,9])),this._applyColorBlend(this.curFillColor),this.retainedMode.geometry.glyph),N=(A||((k=this._textGeom=new u.default.Geometry(1,1,function(){for(var pe=0;pe<=1;pe++)for(var K=0;K<=1;K++)this.vertices.push(new u.default.Vector(K,pe,0)),this.uvs.push(K,pe)})).computeFaces().computeNormals(),A=this.createBuffers("glyph",k)),!0),j=!1,k=void 0;try{for(var F,B=this.retainedMode.buffers.text[Symbol.iterator]();!(N=(F=B.next()).done);N=!0)F.value._prepareBuffer(A,I)}catch(pe){j=!0,k=pe}finally{try{N||B.return==null||B.return()}finally{if(j)throw k}}this._bindBuffer(A.indexBuffer,C.ELEMENT_ARRAY_BUFFER),I.setUniform("uMaterialColor",this.curFillColor),C.pixelStorei(C.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);try{var q=0,V=null,H=P.stringToGlyphs(b),Z=!0,ee=!1,ue=void 0;try{for(var T,D=H[Symbol.iterator]();!(Z=(T=D.next()).done);Z=!0){var G,W,$=T.value,J=(V&&(q+=P.getKerningValue(V,$)),L.getGlyphInfo($));J.uGlyphRect&&(G=J.rowInfo,W=J.colInfo,I.setUniform("uSamplerStrokes",J.strokeImageInfo.imageData),I.setUniform("uSamplerRowStrokes",G.cellImageInfo.imageData),I.setUniform("uSamplerRows",G.dimImageInfo.imageData),I.setUniform("uSamplerColStrokes",W.cellImageInfo.imageData),I.setUniform("uSamplerCols",W.dimImageInfo.imageData),I.setUniform("uGridOffset",J.uGridOffset),I.setUniform("uGlyphRect",J.uGlyphRect),I.setUniform("uGlyphOffset",q),I.bindTextures(),C.drawElements(C.TRIANGLES,6,this.GL.UNSIGNED_SHORT,0)),q+=$.advanceWidth,V=$}}catch(pe){ee=!0,ue=pe}finally{try{Z||D.return==null||D.return()}finally{if(ee)throw ue}}}finally{I.unbindShader(),this._doStroke=E,this.drawMode=M,C.pixelStorei(C.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),y.pop()}}else console.log("WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts are supported");return y}}else console.log("WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.")}},{"../core/constants":269,"../core/main":280,"./p5.RendererGL.Retained":336,"./p5.Shader":338,"core-js/modules/es.array.iterator":164,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.to-string":187,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.string.iterator":197,"core-js/modules/es.string.split":203,"core-js/modules/es.string.sub":205,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}]},{},[264])(264)})})(nh);var zb=nh.exports;const Lc=Hb(zb),Wb=vn(()=>({provide:{p5:Lc,p5:Lc}})),qb=[Rv,Iv,Q0,eb,tb,Ub,Bb,Vb,Wb],Xb=pr({props:{vnode:{type:Object,required:!0},route:{type:Object,required:!0},vnodeRef:Object,renderKey:String,trackRootNodes:Boolean},setup(r){const d=r.renderKey,w=r.route,t={};for(const x in r.route)Object.defineProperty(t,x,{get:()=>d===r.renderKey?r.route[x]:w[x]});return Wr(ps,as(t)),()=>rr(r.vnode,{ref:r.vnodeRef})}}),Yb=pr({name:"NuxtPage",inheritAttrs:!1,props:{name:{type:String},transition:{type:[Boolean,Object],default:void 0},keepalive:{type:[Boolean,Object],default:void 0},route:{type:Object},pageKey:{type:[Function,String],default:null}},setup(r,{attrs:d,expose:w}){const t=It(),x=mt(),v=Ht(ps,null);let s;w({pageRef:x});const c=Ht(Ef,null);let o;const u=t.deferHydration();if(t.isHydrating){const g=t.hooks.hookOnce("app:error",u);qr().beforeEach(g)}return r.pageKey&&In(()=>r.pageKey,(g,p)=>{g!==p&&t.callHook("page:loading:start")}),()=>rr(th,{name:r.name,route:r.route,...d},{default:g=>{const p=Kb(v,g.route,g.Component),n=v&&v.matched.length===g.route.matched.length;if(!g.Component){if(o&&!n)return o;u();return}if(o&&c&&!c.isCurrent(g.route))return o;if(p&&v&&(!c||c!=null&&c.isCurrent(v)))return n?o:null;const i=Da(g,r.pageKey);!t.isHydrating&&!Zb(v,g.route,g.Component)&&s===i&&t.callHook("page:loading:end"),s=i;const a=!!(r.transition??g.route.meta.pageTransition??Aa),h=a&&$b([r.transition,g.route.meta.pageTransition,Aa,{onAfterLeave:()=>{t.callHook("page:transition:finish",g.Component)}}].filter(Boolean)),m=r.keepalive??g.route.meta.keepalive??Sv;return o=rh(fs,a&&h,G0(m,rr(nl,{suspensible:!0,onPending:()=>t.callHook("page:start",g.Component),onResolve:()=>{Fr(()=>t.callHook("page:finish",g.Component).then(()=>t.callHook("page:loading:end")).finally(u))}},{default:()=>{const l=rr(Xb,{key:i||void 0,vnode:g.Component,route:g.route,renderKey:i||void 0,trackRootNodes:a,vnodeRef:x});return m&&(l.type.name=g.Component.type.name||g.Component.type.__name||"RouteProvider"),l}}))).default(),o}})}});function $b(r){const d=r.map(w=>({...w,onAfterLeave:w.onAfterLeave?bl(w.onAfterLeave):void 0}));return jf(...d)}function Kb(r,d,w){if(!r)return!1;const t=d.matched.findIndex(x=>{var v;return((v=x.components)==null?void 0:v.default)===(w==null?void 0:w.type)});return!t||t===-1?!1:d.matched.slice(0,t).some((x,v)=>{var s,c,o;return((s=x.components)==null?void 0:s.default)!==((o=(c=r.matched[v])==null?void 0:c.components)==null?void 0:o.default)})||w&&Da({route:d,Component:w})!==Da({route:r,Component:w})}function Zb(r,d,w){return r?d.matched.findIndex(x=>{var v;return((v=x.components)==null?void 0:v.default)===(w==null?void 0:w.type)})t.default||t);return()=>rr(w,r.layoutProps,d.slots)}}),Jb=pr({name:"NuxtLayout",inheritAttrs:!1,props:{name:{type:[String,Boolean,Object],default:null},fallback:{type:[String,Object],default:null}},setup(r,d){const w=It(),t=Ht(ps),x=t===mi()?U0():t,v=jt(()=>{let o=Bt(r.name)??x.meta.layout??"default";return o&&!(o in Pn)&&r.fallback&&(o=Bt(r.fallback)),o}),s=mt();d.expose({layoutRef:s});const c=w.deferHydration();if(w.isHydrating){const o=w.hooks.hookOnce("app:error",c);qr().beforeEach(o)}return()=>{const o=v.value&&v.value in Pn,u=x.meta.layoutTransition??jv;return rh(fs,o&&u,{default:()=>rr(nl,{suspensible:!0,onResolve:()=>{Fr(c)}},{default:()=>rr(e1,{layoutProps:ef(d.attrs,{ref:s}),key:v.value||void 0,name:v.value,shouldProvide:!r.name,hasTransition:!!u},d.slots)})}).default()}}}),e1=pr({name:"NuxtLayoutProvider",inheritAttrs:!1,props:{name:{type:[String,Boolean]},layoutProps:{type:Object},hasTransition:{type:Boolean},shouldProvide:{type:Boolean}},setup(r,d){const w=r.name;return r.shouldProvide&&Wr(Ef,{isCurrent:t=>w===(t.meta.layout??"default")}),()=>{var t,x;return!w||typeof w=="string"&&!(w in Pn)?(x=(t=d.slots).default)==null?void 0:x.call(t):rr(Qb,{key:w,layoutProps:r.layoutProps,name:w},d.slots)}}}),t1={class:"bg-background"},r1=pr({__name:"app",setup(r){return _v({title:"Colton Padden",ogTitle:"Colton Padden",description:"This is where you can find the blog, portfolio, and experiments of Colton Padden.",ogDescription:"This is where you can find the blog, portfolio, and experiments of Colton Padden."}),(d,w)=>{const t=Yb,x=Jb;return Gr(),ci("body",t1,[pt(x,null,{default:Ur(()=>[pt(t)]),_:1})])}}});async function oh(r,d=qr()){const{path:w,matched:t}=d.resolve(r);if(!t.length||(d._routePreloaded||(d._routePreloaded=new Set),d._routePreloaded.has(w)))return;const x=d._preloadPromises=d._preloadPromises||[];if(x.length>4)return Promise.all(x).then(()=>oh(r,d));d._routePreloaded.add(w);const v=t.map(s=>{var c;return(c=s.components)==null?void 0:c.default}).filter(s=>typeof s=="function");for(const s of v){const c=Promise.resolve(s()).catch(()=>{}).finally(()=>x.splice(x.indexOf(c)));x.push(c)}await Promise.all(x)}const n1=(...r)=>r.find(d=>d!==void 0);function o1(r){const d=r.componentName||"NuxtLink";function w(t,x){if(!t||r.trailingSlash!=="append"&&r.trailingSlash!=="remove")return t;if(typeof t=="string")return Ic(t,r.trailingSlash);const v="path"in t&&t.path!==void 0?t.path:x(t).path;return{...t,name:void 0,path:Ic(v,r.trailingSlash)}}return pr({name:d,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1}},setup(t,{slots:x}){const v=qr(),s=pi(),c=jt(()=>{const a=t.to||t.href||"";return w(a,v.resolve)}),o=jt(()=>typeof c.value=="string"&&gn(c.value,{acceptRelative:!0})),u=jt(()=>t.target&&t.target!=="_self"),g=jt(()=>t.external||u.value?!0:typeof c.value=="object"?!1:c.value===""||o.value),p=mt(!1),n=mt(null),i=a=>{var h;n.value=t.custom?(h=a==null?void 0:a.$el)==null?void 0:h.nextElementSibling:a==null?void 0:a.$el};if(t.prefetch!==!1&&t.noPrefetch!==!0&&t.target!=="_blank"&&!a1()){const h=It();let m,l=null;Qr(()=>{const f=i1();_l(()=>{m=Fa(()=>{var y;(y=n==null?void 0:n.value)!=null&&y.tagName&&(l=f.observe(n.value,async()=>{l==null||l(),l=null;const b=typeof c.value=="string"?c.value:v.resolve(c.value).fullPath;await Promise.all([h.hooks.callHook("link:prefetch",b).catch(()=>{}),!g.value&&oh(c.value,v).catch(()=>{})]),p.value=!0}))})})}),ls(()=>{m&&J0(m),l==null||l(),l=null})}return()=>{var l,f;if(!g.value){const y={ref:i,to:c.value,activeClass:t.activeClass||r.activeClass,exactActiveClass:t.exactActiveClass||r.exactActiveClass,replace:t.replace,ariaCurrentValue:t.ariaCurrentValue,custom:t.custom};return t.custom||(p.value&&(y.class=t.prefetchedClass||r.prefetchedClass),y.rel=t.rel||void 0),rr(Lp("RouterLink"),y,x.default)}const a=typeof c.value=="object"?((l=v.resolve(c.value))==null?void 0:l.href)??null:c.value&&!t.external&&!o.value?w(hi(s.app.baseURL,c.value),v.resolve):c.value||null,h=t.target||null,m=n1(t.noRel?"":t.rel,r.externalRelAttribute,o.value||u.value?"noopener noreferrer":"")||null;if(t.custom){if(!x.default)return null;const y=()=>Eg(a,{replace:t.replace,external:t.external});return x.default({href:a,navigate:y,get route(){if(!a)return;const b=hs(a);return{path:b.pathname,fullPath:b.pathname,get query(){return cf(b.search)},hash:b.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:a}},rel:m,target:h,isExternal:g.value,isActive:!1,isExactActive:!1})}return rr("a",{ref:n,href:a,rel:m,target:h},(f=x.default)==null?void 0:f.call(x))}}})}const s1=o1(Ev);function Ic(r,d){const w=d==="append"?Qs:fi;return gn(r)&&!r.startsWith("http")?r:w(r,!0)}function i1(){const r=It();if(r._observer)return r._observer;let d=null;const w=new Map,t=(v,s)=>(d||(d=new IntersectionObserver(c=>{for(const o of c){const u=w.get(o.target);(o.isIntersecting||o.intersectionRatio>0)&&u&&u()}})),w.set(v,s),d.observe(v),()=>{w.delete(v),d.unobserve(v),w.size===0&&(d.disconnect(),d=null)});return r._observer={observe:t}}function a1(){const r=navigator.connection;return!!(r&&(r.saveData||/2g/.test(r.effectiveType)))}let l1=Symbol("headlessui.useid"),u1=0;function _i(){return Ht(l1,()=>`${++u1}`)()}function Ft(r){var d;if(r==null||r.value==null)return null;let w=(d=r.value.$el)!=null?d:r.value;return w instanceof Node?w:null}function Qn(r,d,...w){if(r in d){let x=d[r];return typeof x=="function"?x(...w):x}let t=new Error(`Tried to handle "${r}" but there is no handler defined. Only defined handlers are: ${Object.keys(d).map(x=>`"${x}"`).join(", ")}.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,Qn),t}var c1=Object.defineProperty,d1=(r,d,w)=>d in r?c1(r,d,{enumerable:!0,configurable:!0,writable:!0,value:w}):r[d]=w,Dc=(r,d,w)=>(d1(r,typeof d!="symbol"?d+"":d,w),w);let f1=class{constructor(){Dc(this,"current",this.detect()),Dc(this,"currentId",0)}set(d){this.current!==d&&(this.currentId=0,this.current=d)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return this.current==="server"}get isClient(){return this.current==="client"}detect(){return typeof window>"u"||typeof document>"u"?"server":"client"}},wi=new f1;function wl(r){if(wi.isServer)return null;if(r instanceof Node)return r.ownerDocument;if(r!=null&&r.hasOwnProperty("value")){let d=Ft(r);if(d)return d.ownerDocument}return document}let Na=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(r=>`${r}:not([tabindex='-1'])`).join(",");var Ua=(r=>(r[r.First=1]="First",r[r.Previous=2]="Previous",r[r.Next=4]="Next",r[r.Last=8]="Last",r[r.WrapAround=16]="WrapAround",r[r.NoScroll=32]="NoScroll",r))(Ua||{}),h1=(r=>(r[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r))(h1||{}),p1=(r=>(r[r.Previous=-1]="Previous",r[r.Next=1]="Next",r))(p1||{});function sh(r=document.body){return r==null?[]:Array.from(r.querySelectorAll(Na)).sort((d,w)=>Math.sign((d.tabIndex||Number.MAX_SAFE_INTEGER)-(w.tabIndex||Number.MAX_SAFE_INTEGER)))}var xl=(r=>(r[r.Strict=0]="Strict",r[r.Loose=1]="Loose",r))(xl||{});function jl(r,d=0){var w;return r===((w=wl(r))==null?void 0:w.body)?!1:Qn(d,{0(){return r.matches(Na)},1(){let t=r;for(;t!==null;){if(t.matches(Na))return!0;t=t.parentElement}return!1}})}function ih(r){let d=wl(r);Fr(()=>{d&&!jl(d.activeElement,0)&&y1(r)})}var m1=(r=>(r[r.Keyboard=0]="Keyboard",r[r.Mouse=1]="Mouse",r))(m1||{});typeof window<"u"&&typeof document<"u"&&(document.addEventListener("keydown",r=>{r.metaKey||r.altKey||r.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",r=>{r.detail===1?delete document.documentElement.dataset.headlessuiFocusVisible:r.detail===0&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0));function y1(r){r==null||r.focus({preventScroll:!0})}let g1=["textarea","input"].join(",");function v1(r){var d,w;return(w=(d=r==null?void 0:r.matches)==null?void 0:d.call(r,g1))!=null?w:!1}function ah(r,d=w=>w){return r.slice().sort((w,t)=>{let x=d(w),v=d(t);if(x===null||v===null)return 0;let s=x.compareDocumentPosition(v);return s&Node.DOCUMENT_POSITION_FOLLOWING?-1:s&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function b1(r,d){return _1(sh(),d,{relativeTo:r})}function _1(r,d,{sorted:w=!0,relativeTo:t=null,skipElements:x=[]}={}){var v;let s=(v=Array.isArray(r)?r.length>0?r[0].ownerDocument:document:r==null?void 0:r.ownerDocument)!=null?v:document,c=Array.isArray(r)?w?ah(r):r:sh(r);x.length>0&&c.length>1&&(c=c.filter(a=>!x.includes(a))),t=t??s.activeElement;let o=(()=>{if(d&5)return 1;if(d&10)return-1;throw new Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),u=(()=>{if(d&1)return 0;if(d&2)return Math.max(0,c.indexOf(t))-1;if(d&4)return Math.max(0,c.indexOf(t))+1;if(d&8)return c.length-1;throw new Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),g=d&32?{preventScroll:!0}:{},p=0,n=c.length,i;do{if(p>=n||p+n<=0)return 0;let a=u+p;if(d&16)a=(a+n)%n;else{if(a<0)return 3;if(a>=n)return 1}i=c[a],i==null||i.focus(g),p+=o}while(i!==s.activeElement);return d&6&&v1(i)&&i.select(),2}function w1(){return/iPhone/gi.test(window.navigator.platform)||/Mac/gi.test(window.navigator.platform)&&window.navigator.maxTouchPoints>0}function x1(){return/Android/gi.test(window.navigator.userAgent)}function j1(){return w1()||x1()}function Is(r,d,w){wi.isServer||ln(t=>{document.addEventListener(r,d,w),t(()=>document.removeEventListener(r,d,w))})}function S1(r,d,w){wi.isServer||ln(t=>{window.addEventListener(r,d,w),t(()=>window.removeEventListener(r,d,w))})}function E1(r,d,w=jt(()=>!0)){function t(v,s){if(!w.value||v.defaultPrevented)return;let c=s(v);if(c===null||!c.getRootNode().contains(c))return;let o=function u(g){return typeof g=="function"?u(g()):Array.isArray(g)||g instanceof Set?g:[g]}(r);for(let u of o){if(u===null)continue;let g=u instanceof HTMLElement?u:Ft(u);if(g!=null&&g.contains(c)||v.composed&&v.composedPath().includes(g))return}return!jl(c,xl.Loose)&&c.tabIndex!==-1&&v.preventDefault(),d(v,c)}let x=mt(null);Is("pointerdown",v=>{var s,c;w.value&&(x.value=((c=(s=v.composedPath)==null?void 0:s.call(v))==null?void 0:c[0])||v.target)},!0),Is("mousedown",v=>{var s,c;w.value&&(x.value=((c=(s=v.composedPath)==null?void 0:s.call(v))==null?void 0:c[0])||v.target)},!0),Is("click",v=>{j1()||x.value&&(t(v,()=>x.value),x.value=null)},!0),Is("touchend",v=>t(v,()=>v.target instanceof HTMLElement?v.target:null),!0),S1("blur",v=>t(v,()=>window.document.activeElement instanceof HTMLIFrameElement?window.document.activeElement:null),!0)}function Fc(r,d){if(r)return r;let w=d??"button";if(typeof w=="string"&&w.toLowerCase()==="button")return"button"}function T1(r,d){let w=mt(Fc(r.value.type,r.value.as));return Qr(()=>{w.value=Fc(r.value.type,r.value.as)}),ln(()=>{var t;w.value||Ft(d)&&Ft(d)instanceof HTMLButtonElement&&!((t=Ft(d))!=null&&t.hasAttribute("type"))&&(w.value="button")}),w}let Nc=/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g;function Uc(r){var d,w;let t=(d=r.innerText)!=null?d:"",x=r.cloneNode(!0);if(!(x instanceof HTMLElement))return t;let v=!1;for(let c of x.querySelectorAll('[hidden],[aria-hidden],[role="img"]'))c.remove(),v=!0;let s=v?(w=x.innerText)!=null?w:"":t;return Nc.test(s)&&(s=s.replace(Nc,"")),s}function k1(r){let d=r.getAttribute("aria-label");if(typeof d=="string")return d.trim();let w=r.getAttribute("aria-labelledby");if(w){let t=w.split(" ").map(x=>{let v=document.getElementById(x);if(v){let s=v.getAttribute("aria-label");return typeof s=="string"?s.trim():Uc(v).trim()}return null}).filter(Boolean);if(t.length>0)return t.join(", ")}return Uc(r).trim()}function M1(r){let d=mt(""),w=mt("");return()=>{let t=Ft(r);if(!t)return"";let x=t.innerText;if(d.value===x)return w.value;let v=k1(t).trim().toLowerCase();return d.value=x,w.value=v,v}}function Bc(r){return[r.screenX,r.screenY]}function C1(){let r=mt([-1,-1]);return{wasMoved(d){let w=Bc(d);return r.value[0]===w[0]&&r.value[1]===w[1]?!1:(r.value=w,!0)},update(d){r.value=Bc(d)}}}function O1({container:r,accept:d,walk:w,enabled:t}){ln(()=>{let x=r.value;if(!x||t!==void 0&&!t.value)return;let v=wl(r);if(!v)return;let s=Object.assign(o=>d(o),{acceptNode:d}),c=v.createTreeWalker(x,NodeFilter.SHOW_ELEMENT,s,!1);for(;c.nextNode();)w(c.currentNode)})}let lh=Symbol("Context");var Ir=(r=>(r[r.Open=1]="Open",r[r.Closed=2]="Closed",r[r.Closing=4]="Closing",r[r.Opening=8]="Opening",r))(Ir||{});function P1(){return Sl()!==null}function Sl(){return Ht(lh,null)}function uh(r){Wr(lh,r)}var ir=(r=>(r.Space=" ",r.Enter="Enter",r.Escape="Escape",r.Backspace="Backspace",r.Delete="Delete",r.ArrowLeft="ArrowLeft",r.ArrowUp="ArrowUp",r.ArrowRight="ArrowRight",r.ArrowDown="ArrowDown",r.Home="Home",r.End="End",r.PageUp="PageUp",r.PageDown="PageDown",r.Tab="Tab",r))(ir||{});function A1(r){throw new Error("Unexpected object: "+r)}var Dr=(r=>(r[r.First=0]="First",r[r.Previous=1]="Previous",r[r.Next=2]="Next",r[r.Last=3]="Last",r[r.Specific=4]="Specific",r[r.Nothing=5]="Nothing",r))(Dr||{});function R1(r,d){let w=d.resolveItems();if(w.length<=0)return null;let t=d.resolveActiveIndex(),x=t??-1;switch(r.focus){case 0:{for(let v=0;v=0;--v)if(!d.resolveDisabled(w[v],v,w))return v;return t}case 2:{for(let v=x+1;v=0;--v)if(!d.resolveDisabled(w[v],v,w))return v;return t}case 4:{for(let v=0;v(r[r.None=0]="None",r[r.RenderStrategy=1]="RenderStrategy",r[r.Static=2]="Static",r))(ni||{}),An=(r=>(r[r.Unmount=0]="Unmount",r[r.Hidden=1]="Hidden",r))(An||{});function To({visible:r=!0,features:d=0,ourProps:w,theirProps:t,...x}){var v;let s=dh(t,w),c=Object.assign(x,{props:s});if(r||d&2&&s.static)return ra(c);if(d&1){let o=(v=s.unmount)==null||v?0:1;return Qn(o,{0(){return null},1(){return ra({...x,props:{...s,hidden:!0,style:{display:"none"}}})}})}return ra(c)}function ra({props:r,attrs:d,slots:w,slot:t,name:x}){var v,s;let{as:c,...o}=fh(r,["unmount","static"]),u=(v=w.default)==null?void 0:v.call(w,t),g={};if(t){let p=!1,n=[];for(let[i,a]of Object.entries(t))typeof a=="boolean"&&(p=!0),a===!0&&n.push(i);p&&(g["data-headlessui-state"]=n.join(" "))}if(c==="template"){if(u=ch(u??[]),Object.keys(o).length>0||Object.keys(d).length>0){let[p,...n]=u??[];if(!L1(p)||n.length>0)throw new Error(['Passing props on "template"!',"",`The current component <${x} /> is rendering a "template".`,"However we need to passthrough the following props:",Object.keys(o).concat(Object.keys(d)).map(h=>h.trim()).filter((h,m,l)=>l.indexOf(h)===m).sort((h,m)=>h.localeCompare(m)).map(h=>` - ${h}`).join(` +`)),G}},{key:"_getEmptyTexture",value:function(){var T;return this._emptyTexture||((T=new o.default.Image(1,1)).set(0,0,255),this._emptyTexture=new o.default.Texture(this,T)),this._emptyTexture}},{key:"getTexture",value:function(T){T instanceof o.default.Framebuffer&&(T=T.color);var D=this.textures.get(T);return D||(D=new o.default.Texture(this,T),this.textures.set(T,D),D)}},{key:"getDiffusedTexture",value:function(T){var D,G,W=this;return this.diffusedTextures.get(T)!=null?this.diffusedTextures.get(T):(D=Math.floor(T.height/T.width*200),G=this._pInst.createFramebuffer({width:200,height:D,density:1}),this.diffusedShader||(this.diffusedShader=this._pInst.createShader(N.imageLightVert,N.imageLightDiffusedFrag)),G.draw(function(){W._pInst.shader(W.diffusedShader),W.diffusedShader.setUniform("environmentMap",T),W._pInst.noStroke(),W._pInst.rectMode(u.CENTER),W._pInst.noLights(),W._pInst.rect(0,0,200,D)}),this.diffusedTextures.set(T,G),G)}},{key:"getSpecularTexture",value:function(T){var D=this;if(this.specularTextures.get(T)!=null)return this.specularTextures.get(T);for(var G,W=[],$=this._pInst.createFramebuffer({width:512,height:512,density:1}),J=Math.log(512)/Math.log(2),ne=(this.specularShader||(this.specularShader=this._pInst.createShader(N.imageLightVert,N.imageLightSpecularFrag)),512);1<=ne;ne/=2)(function(ce){$.resize(ce,ce);var ie=1-Math.log(ce)/Math.log(2)/J;$.draw(function(){D._pInst.shader(D.specularShader),D._pInst.clear(),D.specularShader.setUniform("environmentMap",T),D.specularShader.setUniform("roughness",ie),D._pInst.noStroke(),D._pInst.noLights(),D._pInst.plane(ce,ce)}),W.push($.get().drawingContext.getImageData(0,0,ce,ce))})(ne);return $.remove(),G=new n.MipmapTexture(this,W,{}),this.specularTextures.set(T,G),G}},{key:"activeFramebuffer",value:function(){return this.activeFramebuffers[this.activeFramebuffers.length-1]||null}},{key:"createFramebuffer",value:function(T){return new o.default.Framebuffer(this,T)}},{key:"_setStrokeUniforms",value:function(T){T.bindShader(),T.setUniform("uUseLineColor",this._useLineColor),T.setUniform("uMaterialColor",this.curStrokeColor),T.setUniform("uStrokeWeight",this.curStrokeWeight),T.setUniform("uStrokeCap",L[this.curStrokeCap]),T.setUniform("uStrokeJoin",C[this.curStrokeJoin])}},{key:"_setFillUniforms",value:function(T){var D=this,G=(T.bindShader(),this.mixedSpecularColor=h(this.curSpecularColor),0>7,127&we,ae>>7,127&ae);for(var Se=0;Se>7,127&Pe,0,0)}}return{cellImageInfo:re,dimOffset:Le,dimImageInfo:xe}}}}]),m}();u.default.RendererGL.prototype._renderText=function(m,b,j,k,E){if(this._textFont&&typeof this._textFont!="string"){if(!(E<=k)&&this._doFill){if(this._isOpenType()){m.push();var E=this._doStroke,M=this.drawMode,P=(this._doStroke=!1,this.drawMode=g.TEXTURE,this._textFont.font),L=(L=this._textFont._fontInfo)||(this._textFont._fontInfo=new f(P)),j=this._textFont._handleAlignment(this,b,j,k),k=this._textSize/P.unitsPerEm,C=(this.translate(j.x,j.y,0),this.scale(k,k,1),this.GL),j=!this._defaultFontShader,I=this._getFontShader(),A=(I.init(),I.bindShader(),j&&(I.setUniform("uGridImageSize",[64,64]),I.setUniform("uCellsImageSize",[64,64]),I.setUniform("uStrokeImageSize",[64,64]),I.setUniform("uGridSize",[9,9])),this._applyColorBlend(this.curFillColor),this.retainedMode.geometry.glyph),N=(A||((k=this._textGeom=new u.default.Geometry(1,1,function(){for(var pe=0;pe<=1;pe++)for(var K=0;K<=1;K++)this.vertices.push(new u.default.Vector(K,pe,0)),this.uvs.push(K,pe)})).computeFaces().computeNormals(),A=this.createBuffers("glyph",k)),!0),j=!1,k=void 0;try{for(var F,B=this.retainedMode.buffers.text[Symbol.iterator]();!(N=(F=B.next()).done);N=!0)F.value._prepareBuffer(A,I)}catch(pe){j=!0,k=pe}finally{try{N||B.return==null||B.return()}finally{if(j)throw k}}this._bindBuffer(A.indexBuffer,C.ELEMENT_ARRAY_BUFFER),I.setUniform("uMaterialColor",this.curFillColor),C.pixelStorei(C.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);try{var q=0,V=null,H=P.stringToGlyphs(b),Z=!0,ee=!1,ue=void 0;try{for(var T,D=H[Symbol.iterator]();!(Z=(T=D.next()).done);Z=!0){var G,W,$=T.value,J=(V&&(q+=P.getKerningValue(V,$)),L.getGlyphInfo($));J.uGlyphRect&&(G=J.rowInfo,W=J.colInfo,I.setUniform("uSamplerStrokes",J.strokeImageInfo.imageData),I.setUniform("uSamplerRowStrokes",G.cellImageInfo.imageData),I.setUniform("uSamplerRows",G.dimImageInfo.imageData),I.setUniform("uSamplerColStrokes",W.cellImageInfo.imageData),I.setUniform("uSamplerCols",W.dimImageInfo.imageData),I.setUniform("uGridOffset",J.uGridOffset),I.setUniform("uGlyphRect",J.uGlyphRect),I.setUniform("uGlyphOffset",q),I.bindTextures(),C.drawElements(C.TRIANGLES,6,this.GL.UNSIGNED_SHORT,0)),q+=$.advanceWidth,V=$}}catch(pe){ee=!0,ue=pe}finally{try{Z||D.return==null||D.return()}finally{if(ee)throw ue}}}finally{I.unbindShader(),this._doStroke=E,this.drawMode=M,C.pixelStorei(C.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),m.pop()}}else console.log("WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts are supported");return m}}else console.log("WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.")}},{"../core/constants":269,"../core/main":280,"./p5.RendererGL.Retained":336,"./p5.Shader":338,"core-js/modules/es.array.iterator":164,"core-js/modules/es.object.get-own-property-descriptor":183,"core-js/modules/es.object.to-string":187,"core-js/modules/es.regexp.exec":192,"core-js/modules/es.string.iterator":197,"core-js/modules/es.string.split":203,"core-js/modules/es.string.sub":205,"core-js/modules/es.symbol":209,"core-js/modules/es.symbol.description":207,"core-js/modules/es.symbol.iterator":208,"core-js/modules/es.weak-map":241,"core-js/modules/web.dom-collections.iterator":243}]},{},[264])(264)})})(oh);var qb=oh.exports;const Rc=Wb(qb),Xb=vn(()=>({provide:{p5:Rc,p5:Rc}})),Yb=[Iv,Fv,eb,rb,nb,Gb,Vb,zb,Xb],$b=pr({props:{vnode:{type:Object,required:!0},route:{type:Object,required:!0},vnodeRef:Object,renderKey:String,trackRootNodes:Boolean},setup(r){const d=r.renderKey,w=r.route,t={};for(const x in r.route)Object.defineProperty(t,x,{get:()=>d===r.renderKey?r.route[x]:w[x]});return Wr(ps,as(t)),()=>rr(r.vnode,{ref:r.vnodeRef})}}),Kb=pr({name:"NuxtPage",inheritAttrs:!1,props:{name:{type:String},transition:{type:[Boolean,Object],default:void 0},keepalive:{type:[Boolean,Object],default:void 0},route:{type:Object},pageKey:{type:[Function,String],default:null}},setup(r,{attrs:d,expose:w}){const t=It(),x=mt(),v=Ht(ps,null);let s;w({pageRef:x});const c=Ht(Tf,null);let o;const u=t.deferHydration();if(t.isHydrating){const g=t.hooks.hookOnce("app:error",u);qr().beforeEach(g)}return r.pageKey&&In(()=>r.pageKey,(g,p)=>{g!==p&&t.callHook("page:loading:start")}),()=>rr(rh,{name:r.name,route:r.route,...d},{default:g=>{const p=Qb(v,g.route,g.Component),n=v&&v.matched.length===g.route.matched.length;if(!g.Component){if(o&&!n)return o;u();return}if(o&&c&&!c.isCurrent(g.route))return o;if(p&&v&&(!c||c!=null&&c.isCurrent(v)))return n?o:null;const i=Da(g,r.pageKey);!t.isHydrating&&!Jb(v,g.route,g.Component)&&s===i&&t.callHook("page:loading:end"),s=i;const a=!!(r.transition??g.route.meta.pageTransition??Aa),h=a&&Zb([r.transition,g.route.meta.pageTransition,Aa,{onAfterLeave:()=>{t.callHook("page:transition:finish",g.Component)}}].filter(Boolean)),y=r.keepalive??g.route.meta.keepalive??Tv;return o=nh(fs,a&&h,H0(y,rr(nl,{suspensible:!0,onPending:()=>t.callHook("page:start",g.Component),onResolve:()=>{Fr(()=>t.callHook("page:finish",g.Component).then(()=>t.callHook("page:loading:end")).finally(u))}},{default:()=>{const l=rr($b,{key:i||void 0,vnode:g.Component,route:g.route,renderKey:i||void 0,trackRootNodes:a,vnodeRef:x});return y&&(l.type.name=g.Component.type.name||g.Component.type.__name||"RouteProvider"),l}}))).default(),o}})}});function Zb(r){const d=r.map(w=>({...w,onAfterLeave:w.onAfterLeave?vl(w.onAfterLeave):void 0}));return Sf(...d)}function Qb(r,d,w){if(!r)return!1;const t=d.matched.findIndex(x=>{var v;return((v=x.components)==null?void 0:v.default)===(w==null?void 0:w.type)});return!t||t===-1?!1:d.matched.slice(0,t).some((x,v)=>{var s,c,o;return((s=x.components)==null?void 0:s.default)!==((o=(c=r.matched[v])==null?void 0:c.components)==null?void 0:o.default)})||w&&Da({route:d,Component:w})!==Da({route:r,Component:w})}function Jb(r,d,w){return r?d.matched.findIndex(x=>{var v;return((v=x.components)==null?void 0:v.default)===(w==null?void 0:w.type)})t.default||t);return()=>rr(w,r.layoutProps,d.slots)}}),t1=pr({name:"NuxtLayout",inheritAttrs:!1,props:{name:{type:[String,Boolean,Object],default:null},fallback:{type:[String,Object],default:null}},setup(r,d){const w=It(),t=Ht(ps),x=t===mi()?G0():t,v=jt(()=>{let o=Bt(r.name)??x.meta.layout??"default";return o&&!(o in Pn)&&r.fallback&&(o=Bt(r.fallback)),o}),s=mt();d.expose({layoutRef:s});const c=w.deferHydration();if(w.isHydrating){const o=w.hooks.hookOnce("app:error",c);qr().beforeEach(o)}return()=>{const o=v.value&&v.value in Pn,u=x.meta.layoutTransition??Ev;return nh(fs,o&&u,{default:()=>rr(nl,{suspensible:!0,onResolve:()=>{Fr(c)}},{default:()=>rr(r1,{layoutProps:tf(d.attrs,{ref:s}),key:v.value||void 0,name:v.value,shouldProvide:!r.name,hasTransition:!!u},d.slots)})}).default()}}}),r1=pr({name:"NuxtLayoutProvider",inheritAttrs:!1,props:{name:{type:[String,Boolean]},layoutProps:{type:Object},hasTransition:{type:Boolean},shouldProvide:{type:Boolean}},setup(r,d){const w=r.name;return r.shouldProvide&&Wr(Tf,{isCurrent:t=>w===(t.meta.layout??"default")}),()=>{var t,x;return!w||typeof w=="string"&&!(w in Pn)?(x=(t=d.slots).default)==null?void 0:x.call(t):rr(e1,{key:w,layoutProps:r.layoutProps,name:w},d.slots)}}}),n1={class:"bg-background"},o1=pr({__name:"app",setup(r){return xv({title:"Colton Padden",ogTitle:"Colton Padden",description:"This is where you can find the blog, portfolio, and experiments of Colton Padden.",ogDescription:"This is where you can find the blog, portfolio, and experiments of Colton Padden."}),(d,w)=>{const t=Kb,x=t1;return Gr(),ci("body",n1,[pt(x,null,{default:Ur(()=>[pt(t)]),_:1})])}}});async function sh(r,d=qr()){const{path:w,matched:t}=d.resolve(r);if(!t.length||(d._routePreloaded||(d._routePreloaded=new Set),d._routePreloaded.has(w)))return;const x=d._preloadPromises=d._preloadPromises||[];if(x.length>4)return Promise.all(x).then(()=>sh(r,d));d._routePreloaded.add(w);const v=t.map(s=>{var c;return(c=s.components)==null?void 0:c.default}).filter(s=>typeof s=="function");for(const s of v){const c=Promise.resolve(s()).catch(()=>{}).finally(()=>x.splice(x.indexOf(c)));x.push(c)}await Promise.all(x)}const s1=(...r)=>r.find(d=>d!==void 0);function i1(r){const d=r.componentName||"NuxtLink";function w(t,x){if(!t||r.trailingSlash!=="append"&&r.trailingSlash!=="remove")return t;if(typeof t=="string")return Lc(t,r.trailingSlash);const v="path"in t&&t.path!==void 0?t.path:x(t).path;return{...t,name:void 0,path:Lc(v,r.trailingSlash)}}return pr({name:d,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1}},setup(t,{slots:x}){const v=qr(),s=pi(),c=jt(()=>{const a=t.to||t.href||"";return w(a,v.resolve)}),o=jt(()=>typeof c.value=="string"&&gn(c.value,{acceptRelative:!0})),u=jt(()=>t.target&&t.target!=="_self"),g=jt(()=>t.external||u.value?!0:typeof c.value=="object"?!1:c.value===""||o.value),p=mt(!1),n=mt(null),i=a=>{var h;n.value=t.custom?(h=a==null?void 0:a.$el)==null?void 0:h.nextElementSibling:a==null?void 0:a.$el};if(t.prefetch!==!1&&t.noPrefetch!==!0&&t.target!=="_blank"&&!u1()){const h=It();let y,l=null;Qr(()=>{const f=l1();bl(()=>{y=Fa(()=>{var m;(m=n==null?void 0:n.value)!=null&&m.tagName&&(l=f.observe(n.value,async()=>{l==null||l(),l=null;const b=typeof c.value=="string"?c.value:v.resolve(c.value).fullPath;await Promise.all([h.hooks.callHook("link:prefetch",b).catch(()=>{}),!g.value&&sh(c.value,v).catch(()=>{})]),p.value=!0}))})})}),ls(()=>{y&&tb(y),l==null||l(),l=null})}return()=>{var l,f;if(!g.value){const m={ref:i,to:c.value,activeClass:t.activeClass||r.activeClass,exactActiveClass:t.exactActiveClass||r.exactActiveClass,replace:t.replace,ariaCurrentValue:t.ariaCurrentValue,custom:t.custom};return t.custom||(p.value&&(m.class=t.prefetchedClass||r.prefetchedClass),m.rel=t.rel||void 0),rr(Dp("RouterLink"),m,x.default)}const a=typeof c.value=="object"?((l=v.resolve(c.value))==null?void 0:l.href)??null:c.value&&!t.external&&!o.value?w(hi(s.app.baseURL,c.value),v.resolve):c.value||null,h=t.target||null,y=s1(t.noRel?"":t.rel,r.externalRelAttribute,o.value||u.value?"noopener noreferrer":"")||null;if(t.custom){if(!x.default)return null;const m=()=>kg(a,{replace:t.replace,external:t.external});return x.default({href:a,navigate:m,get route(){if(!a)return;const b=hs(a);return{path:b.pathname,fullPath:b.pathname,get query(){return df(b.search)},hash:b.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:a}},rel:y,target:h,isExternal:g.value,isActive:!1,isExactActive:!1})}return rr("a",{ref:n,href:a,rel:y,target:h},(f=x.default)==null?void 0:f.call(x))}}})}const a1=i1(kv);function Lc(r,d){const w=d==="append"?Qs:fi;return gn(r)&&!r.startsWith("http")?r:w(r,!0)}function l1(){const r=It();if(r._observer)return r._observer;let d=null;const w=new Map,t=(v,s)=>(d||(d=new IntersectionObserver(c=>{for(const o of c){const u=w.get(o.target);(o.isIntersecting||o.intersectionRatio>0)&&u&&u()}})),w.set(v,s),d.observe(v),()=>{w.delete(v),d.unobserve(v),w.size===0&&(d.disconnect(),d=null)});return r._observer={observe:t}}function u1(){const r=navigator.connection;return!!(r&&(r.saveData||/2g/.test(r.effectiveType)))}let c1=Symbol("headlessui.useid"),d1=0;function _i(){return Ht(c1,()=>`${++d1}`)()}function Ft(r){var d;if(r==null||r.value==null)return null;let w=(d=r.value.$el)!=null?d:r.value;return w instanceof Node?w:null}function Jn(r,d,...w){if(r in d){let x=d[r];return typeof x=="function"?x(...w):x}let t=new Error(`Tried to handle "${r}" but there is no handler defined. Only defined handlers are: ${Object.keys(d).map(x=>`"${x}"`).join(", ")}.`);throw Error.captureStackTrace&&Error.captureStackTrace(t,Jn),t}var f1=Object.defineProperty,h1=(r,d,w)=>d in r?f1(r,d,{enumerable:!0,configurable:!0,writable:!0,value:w}):r[d]=w,Ic=(r,d,w)=>(h1(r,typeof d!="symbol"?d+"":d,w),w);let p1=class{constructor(){Ic(this,"current",this.detect()),Ic(this,"currentId",0)}set(d){this.current!==d&&(this.currentId=0,this.current=d)}reset(){this.set(this.detect())}nextId(){return++this.currentId}get isServer(){return this.current==="server"}get isClient(){return this.current==="client"}detect(){return typeof window>"u"||typeof document>"u"?"server":"client"}},wi=new p1;function _l(r){if(wi.isServer)return null;if(r instanceof Node)return r.ownerDocument;if(r!=null&&r.hasOwnProperty("value")){let d=Ft(r);if(d)return d.ownerDocument}return document}let Na=["[contentEditable=true]","[tabindex]","a[href]","area[href]","button:not([disabled])","iframe","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].map(r=>`${r}:not([tabindex='-1'])`).join(",");var Ua=(r=>(r[r.First=1]="First",r[r.Previous=2]="Previous",r[r.Next=4]="Next",r[r.Last=8]="Last",r[r.WrapAround=16]="WrapAround",r[r.NoScroll=32]="NoScroll",r))(Ua||{}),m1=(r=>(r[r.Error=0]="Error",r[r.Overflow=1]="Overflow",r[r.Success=2]="Success",r[r.Underflow=3]="Underflow",r))(m1||{}),y1=(r=>(r[r.Previous=-1]="Previous",r[r.Next=1]="Next",r))(y1||{});function ih(r=document.body){return r==null?[]:Array.from(r.querySelectorAll(Na)).sort((d,w)=>Math.sign((d.tabIndex||Number.MAX_SAFE_INTEGER)-(w.tabIndex||Number.MAX_SAFE_INTEGER)))}var wl=(r=>(r[r.Strict=0]="Strict",r[r.Loose=1]="Loose",r))(wl||{});function xl(r,d=0){var w;return r===((w=_l(r))==null?void 0:w.body)?!1:Jn(d,{0(){return r.matches(Na)},1(){let t=r;for(;t!==null;){if(t.matches(Na))return!0;t=t.parentElement}return!1}})}function ah(r){let d=_l(r);Fr(()=>{d&&!xl(d.activeElement,0)&&v1(r)})}var g1=(r=>(r[r.Keyboard=0]="Keyboard",r[r.Mouse=1]="Mouse",r))(g1||{});typeof window<"u"&&typeof document<"u"&&(document.addEventListener("keydown",r=>{r.metaKey||r.altKey||r.ctrlKey||(document.documentElement.dataset.headlessuiFocusVisible="")},!0),document.addEventListener("click",r=>{r.detail===1?delete document.documentElement.dataset.headlessuiFocusVisible:r.detail===0&&(document.documentElement.dataset.headlessuiFocusVisible="")},!0));function v1(r){r==null||r.focus({preventScroll:!0})}let b1=["textarea","input"].join(",");function _1(r){var d,w;return(w=(d=r==null?void 0:r.matches)==null?void 0:d.call(r,b1))!=null?w:!1}function lh(r,d=w=>w){return r.slice().sort((w,t)=>{let x=d(w),v=d(t);if(x===null||v===null)return 0;let s=x.compareDocumentPosition(v);return s&Node.DOCUMENT_POSITION_FOLLOWING?-1:s&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function w1(r,d){return x1(ih(),d,{relativeTo:r})}function x1(r,d,{sorted:w=!0,relativeTo:t=null,skipElements:x=[]}={}){var v;let s=(v=Array.isArray(r)?r.length>0?r[0].ownerDocument:document:r==null?void 0:r.ownerDocument)!=null?v:document,c=Array.isArray(r)?w?lh(r):r:ih(r);x.length>0&&c.length>1&&(c=c.filter(a=>!x.includes(a))),t=t??s.activeElement;let o=(()=>{if(d&5)return 1;if(d&10)return-1;throw new Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),u=(()=>{if(d&1)return 0;if(d&2)return Math.max(0,c.indexOf(t))-1;if(d&4)return Math.max(0,c.indexOf(t))+1;if(d&8)return c.length-1;throw new Error("Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last")})(),g=d&32?{preventScroll:!0}:{},p=0,n=c.length,i;do{if(p>=n||p+n<=0)return 0;let a=u+p;if(d&16)a=(a+n)%n;else{if(a<0)return 3;if(a>=n)return 1}i=c[a],i==null||i.focus(g),p+=o}while(i!==s.activeElement);return d&6&&_1(i)&&i.select(),2}function j1(){return/iPhone/gi.test(window.navigator.platform)||/Mac/gi.test(window.navigator.platform)&&window.navigator.maxTouchPoints>0}function S1(){return/Android/gi.test(window.navigator.userAgent)}function E1(){return j1()||S1()}function Is(r,d,w){wi.isServer||ln(t=>{document.addEventListener(r,d,w),t(()=>document.removeEventListener(r,d,w))})}function T1(r,d,w){wi.isServer||ln(t=>{window.addEventListener(r,d,w),t(()=>window.removeEventListener(r,d,w))})}function k1(r,d,w=jt(()=>!0)){function t(v,s){if(!w.value||v.defaultPrevented)return;let c=s(v);if(c===null||!c.getRootNode().contains(c))return;let o=function u(g){return typeof g=="function"?u(g()):Array.isArray(g)||g instanceof Set?g:[g]}(r);for(let u of o){if(u===null)continue;let g=u instanceof HTMLElement?u:Ft(u);if(g!=null&&g.contains(c)||v.composed&&v.composedPath().includes(g))return}return!xl(c,wl.Loose)&&c.tabIndex!==-1&&v.preventDefault(),d(v,c)}let x=mt(null);Is("pointerdown",v=>{var s,c;w.value&&(x.value=((c=(s=v.composedPath)==null?void 0:s.call(v))==null?void 0:c[0])||v.target)},!0),Is("mousedown",v=>{var s,c;w.value&&(x.value=((c=(s=v.composedPath)==null?void 0:s.call(v))==null?void 0:c[0])||v.target)},!0),Is("click",v=>{E1()||x.value&&(t(v,()=>x.value),x.value=null)},!0),Is("touchend",v=>t(v,()=>v.target instanceof HTMLElement?v.target:null),!0),T1("blur",v=>t(v,()=>window.document.activeElement instanceof HTMLIFrameElement?window.document.activeElement:null),!0)}function Dc(r,d){if(r)return r;let w=d??"button";if(typeof w=="string"&&w.toLowerCase()==="button")return"button"}function M1(r,d){let w=mt(Dc(r.value.type,r.value.as));return Qr(()=>{w.value=Dc(r.value.type,r.value.as)}),ln(()=>{var t;w.value||Ft(d)&&Ft(d)instanceof HTMLButtonElement&&!((t=Ft(d))!=null&&t.hasAttribute("type"))&&(w.value="button")}),w}let Fc=/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g;function Nc(r){var d,w;let t=(d=r.innerText)!=null?d:"",x=r.cloneNode(!0);if(!(x instanceof HTMLElement))return t;let v=!1;for(let c of x.querySelectorAll('[hidden],[aria-hidden],[role="img"]'))c.remove(),v=!0;let s=v?(w=x.innerText)!=null?w:"":t;return Fc.test(s)&&(s=s.replace(Fc,"")),s}function C1(r){let d=r.getAttribute("aria-label");if(typeof d=="string")return d.trim();let w=r.getAttribute("aria-labelledby");if(w){let t=w.split(" ").map(x=>{let v=document.getElementById(x);if(v){let s=v.getAttribute("aria-label");return typeof s=="string"?s.trim():Nc(v).trim()}return null}).filter(Boolean);if(t.length>0)return t.join(", ")}return Nc(r).trim()}function O1(r){let d=mt(""),w=mt("");return()=>{let t=Ft(r);if(!t)return"";let x=t.innerText;if(d.value===x)return w.value;let v=C1(t).trim().toLowerCase();return d.value=x,w.value=v,v}}function Uc(r){return[r.screenX,r.screenY]}function P1(){let r=mt([-1,-1]);return{wasMoved(d){let w=Uc(d);return r.value[0]===w[0]&&r.value[1]===w[1]?!1:(r.value=w,!0)},update(d){r.value=Uc(d)}}}function A1({container:r,accept:d,walk:w,enabled:t}){ln(()=>{let x=r.value;if(!x||t!==void 0&&!t.value)return;let v=_l(r);if(!v)return;let s=Object.assign(o=>d(o),{acceptNode:d}),c=v.createTreeWalker(x,NodeFilter.SHOW_ELEMENT,s,!1);for(;c.nextNode();)w(c.currentNode)})}let uh=Symbol("Context");var Ir=(r=>(r[r.Open=1]="Open",r[r.Closed=2]="Closed",r[r.Closing=4]="Closing",r[r.Opening=8]="Opening",r))(Ir||{});function R1(){return jl()!==null}function jl(){return Ht(uh,null)}function ch(r){Wr(uh,r)}var ir=(r=>(r.Space=" ",r.Enter="Enter",r.Escape="Escape",r.Backspace="Backspace",r.Delete="Delete",r.ArrowLeft="ArrowLeft",r.ArrowUp="ArrowUp",r.ArrowRight="ArrowRight",r.ArrowDown="ArrowDown",r.Home="Home",r.End="End",r.PageUp="PageUp",r.PageDown="PageDown",r.Tab="Tab",r))(ir||{});function L1(r){throw new Error("Unexpected object: "+r)}var Dr=(r=>(r[r.First=0]="First",r[r.Previous=1]="Previous",r[r.Next=2]="Next",r[r.Last=3]="Last",r[r.Specific=4]="Specific",r[r.Nothing=5]="Nothing",r))(Dr||{});function I1(r,d){let w=d.resolveItems();if(w.length<=0)return null;let t=d.resolveActiveIndex(),x=t??-1;switch(r.focus){case 0:{for(let v=0;v=0;--v)if(!d.resolveDisabled(w[v],v,w))return v;return t}case 2:{for(let v=x+1;v=0;--v)if(!d.resolveDisabled(w[v],v,w))return v;return t}case 4:{for(let v=0;v(r[r.None=0]="None",r[r.RenderStrategy=1]="RenderStrategy",r[r.Static=2]="Static",r))(ni||{}),An=(r=>(r[r.Unmount=0]="Unmount",r[r.Hidden=1]="Hidden",r))(An||{});function To({visible:r=!0,features:d=0,ourProps:w,theirProps:t,...x}){var v;let s=fh(t,w),c=Object.assign(x,{props:s});if(r||d&2&&s.static)return ra(c);if(d&1){let o=(v=s.unmount)==null||v?0:1;return Jn(o,{0(){return null},1(){return ra({...x,props:{...s,hidden:!0,style:{display:"none"}}})}})}return ra(c)}function ra({props:r,attrs:d,slots:w,slot:t,name:x}){var v,s;let{as:c,...o}=hh(r,["unmount","static"]),u=(v=w.default)==null?void 0:v.call(w,t),g={};if(t){let p=!1,n=[];for(let[i,a]of Object.entries(t))typeof a=="boolean"&&(p=!0),a===!0&&n.push(i);p&&(g["data-headlessui-state"]=n.join(" "))}if(c==="template"){if(u=dh(u??[]),Object.keys(o).length>0||Object.keys(d).length>0){let[p,...n]=u??[];if(!D1(p)||n.length>0)throw new Error(['Passing props on "template"!',"",`The current component <${x} /> is rendering a "template".`,"However we need to passthrough the following props:",Object.keys(o).concat(Object.keys(d)).map(h=>h.trim()).filter((h,y,l)=>l.indexOf(h)===y).sort((h,y)=>h.localeCompare(y)).map(h=>` - ${h}`).join(` `),"","You can apply a few solutions:",['Add an `as="..."` prop, to ensure that we render an actual element instead of a "template".',"Render a single element as the child so that we can forward the props onto that element."].map(h=>` - ${h}`).join(` `)].join(` -`));let i=dh((s=p.props)!=null?s:{},o,g),a=un(p,i,!0);for(let h in i)h.startsWith("on")&&(a.props||(a.props={}),a.props[h]=i[h]);return a}return Array.isArray(u)&&u.length===1?u[0]:u}return rr(c,Object.assign({},o,g),{default:()=>u})}function ch(r){return r.flatMap(d=>d.type===gr?ch(d.children):[d])}function dh(...r){if(r.length===0)return{};if(r.length===1)return r[0];let d={},w={};for(let t of r)for(let x in t)x.startsWith("on")&&typeof t[x]=="function"?(w[x]!=null||(w[x]=[]),w[x].push(t[x])):d[x]=t[x];if(d.disabled||d["aria-disabled"])return Object.assign(d,Object.fromEntries(Object.keys(w).map(t=>[t,void 0])));for(let t in w)Object.assign(d,{[t](x,...v){let s=w[t];for(let c of s){if(x instanceof Event&&x.defaultPrevented)return;c(x,...v)}}});return d}function fh(r,d=[]){let w=Object.assign({},r);for(let t of d)t in w&&delete w[t];return w}function L1(r){return r==null?!1:typeof r.type=="string"||typeof r.type=="object"||typeof r.type=="function"}var I1=(r=>(r[r.Open=0]="Open",r[r.Closed=1]="Closed",r))(I1||{}),D1=(r=>(r[r.Pointer=0]="Pointer",r[r.Other=1]="Other",r))(D1||{});function F1(r){requestAnimationFrame(()=>requestAnimationFrame(r))}let hh=Symbol("MenuContext");function xi(r){let d=Ht(hh,null);if(d===null){let w=new Error(`<${r} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(w,xi),w}return d}let N1=pr({name:"Menu",props:{as:{type:[Object,String],default:"template"}},setup(r,{slots:d,attrs:w}){let t=mt(1),x=mt(null),v=mt(null),s=mt([]),c=mt(""),o=mt(null),u=mt(1);function g(n=i=>i){let i=o.value!==null?s.value[o.value]:null,a=ah(n(s.value.slice()),m=>Ft(m.dataRef.domRef)),h=i?a.indexOf(i):null;return h===-1&&(h=null),{items:a,activeItemIndex:h}}let p={menuState:t,buttonRef:x,itemsRef:v,items:s,searchQuery:c,activeItemIndex:o,activationTrigger:u,closeMenu:()=>{t.value=1,o.value=null},openMenu:()=>t.value=0,goToItem(n,i,a){let h=g(),m=R1(n===Dr.Specific?{focus:Dr.Specific,id:i}:{focus:n},{resolveItems:()=>h.items,resolveActiveIndex:()=>h.activeItemIndex,resolveId:l=>l.id,resolveDisabled:l=>l.dataRef.disabled});c.value="",o.value=m,u.value=a??1,s.value=h.items},search(n){let i=c.value!==""?0:1;c.value+=n.toLowerCase();let a=(o.value!==null?s.value.slice(o.value+i).concat(s.value.slice(0,o.value+i)):s.value).find(m=>m.dataRef.textValue.startsWith(c.value)&&!m.dataRef.disabled),h=a?s.value.indexOf(a):-1;h===-1||h===o.value||(o.value=h,u.value=1)},clearSearch(){c.value=""},registerItem(n,i){let a=g(h=>[...h,{id:n,dataRef:i}]);s.value=a.items,o.value=a.activeItemIndex,u.value=1},unregisterItem(n){let i=g(a=>{let h=a.findIndex(m=>m.id===n);return h!==-1&&a.splice(h,1),a});s.value=i.items,o.value=i.activeItemIndex,u.value=1}};return E1([x,v],(n,i)=>{var a;p.closeMenu(),jl(i,xl.Loose)||(n.preventDefault(),(a=Ft(x))==null||a.focus())},jt(()=>t.value===0)),Wr(hh,p),uh(jt(()=>Qn(t.value,{0:Ir.Open,1:Ir.Closed}))),()=>{let n={open:t.value===0,close:p.closeMenu};return To({ourProps:{},theirProps:r,slot:n,slots:d,attrs:w,name:"Menu"})}}}),U1=pr({name:"MenuButton",props:{disabled:{type:Boolean,default:!1},as:{type:[Object,String],default:"button"},id:{type:String,default:null}},setup(r,{attrs:d,slots:w,expose:t}){var x;let v=(x=r.id)!=null?x:`headlessui-menu-button-${_i()}`,s=xi("MenuButton");t({el:s.buttonRef,$el:s.buttonRef});function c(p){switch(p.key){case ir.Space:case ir.Enter:case ir.ArrowDown:p.preventDefault(),p.stopPropagation(),s.openMenu(),Fr(()=>{var n;(n=Ft(s.itemsRef))==null||n.focus({preventScroll:!0}),s.goToItem(Dr.First)});break;case ir.ArrowUp:p.preventDefault(),p.stopPropagation(),s.openMenu(),Fr(()=>{var n;(n=Ft(s.itemsRef))==null||n.focus({preventScroll:!0}),s.goToItem(Dr.Last)});break}}function o(p){switch(p.key){case ir.Space:p.preventDefault();break}}function u(p){r.disabled||(s.menuState.value===0?(s.closeMenu(),Fr(()=>{var n;return(n=Ft(s.buttonRef))==null?void 0:n.focus({preventScroll:!0})})):(p.preventDefault(),s.openMenu(),F1(()=>{var n;return(n=Ft(s.itemsRef))==null?void 0:n.focus({preventScroll:!0})})))}let g=T1(jt(()=>({as:r.as,type:d.type})),s.buttonRef);return()=>{var p;let n={open:s.menuState.value===0},{...i}=r,a={ref:s.buttonRef,id:v,type:g.value,"aria-haspopup":"menu","aria-controls":(p=Ft(s.itemsRef))==null?void 0:p.id,"aria-expanded":s.menuState.value===0,onKeydown:c,onKeyup:o,onClick:u};return To({ourProps:a,theirProps:i,slot:n,attrs:d,slots:w,name:"MenuButton"})}}}),B1=pr({name:"MenuItems",props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1},unmount:{type:Boolean,default:!0},id:{type:String,default:null}},setup(r,{attrs:d,slots:w,expose:t}){var x;let v=(x=r.id)!=null?x:`headlessui-menu-items-${_i()}`,s=xi("MenuItems"),c=mt(null);t({el:s.itemsRef,$el:s.itemsRef}),O1({container:jt(()=>Ft(s.itemsRef)),enabled:jt(()=>s.menuState.value===0),accept(n){return n.getAttribute("role")==="menuitem"?NodeFilter.FILTER_REJECT:n.hasAttribute("role")?NodeFilter.FILTER_SKIP:NodeFilter.FILTER_ACCEPT},walk(n){n.setAttribute("role","none")}});function o(n){var i;switch(c.value&&clearTimeout(c.value),n.key){case ir.Space:if(s.searchQuery.value!=="")return n.preventDefault(),n.stopPropagation(),s.search(n.key);case ir.Enter:if(n.preventDefault(),n.stopPropagation(),s.activeItemIndex.value!==null){let a=s.items.value[s.activeItemIndex.value];(i=Ft(a.dataRef.domRef))==null||i.click()}s.closeMenu(),ih(Ft(s.buttonRef));break;case ir.ArrowDown:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.Next);case ir.ArrowUp:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.Previous);case ir.Home:case ir.PageUp:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.First);case ir.End:case ir.PageDown:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.Last);case ir.Escape:n.preventDefault(),n.stopPropagation(),s.closeMenu(),Fr(()=>{var a;return(a=Ft(s.buttonRef))==null?void 0:a.focus({preventScroll:!0})});break;case ir.Tab:n.preventDefault(),n.stopPropagation(),s.closeMenu(),Fr(()=>b1(Ft(s.buttonRef),n.shiftKey?Ua.Previous:Ua.Next));break;default:n.key.length===1&&(s.search(n.key),c.value=setTimeout(()=>s.clearSearch(),350));break}}function u(n){switch(n.key){case ir.Space:n.preventDefault();break}}let g=Sl(),p=jt(()=>g!==null?(g.value&Ir.Open)===Ir.Open:s.menuState.value===0);return()=>{var n,i;let a={open:s.menuState.value===0},{...h}=r,m={"aria-activedescendant":s.activeItemIndex.value===null||(n=s.items.value[s.activeItemIndex.value])==null?void 0:n.id,"aria-labelledby":(i=Ft(s.buttonRef))==null?void 0:i.id,id:v,onKeydown:o,onKeyup:u,role:"menu",tabIndex:0,ref:s.itemsRef};return To({ourProps:m,theirProps:h,slot:a,attrs:d,slots:w,features:ni.RenderStrategy|ni.Static,visible:p.value,name:"MenuItems"})}}}),G1=pr({name:"MenuItem",inheritAttrs:!1,props:{as:{type:[Object,String],default:"template"},disabled:{type:Boolean,default:!1},id:{type:String,default:null}},setup(r,{slots:d,attrs:w,expose:t}){var x;let v=(x=r.id)!=null?x:`headlessui-menu-item-${_i()}`,s=xi("MenuItem"),c=mt(null);t({el:c,$el:c});let o=jt(()=>s.activeItemIndex.value!==null?s.items.value[s.activeItemIndex.value].id===v:!1),u=M1(c),g=jt(()=>({disabled:r.disabled,get textValue(){return u()},domRef:c}));Qr(()=>s.registerItem(v,g)),us(()=>s.unregisterItem(v)),ln(()=>{s.menuState.value===0&&o.value&&s.activationTrigger.value!==0&&Fr(()=>{var l,f;return(f=(l=Ft(c))==null?void 0:l.scrollIntoView)==null?void 0:f.call(l,{block:"nearest"})})});function p(l){if(r.disabled)return l.preventDefault();s.closeMenu(),ih(Ft(s.buttonRef))}function n(){if(r.disabled)return s.goToItem(Dr.Nothing);s.goToItem(Dr.Specific,v)}let i=C1();function a(l){i.update(l)}function h(l){i.wasMoved(l)&&(r.disabled||o.value||s.goToItem(Dr.Specific,v,0))}function m(l){i.wasMoved(l)&&(r.disabled||o.value&&s.goToItem(Dr.Nothing))}return()=>{let{disabled:l,...f}=r,y={active:o.value,disabled:l,close:s.closeMenu};return To({ourProps:{id:v,ref:c,role:"menuitem",tabIndex:l===!0?void 0:-1,"aria-disabled":l===!0?!0:void 0,onClick:p,onFocus:n,onPointerenter:a,onMouseenter:a,onPointermove:h,onMousemove:h,onPointerleave:m,onMouseleave:m},theirProps:{...w,...f},slot:y,attrs:w,slots:d,name:"MenuItem"})}}});function V1(r,d){return Gr(),ci("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true","data-slot":"icon"},[Lt("path",{"fill-rule":"evenodd",d:"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z","clip-rule":"evenodd"})])}const H1={class:"container mx-auto py-6"},z1={class:"flex items-end justify-between text-gray-200"},W1={class:"px-1 py-1"},q1={href:"/articles"},X1=Lt("svg",{class:"mr-2 inline h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},[Lt("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"})],-1),Y1={href:"/playground"},$1=Lt("svg",{class:"mr-2 inline h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},[Lt("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23-.693L5 14.5m14.8.8l1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0112 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5"})],-1),K1={href:"https://github.com/cmpadden"},Z1=Lt("svg",{class:"mr-2 inline h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},[Lt("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0021 18V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v12a2.25 2.25 0 002.25 2.25z"})],-1),Q1={__name:"Header",setup(r){return mi(),(d,w)=>{const t=s1,x=U1,v=G1,s=B1,c=N1;return Gr(),ci("nav",H1,[Lt("div",z1,[pt(t,{to:"/",class:"font-mono text-3xl font-semibold text-white underline decoration-orange-500 underline-offset-4 hover:text-orange-500",as:"div"},{default:Ur(()=>[ao(" who·am·i ")]),_:1}),Lt("div",null,[pt(c,{as:"div",class:"relative z-50 inline-block text-left"},{default:Ur(()=>[Lt("div",null,[pt(x,{class:"inline-flex w-full justify-center rounded-md bg-black bg-opacity-30 p-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"},{default:Ur(()=>[pt(Bt(V1),{class:"h-5 w-5 text-white hover:text-blue-400","aria-hidden":"true"})]),_:1})]),pt(fs,{"enter-active-class":"transition duration-100 ease-out","enter-from-class":"transform scale-95 opacity-0","enter-to-class":"transform scale-100 opacity-100","leave-active-class":"transition duration-75 ease-in","leave-from-class":"transform scale-100 opacity-100","leave-to-class":"transform scale-95 opacity-0"},{default:Ur(()=>[pt(s,{class:"absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md bg-black/80 text-white shadow-lg ring-1 ring-black ring-opacity-5 backdrop-blur-sm focus:outline-none"},{default:Ur(()=>[Lt("div",W1,[pt(v,null,{default:Ur(({active:o})=>[Lt("a",q1,[Lt("button",{class:Xn([o?"bg-slate-700 text-white":"text-white","group flex w-full items-center rounded-md px-2 py-2 text-sm"])},[X1,ao(" Blog ")],2)])]),_:1}),pt(v,null,{default:Ur(({active:o})=>[Lt("a",Y1,[Lt("button",{class:Xn([o?"bg-slate-700 text-white":"text-white","group flex w-full items-center rounded-md px-2 py-2 text-sm"])},[$1,ao(" Experiments ")],2)])]),_:1}),pt(v,null,{default:Ur(({active:o})=>[Lt("a",K1,[Lt("button",{class:Xn([o?"bg-slate-700":"","group flex w-full items-center rounded-md px-2 py-2 text-sm"])},[Z1,ao(" GitHub ")],2)])]),_:1})])]),_:1})]),_:1})]),_:1})])])])}}};function J1(r){typeof queueMicrotask=="function"?queueMicrotask(r):Promise.resolve().then(r).catch(d=>setTimeout(()=>{throw d}))}function El(){let r=[],d={addEventListener(w,t,x,v){return w.addEventListener(t,x,v),d.add(()=>w.removeEventListener(t,x,v))},requestAnimationFrame(...w){let t=requestAnimationFrame(...w);d.add(()=>cancelAnimationFrame(t))},nextFrame(...w){d.requestAnimationFrame(()=>{d.requestAnimationFrame(...w)})},setTimeout(...w){let t=setTimeout(...w);d.add(()=>clearTimeout(t))},microTask(...w){let t={current:!0};return J1(()=>{t.current&&w[0]()}),d.add(()=>{t.current=!1})},style(w,t,x){let v=w.style.getPropertyValue(t);return Object.assign(w.style,{[t]:x}),this.add(()=>{Object.assign(w.style,{[t]:v})})},group(w){let t=El();return w(t),this.add(()=>t.dispose())},add(w){return r.push(w),()=>{let t=r.indexOf(w);if(t>=0)for(let x of r.splice(t,1))x()}},dispose(){for(let w of r.splice(0))w()}};return d}function e_(r){let d={called:!1};return(...w)=>{if(!d.called)return d.called=!0,r(...w)}}function na(r,...d){r&&d.length>0&&r.classList.add(...d)}function Ds(r,...d){r&&d.length>0&&r.classList.remove(...d)}var Ba=(r=>(r.Finished="finished",r.Cancelled="cancelled",r))(Ba||{});function t_(r,d){let w=El();if(!r)return w.dispose;let{transitionDuration:t,transitionDelay:x}=getComputedStyle(r),[v,s]=[t,x].map(c=>{let[o=0]=c.split(",").filter(Boolean).map(u=>u.includes("ms")?parseFloat(u):parseFloat(u)*1e3).sort((u,g)=>g-u);return o});return v!==0?w.setTimeout(()=>d("finished"),v+s):d("finished"),w.add(()=>d("cancelled")),w.dispose}function Gc(r,d,w,t,x,v){let s=El(),c=v!==void 0?e_(v):()=>{};return Ds(r,...x),na(r,...d,...w),s.nextFrame(()=>{Ds(r,...w),na(r,...t),s.add(t_(r,o=>(Ds(r,...t,...d),na(r,...x),c(o))))}),s.add(()=>Ds(r,...d,...w,...t,...x)),s.add(()=>c("cancelled")),s.dispose}function Hn(r=""){return r.split(/\s+/).filter(d=>d.length>1)}let Tl=Symbol("TransitionContext");var r_=(r=>(r.Visible="visible",r.Hidden="hidden",r))(r_||{});function n_(){return Ht(Tl,null)!==null}function o_(){let r=Ht(Tl,null);if(r===null)throw new Error("A is used but it is missing a parent .");return r}function s_(){let r=Ht(kl,null);if(r===null)throw new Error("A is used but it is missing a parent .");return r}let kl=Symbol("NestingContext");function ji(r){return"children"in r?ji(r.children):r.value.filter(({state:d})=>d==="visible").length>0}function ph(r){let d=mt([]),w=mt(!1);Qr(()=>w.value=!0),us(()=>w.value=!1);function t(v,s=An.Hidden){let c=d.value.findIndex(({id:o})=>o===v);c!==-1&&(Qn(s,{[An.Unmount](){d.value.splice(c,1)},[An.Hidden](){d.value[c].state="hidden"}}),!ji(d)&&w.value&&(r==null||r()))}function x(v){let s=d.value.find(({id:c})=>c===v);return s?s.state!=="visible"&&(s.state="visible"):d.value.push({id:v,state:"visible"}),()=>t(v,An.Unmount)}return{children:d,register:x,unregister:t}}let mh=ni.RenderStrategy,i_=pr({props:{as:{type:[Object,String],default:"div"},show:{type:[Boolean],default:null},unmount:{type:[Boolean],default:!0},appear:{type:[Boolean],default:!1},enter:{type:[String],default:""},enterFrom:{type:[String],default:""},enterTo:{type:[String],default:""},entered:{type:[String],default:""},leave:{type:[String],default:""},leaveFrom:{type:[String],default:""},leaveTo:{type:[String],default:""}},emits:{beforeEnter:()=>!0,afterEnter:()=>!0,beforeLeave:()=>!0,afterLeave:()=>!0},setup(r,{emit:d,attrs:w,slots:t,expose:x}){let v=mt(0);function s(){v.value|=Ir.Opening,d("beforeEnter")}function c(){v.value&=~Ir.Opening,d("afterEnter")}function o(){v.value|=Ir.Closing,d("beforeLeave")}function u(){v.value&=~Ir.Closing,d("afterLeave")}if(!n_()&&P1())return()=>rr(yh,{...r,onBeforeEnter:s,onAfterEnter:c,onBeforeLeave:o,onAfterLeave:u},t);let g=mt(null),p=jt(()=>r.unmount?An.Unmount:An.Hidden);x({el:g,$el:g});let{show:n,appear:i}=o_(),{register:a,unregister:h}=s_(),m=mt(n.value?"visible":"hidden"),l={value:!0},f=_i(),y={value:!1},b=ph(()=>{!y.value&&m.value!=="hidden"&&(m.value="hidden",h(f),u())});Qr(()=>{let A=a(f);us(A)}),ln(()=>{if(p.value===An.Hidden&&f){if(n.value&&m.value!=="visible"){m.value="visible";return}Qn(m.value,{hidden:()=>h(f),visible:()=>a(f)})}});let j=Hn(r.enter),k=Hn(r.enterFrom),E=Hn(r.enterTo),M=Hn(r.entered),P=Hn(r.leave),L=Hn(r.leaveFrom),C=Hn(r.leaveTo);Qr(()=>{ln(()=>{if(m.value==="visible"){let A=Ft(g);if(A instanceof Comment&&A.data==="")throw new Error("Did you forget to passthrough the `ref` to the actual DOM node?")}})});function I(A){let N=l.value&&!i.value,F=Ft(g);!F||!(F instanceof HTMLElement)||N||(y.value=!0,n.value&&s(),n.value||o(),A(n.value?Gc(F,j,k,E,M,B=>{y.value=!1,B===Ba.Finished&&c()}):Gc(F,P,L,C,M,B=>{y.value=!1,B===Ba.Finished&&(ji(b)||(m.value="hidden",h(f),u()))})))}return Qr(()=>{In([n],(A,N,F)=>{I(F),l.value=!1},{immediate:!0})}),Wr(kl,b),uh(jt(()=>Qn(m.value,{visible:Ir.Open,hidden:Ir.Closed})|v.value)),()=>{let{appear:A,show:N,enter:F,enterFrom:B,enterTo:q,entered:V,leave:H,leaveFrom:Z,leaveTo:ee,...ue}=r,T={ref:g},D={...ue,...i.value&&n.value&&wi.isServer?{class:Xn([w.class,ue.class,...j,...k])}:{}};return To({theirProps:D,ourProps:T,slot:{},slots:t,attrs:w,features:mh,visible:m.value==="visible",name:"TransitionChild"})}}}),a_=i_,yh=pr({inheritAttrs:!1,props:{as:{type:[Object,String],default:"div"},show:{type:[Boolean],default:null},unmount:{type:[Boolean],default:!0},appear:{type:[Boolean],default:!1},enter:{type:[String],default:""},enterFrom:{type:[String],default:""},enterTo:{type:[String],default:""},entered:{type:[String],default:""},leave:{type:[String],default:""},leaveFrom:{type:[String],default:""},leaveTo:{type:[String],default:""}},emits:{beforeEnter:()=>!0,afterEnter:()=>!0,beforeLeave:()=>!0,afterLeave:()=>!0},setup(r,{emit:d,attrs:w,slots:t}){let x=Sl(),v=jt(()=>r.show===null&&x!==null?(x.value&Ir.Open)===Ir.Open:r.show);ln(()=>{if(![!0,!1].includes(v.value))throw new Error('A is used but it is missing a `:show="true | false"` prop.')});let s=mt(v.value?"visible":"hidden"),c=ph(()=>{s.value="hidden"}),o=mt(!0),u={show:v,appear:jt(()=>r.appear||!o.value)};return Qr(()=>{ln(()=>{o.value=!1,v.value?s.value="visible":ji(c)||(s.value="hidden")})}),Wr(kl,c),Wr(Tl,u),()=>{let g=fh(r,["show","appear","unmount","onBeforeEnter","onBeforeLeave","onAfterEnter","onAfterLeave"]),p={unmount:r.unmount};return To({ourProps:{...p,as:"template"},theirProps:{},slot:{},slots:{...t,default:()=>[rr(a_,{onBeforeEnter:()=>d("beforeEnter"),onAfterEnter:()=>d("afterEnter"),onBeforeLeave:()=>d("beforeLeave"),onAfterLeave:()=>d("afterLeave"),...w,...p,...g},t.default)]},attrs:{},features:mh,visible:s.value==="visible",name:"Transition"})}}});const l_=(r,d)=>{const w=r.__vccOpts||r;for(const[t,x]of d)w[t]=x;return w},u_={},c_={class:"flex min-h-screen flex-col bg-background font-display"},d_={class:"mt-4 flex-1"},f_={class:"flex justify-center"},h_=Lt("div",{class:"rounded-xl bg-black/50 p-6 text-center shadow-lg"},[Lt("div",{class:"text-6xl font-extrabold tracking-widest text-white"}," Yikes! "),Lt("div",{class:"text-base text-gray-200"}," Either the page you're looking for doesn't exist, or something has gone terribly wrong. ")],-1);function p_(r,d){const w=Q1,t=yh;return Gr(),ci("body",c_,[pt(w),Lt("main",d_,[Lt("div",f_,[pt(t,{show:"",appear:"",as:"template",enter:"transition transform duration-300 ease-out","enter-from":"translate-x-8 opacity-0","enter-to":"translate-x-0 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"-translate-x-8 opacity-0"},{default:Ur(()=>[h_]),_:1})])])])}const m_=l_(u_,[["render",p_]]),Vc={__name:"nuxt-root",setup(r){const d=()=>null,w=It(),t=w.deferHydration();if(w.isHydrating){const c=w.hooks.hookOnce("app:error",t);qr().beforeEach(c)}const x=!1;Wr(ps,mi()),w.hooks.callHookWith(c=>c.map(o=>o()),"vue:setup");const v=yi();Td((c,o,u)=>{if(w.hooks.callHook("vue:error",c,o,u).catch(g=>console.error("[nuxt] Error in `vue:error` hook",g)),kg(c)&&(c.fatal||c.unhandled))return w.runWithContext(()=>lo(c)),!1});const s=!1;return(c,o)=>(Gr(),qn(nl,{onResolve:Bt(t)},{default:Ur(()=>[Bt(v)?(Gr(),qn(Bt(m_),{key:0,error:Bt(v)},null,8,["error"])):Bt(s)?(Gr(),qn(Bt(d),{key:1,context:Bt(s)},null,8,["context"])):Bt(x)?(Gr(),qn(Ip(Bt(x)),{key:2})):(Gr(),qn(Bt(r1),{key:3}))]),_:1},8,["onResolve"]))}};let Hc;{let r;Hc=async function(){var s,c;if(r)return r;const t=!!((s=window.__NUXT__)!=null&&s.serverRendered||((c=document.getElementById("__NUXT_DATA__"))==null?void 0:c.dataset.ssr)==="true")?iy(Vc):sy(Vc),x=dg({vueApp:t});async function v(o){await x.callHook("app:error",o),x.payload.error=x.payload.error||gi(o)}t.config.errorHandler=v;try{await hg(x,qb)}catch(o){v(o)}try{await x.hooks.callHook("app:created",t),await x.hooks.callHook("app:beforeMount",t),t.mount(Tv),await x.hooks.callHook("app:mounted",t),await Fr()}catch(o){v(o)}return t.config.errorHandler===v&&(t.config.errorHandler=void 0),t},r=Hc().catch(d=>{throw console.error("Error while mounting app:",d),d})}export{Eo as $,w_ as A,M_ as B,hr as C,qn as D,Fr as E,gr as F,vv as G,pi as H,S_ as I,Qs as J,rr as K,rt as L,Sp as M,It as N,__ as O,Ry as P,Qu as Q,hi as R,yh as S,fs as T,fi as U,C_ as V,Ko as W,Vp as X,g_ as Y,gi as Z,l_ as _,Bt as a,Kh as a0,bt as a1,Lp as a2,vo as a3,ar as a4,Ks as a5,b_ as a6,j_ as a7,qa as a8,Q1 as a9,Rs as aa,Lt as b,ci as c,pr as d,k_ as e,pt as f,Ur as g,ao as h,s1 as i,T_ as j,mt as k,Qr as l,i_ as m,Xn as n,Gr as o,In as p,ls as q,x_ as r,us as s,y_ as t,mi as u,jt as v,E_ as w,Un as x,O_ as y,v_ as z}; +`));let i=fh((s=p.props)!=null?s:{},o,g),a=un(p,i,!0);for(let h in i)h.startsWith("on")&&(a.props||(a.props={}),a.props[h]=i[h]);return a}return Array.isArray(u)&&u.length===1?u[0]:u}return rr(c,Object.assign({},o,g),{default:()=>u})}function dh(r){return r.flatMap(d=>d.type===gr?dh(d.children):[d])}function fh(...r){if(r.length===0)return{};if(r.length===1)return r[0];let d={},w={};for(let t of r)for(let x in t)x.startsWith("on")&&typeof t[x]=="function"?(w[x]!=null||(w[x]=[]),w[x].push(t[x])):d[x]=t[x];if(d.disabled||d["aria-disabled"])return Object.assign(d,Object.fromEntries(Object.keys(w).map(t=>[t,void 0])));for(let t in w)Object.assign(d,{[t](x,...v){let s=w[t];for(let c of s){if(x instanceof Event&&x.defaultPrevented)return;c(x,...v)}}});return d}function hh(r,d=[]){let w=Object.assign({},r);for(let t of d)t in w&&delete w[t];return w}function D1(r){return r==null?!1:typeof r.type=="string"||typeof r.type=="object"||typeof r.type=="function"}var F1=(r=>(r[r.Open=0]="Open",r[r.Closed=1]="Closed",r))(F1||{}),N1=(r=>(r[r.Pointer=0]="Pointer",r[r.Other=1]="Other",r))(N1||{});function U1(r){requestAnimationFrame(()=>requestAnimationFrame(r))}let ph=Symbol("MenuContext");function xi(r){let d=Ht(ph,null);if(d===null){let w=new Error(`<${r} /> is missing a parent component.`);throw Error.captureStackTrace&&Error.captureStackTrace(w,xi),w}return d}let B1=pr({name:"Menu",props:{as:{type:[Object,String],default:"template"}},setup(r,{slots:d,attrs:w}){let t=mt(1),x=mt(null),v=mt(null),s=mt([]),c=mt(""),o=mt(null),u=mt(1);function g(n=i=>i){let i=o.value!==null?s.value[o.value]:null,a=lh(n(s.value.slice()),y=>Ft(y.dataRef.domRef)),h=i?a.indexOf(i):null;return h===-1&&(h=null),{items:a,activeItemIndex:h}}let p={menuState:t,buttonRef:x,itemsRef:v,items:s,searchQuery:c,activeItemIndex:o,activationTrigger:u,closeMenu:()=>{t.value=1,o.value=null},openMenu:()=>t.value=0,goToItem(n,i,a){let h=g(),y=I1(n===Dr.Specific?{focus:Dr.Specific,id:i}:{focus:n},{resolveItems:()=>h.items,resolveActiveIndex:()=>h.activeItemIndex,resolveId:l=>l.id,resolveDisabled:l=>l.dataRef.disabled});c.value="",o.value=y,u.value=a??1,s.value=h.items},search(n){let i=c.value!==""?0:1;c.value+=n.toLowerCase();let a=(o.value!==null?s.value.slice(o.value+i).concat(s.value.slice(0,o.value+i)):s.value).find(y=>y.dataRef.textValue.startsWith(c.value)&&!y.dataRef.disabled),h=a?s.value.indexOf(a):-1;h===-1||h===o.value||(o.value=h,u.value=1)},clearSearch(){c.value=""},registerItem(n,i){let a=g(h=>[...h,{id:n,dataRef:i}]);s.value=a.items,o.value=a.activeItemIndex,u.value=1},unregisterItem(n){let i=g(a=>{let h=a.findIndex(y=>y.id===n);return h!==-1&&a.splice(h,1),a});s.value=i.items,o.value=i.activeItemIndex,u.value=1}};return k1([x,v],(n,i)=>{var a;p.closeMenu(),xl(i,wl.Loose)||(n.preventDefault(),(a=Ft(x))==null||a.focus())},jt(()=>t.value===0)),Wr(ph,p),ch(jt(()=>Jn(t.value,{0:Ir.Open,1:Ir.Closed}))),()=>{let n={open:t.value===0,close:p.closeMenu};return To({ourProps:{},theirProps:r,slot:n,slots:d,attrs:w,name:"Menu"})}}}),G1=pr({name:"MenuButton",props:{disabled:{type:Boolean,default:!1},as:{type:[Object,String],default:"button"},id:{type:String,default:null}},setup(r,{attrs:d,slots:w,expose:t}){var x;let v=(x=r.id)!=null?x:`headlessui-menu-button-${_i()}`,s=xi("MenuButton");t({el:s.buttonRef,$el:s.buttonRef});function c(p){switch(p.key){case ir.Space:case ir.Enter:case ir.ArrowDown:p.preventDefault(),p.stopPropagation(),s.openMenu(),Fr(()=>{var n;(n=Ft(s.itemsRef))==null||n.focus({preventScroll:!0}),s.goToItem(Dr.First)});break;case ir.ArrowUp:p.preventDefault(),p.stopPropagation(),s.openMenu(),Fr(()=>{var n;(n=Ft(s.itemsRef))==null||n.focus({preventScroll:!0}),s.goToItem(Dr.Last)});break}}function o(p){switch(p.key){case ir.Space:p.preventDefault();break}}function u(p){r.disabled||(s.menuState.value===0?(s.closeMenu(),Fr(()=>{var n;return(n=Ft(s.buttonRef))==null?void 0:n.focus({preventScroll:!0})})):(p.preventDefault(),s.openMenu(),U1(()=>{var n;return(n=Ft(s.itemsRef))==null?void 0:n.focus({preventScroll:!0})})))}let g=M1(jt(()=>({as:r.as,type:d.type})),s.buttonRef);return()=>{var p;let n={open:s.menuState.value===0},{...i}=r,a={ref:s.buttonRef,id:v,type:g.value,"aria-haspopup":"menu","aria-controls":(p=Ft(s.itemsRef))==null?void 0:p.id,"aria-expanded":s.menuState.value===0,onKeydown:c,onKeyup:o,onClick:u};return To({ourProps:a,theirProps:i,slot:n,attrs:d,slots:w,name:"MenuButton"})}}}),V1=pr({name:"MenuItems",props:{as:{type:[Object,String],default:"div"},static:{type:Boolean,default:!1},unmount:{type:Boolean,default:!0},id:{type:String,default:null}},setup(r,{attrs:d,slots:w,expose:t}){var x;let v=(x=r.id)!=null?x:`headlessui-menu-items-${_i()}`,s=xi("MenuItems"),c=mt(null);t({el:s.itemsRef,$el:s.itemsRef}),A1({container:jt(()=>Ft(s.itemsRef)),enabled:jt(()=>s.menuState.value===0),accept(n){return n.getAttribute("role")==="menuitem"?NodeFilter.FILTER_REJECT:n.hasAttribute("role")?NodeFilter.FILTER_SKIP:NodeFilter.FILTER_ACCEPT},walk(n){n.setAttribute("role","none")}});function o(n){var i;switch(c.value&&clearTimeout(c.value),n.key){case ir.Space:if(s.searchQuery.value!=="")return n.preventDefault(),n.stopPropagation(),s.search(n.key);case ir.Enter:if(n.preventDefault(),n.stopPropagation(),s.activeItemIndex.value!==null){let a=s.items.value[s.activeItemIndex.value];(i=Ft(a.dataRef.domRef))==null||i.click()}s.closeMenu(),ah(Ft(s.buttonRef));break;case ir.ArrowDown:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.Next);case ir.ArrowUp:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.Previous);case ir.Home:case ir.PageUp:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.First);case ir.End:case ir.PageDown:return n.preventDefault(),n.stopPropagation(),s.goToItem(Dr.Last);case ir.Escape:n.preventDefault(),n.stopPropagation(),s.closeMenu(),Fr(()=>{var a;return(a=Ft(s.buttonRef))==null?void 0:a.focus({preventScroll:!0})});break;case ir.Tab:n.preventDefault(),n.stopPropagation(),s.closeMenu(),Fr(()=>w1(Ft(s.buttonRef),n.shiftKey?Ua.Previous:Ua.Next));break;default:n.key.length===1&&(s.search(n.key),c.value=setTimeout(()=>s.clearSearch(),350));break}}function u(n){switch(n.key){case ir.Space:n.preventDefault();break}}let g=jl(),p=jt(()=>g!==null?(g.value&Ir.Open)===Ir.Open:s.menuState.value===0);return()=>{var n,i;let a={open:s.menuState.value===0},{...h}=r,y={"aria-activedescendant":s.activeItemIndex.value===null||(n=s.items.value[s.activeItemIndex.value])==null?void 0:n.id,"aria-labelledby":(i=Ft(s.buttonRef))==null?void 0:i.id,id:v,onKeydown:o,onKeyup:u,role:"menu",tabIndex:0,ref:s.itemsRef};return To({ourProps:y,theirProps:h,slot:a,attrs:d,slots:w,features:ni.RenderStrategy|ni.Static,visible:p.value,name:"MenuItems"})}}}),H1=pr({name:"MenuItem",inheritAttrs:!1,props:{as:{type:[Object,String],default:"template"},disabled:{type:Boolean,default:!1},id:{type:String,default:null}},setup(r,{slots:d,attrs:w,expose:t}){var x;let v=(x=r.id)!=null?x:`headlessui-menu-item-${_i()}`,s=xi("MenuItem"),c=mt(null);t({el:c,$el:c});let o=jt(()=>s.activeItemIndex.value!==null?s.items.value[s.activeItemIndex.value].id===v:!1),u=O1(c),g=jt(()=>({disabled:r.disabled,get textValue(){return u()},domRef:c}));Qr(()=>s.registerItem(v,g)),us(()=>s.unregisterItem(v)),ln(()=>{s.menuState.value===0&&o.value&&s.activationTrigger.value!==0&&Fr(()=>{var l,f;return(f=(l=Ft(c))==null?void 0:l.scrollIntoView)==null?void 0:f.call(l,{block:"nearest"})})});function p(l){if(r.disabled)return l.preventDefault();s.closeMenu(),ah(Ft(s.buttonRef))}function n(){if(r.disabled)return s.goToItem(Dr.Nothing);s.goToItem(Dr.Specific,v)}let i=P1();function a(l){i.update(l)}function h(l){i.wasMoved(l)&&(r.disabled||o.value||s.goToItem(Dr.Specific,v,0))}function y(l){i.wasMoved(l)&&(r.disabled||o.value&&s.goToItem(Dr.Nothing))}return()=>{let{disabled:l,...f}=r,m={active:o.value,disabled:l,close:s.closeMenu};return To({ourProps:{id:v,ref:c,role:"menuitem",tabIndex:l===!0?void 0:-1,"aria-disabled":l===!0?!0:void 0,onClick:p,onFocus:n,onPointerenter:a,onMouseenter:a,onPointermove:h,onMousemove:h,onPointerleave:y,onMouseleave:y},theirProps:{...w,...f},slot:m,attrs:w,slots:d,name:"MenuItem"})}}});function z1(r,d){return Gr(),ci("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true","data-slot":"icon"},[Lt("path",{"fill-rule":"evenodd",d:"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z","clip-rule":"evenodd"})])}const W1={class:"container mx-auto py-6"},q1={class:"flex items-end justify-between text-gray-200"},X1={class:"px-1 py-1"},Y1={href:"/articles"},$1=Lt("svg",{class:"mr-2 inline h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},[Lt("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"})],-1),K1={href:"/playground"},Z1=Lt("svg",{class:"mr-2 inline h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},[Lt("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23-.693L5 14.5m14.8.8l1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0112 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5"})],-1),Q1={href:"https://github.com/cmpadden"},J1=Lt("svg",{class:"mr-2 inline h-5 w-5",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor"},[Lt("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0021 18V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v12a2.25 2.25 0 002.25 2.25z"})],-1),e_={__name:"Header",setup(r){return mi(),(d,w)=>{const t=a1,x=G1,v=H1,s=V1,c=B1;return Gr(),ci("nav",W1,[Lt("div",q1,[pt(t,{to:"/",class:"font-mono text-3xl font-semibold text-white underline decoration-orange-500 underline-offset-4 hover:text-orange-500",as:"div"},{default:Ur(()=>[ao(" who·am·i ")]),_:1}),Lt("div",null,[pt(c,{as:"div",class:"relative z-50 inline-block text-left"},{default:Ur(()=>[Lt("div",null,[pt(x,{class:"inline-flex w-full justify-center rounded-md bg-black bg-opacity-30 p-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"},{default:Ur(()=>[pt(Bt(z1),{class:"h-5 w-5 text-white hover:text-blue-400","aria-hidden":"true"})]),_:1})]),pt(fs,{"enter-active-class":"transition duration-100 ease-out","enter-from-class":"transform scale-95 opacity-0","enter-to-class":"transform scale-100 opacity-100","leave-active-class":"transition duration-75 ease-in","leave-from-class":"transform scale-100 opacity-100","leave-to-class":"transform scale-95 opacity-0"},{default:Ur(()=>[pt(s,{class:"absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md bg-black/80 text-white shadow-lg ring-1 ring-black ring-opacity-5 backdrop-blur-sm focus:outline-none"},{default:Ur(()=>[Lt("div",X1,[pt(v,null,{default:Ur(({active:o})=>[Lt("a",Y1,[Lt("button",{class:Yn([o?"bg-slate-700 text-white":"text-white","group flex w-full items-center rounded-md px-2 py-2 text-sm"])},[$1,ao(" Blog ")],2)])]),_:1}),pt(v,null,{default:Ur(({active:o})=>[Lt("a",K1,[Lt("button",{class:Yn([o?"bg-slate-700 text-white":"text-white","group flex w-full items-center rounded-md px-2 py-2 text-sm"])},[Z1,ao(" Experiments ")],2)])]),_:1}),pt(v,null,{default:Ur(({active:o})=>[Lt("a",Q1,[Lt("button",{class:Yn([o?"bg-slate-700":"","group flex w-full items-center rounded-md px-2 py-2 text-sm"])},[J1,ao(" GitHub ")],2)])]),_:1})])]),_:1})]),_:1})]),_:1})])])])}}};function t_(r){typeof queueMicrotask=="function"?queueMicrotask(r):Promise.resolve().then(r).catch(d=>setTimeout(()=>{throw d}))}function Sl(){let r=[],d={addEventListener(w,t,x,v){return w.addEventListener(t,x,v),d.add(()=>w.removeEventListener(t,x,v))},requestAnimationFrame(...w){let t=requestAnimationFrame(...w);d.add(()=>cancelAnimationFrame(t))},nextFrame(...w){d.requestAnimationFrame(()=>{d.requestAnimationFrame(...w)})},setTimeout(...w){let t=setTimeout(...w);d.add(()=>clearTimeout(t))},microTask(...w){let t={current:!0};return t_(()=>{t.current&&w[0]()}),d.add(()=>{t.current=!1})},style(w,t,x){let v=w.style.getPropertyValue(t);return Object.assign(w.style,{[t]:x}),this.add(()=>{Object.assign(w.style,{[t]:v})})},group(w){let t=Sl();return w(t),this.add(()=>t.dispose())},add(w){return r.push(w),()=>{let t=r.indexOf(w);if(t>=0)for(let x of r.splice(t,1))x()}},dispose(){for(let w of r.splice(0))w()}};return d}function r_(r){let d={called:!1};return(...w)=>{if(!d.called)return d.called=!0,r(...w)}}function na(r,...d){r&&d.length>0&&r.classList.add(...d)}function Ds(r,...d){r&&d.length>0&&r.classList.remove(...d)}var Ba=(r=>(r.Finished="finished",r.Cancelled="cancelled",r))(Ba||{});function n_(r,d){let w=Sl();if(!r)return w.dispose;let{transitionDuration:t,transitionDelay:x}=getComputedStyle(r),[v,s]=[t,x].map(c=>{let[o=0]=c.split(",").filter(Boolean).map(u=>u.includes("ms")?parseFloat(u):parseFloat(u)*1e3).sort((u,g)=>g-u);return o});return v!==0?w.setTimeout(()=>d("finished"),v+s):d("finished"),w.add(()=>d("cancelled")),w.dispose}function Bc(r,d,w,t,x,v){let s=Sl(),c=v!==void 0?r_(v):()=>{};return Ds(r,...x),na(r,...d,...w),s.nextFrame(()=>{Ds(r,...w),na(r,...t),s.add(n_(r,o=>(Ds(r,...t,...d),na(r,...x),c(o))))}),s.add(()=>Ds(r,...d,...w,...t,...x)),s.add(()=>c("cancelled")),s.dispose}function zn(r=""){return r.split(/\s+/).filter(d=>d.length>1)}let El=Symbol("TransitionContext");var o_=(r=>(r.Visible="visible",r.Hidden="hidden",r))(o_||{});function s_(){return Ht(El,null)!==null}function i_(){let r=Ht(El,null);if(r===null)throw new Error("A is used but it is missing a parent .");return r}function a_(){let r=Ht(Tl,null);if(r===null)throw new Error("A is used but it is missing a parent .");return r}let Tl=Symbol("NestingContext");function ji(r){return"children"in r?ji(r.children):r.value.filter(({state:d})=>d==="visible").length>0}function mh(r){let d=mt([]),w=mt(!1);Qr(()=>w.value=!0),us(()=>w.value=!1);function t(v,s=An.Hidden){let c=d.value.findIndex(({id:o})=>o===v);c!==-1&&(Jn(s,{[An.Unmount](){d.value.splice(c,1)},[An.Hidden](){d.value[c].state="hidden"}}),!ji(d)&&w.value&&(r==null||r()))}function x(v){let s=d.value.find(({id:c})=>c===v);return s?s.state!=="visible"&&(s.state="visible"):d.value.push({id:v,state:"visible"}),()=>t(v,An.Unmount)}return{children:d,register:x,unregister:t}}let yh=ni.RenderStrategy,l_=pr({props:{as:{type:[Object,String],default:"div"},show:{type:[Boolean],default:null},unmount:{type:[Boolean],default:!0},appear:{type:[Boolean],default:!1},enter:{type:[String],default:""},enterFrom:{type:[String],default:""},enterTo:{type:[String],default:""},entered:{type:[String],default:""},leave:{type:[String],default:""},leaveFrom:{type:[String],default:""},leaveTo:{type:[String],default:""}},emits:{beforeEnter:()=>!0,afterEnter:()=>!0,beforeLeave:()=>!0,afterLeave:()=>!0},setup(r,{emit:d,attrs:w,slots:t,expose:x}){let v=mt(0);function s(){v.value|=Ir.Opening,d("beforeEnter")}function c(){v.value&=~Ir.Opening,d("afterEnter")}function o(){v.value|=Ir.Closing,d("beforeLeave")}function u(){v.value&=~Ir.Closing,d("afterLeave")}if(!s_()&&R1())return()=>rr(gh,{...r,onBeforeEnter:s,onAfterEnter:c,onBeforeLeave:o,onAfterLeave:u},t);let g=mt(null),p=jt(()=>r.unmount?An.Unmount:An.Hidden);x({el:g,$el:g});let{show:n,appear:i}=i_(),{register:a,unregister:h}=a_(),y=mt(n.value?"visible":"hidden"),l={value:!0},f=_i(),m={value:!1},b=mh(()=>{!m.value&&y.value!=="hidden"&&(y.value="hidden",h(f),u())});Qr(()=>{let A=a(f);us(A)}),ln(()=>{if(p.value===An.Hidden&&f){if(n.value&&y.value!=="visible"){y.value="visible";return}Jn(y.value,{hidden:()=>h(f),visible:()=>a(f)})}});let j=zn(r.enter),k=zn(r.enterFrom),E=zn(r.enterTo),M=zn(r.entered),P=zn(r.leave),L=zn(r.leaveFrom),C=zn(r.leaveTo);Qr(()=>{ln(()=>{if(y.value==="visible"){let A=Ft(g);if(A instanceof Comment&&A.data==="")throw new Error("Did you forget to passthrough the `ref` to the actual DOM node?")}})});function I(A){let N=l.value&&!i.value,F=Ft(g);!F||!(F instanceof HTMLElement)||N||(m.value=!0,n.value&&s(),n.value||o(),A(n.value?Bc(F,j,k,E,M,B=>{m.value=!1,B===Ba.Finished&&c()}):Bc(F,P,L,C,M,B=>{m.value=!1,B===Ba.Finished&&(ji(b)||(y.value="hidden",h(f),u()))})))}return Qr(()=>{In([n],(A,N,F)=>{I(F),l.value=!1},{immediate:!0})}),Wr(Tl,b),ch(jt(()=>Jn(y.value,{visible:Ir.Open,hidden:Ir.Closed})|v.value)),()=>{let{appear:A,show:N,enter:F,enterFrom:B,enterTo:q,entered:V,leave:H,leaveFrom:Z,leaveTo:ee,...ue}=r,T={ref:g},D={...ue,...i.value&&n.value&&wi.isServer?{class:Yn([w.class,ue.class,...j,...k])}:{}};return To({theirProps:D,ourProps:T,slot:{},slots:t,attrs:w,features:yh,visible:y.value==="visible",name:"TransitionChild"})}}}),u_=l_,gh=pr({inheritAttrs:!1,props:{as:{type:[Object,String],default:"div"},show:{type:[Boolean],default:null},unmount:{type:[Boolean],default:!0},appear:{type:[Boolean],default:!1},enter:{type:[String],default:""},enterFrom:{type:[String],default:""},enterTo:{type:[String],default:""},entered:{type:[String],default:""},leave:{type:[String],default:""},leaveFrom:{type:[String],default:""},leaveTo:{type:[String],default:""}},emits:{beforeEnter:()=>!0,afterEnter:()=>!0,beforeLeave:()=>!0,afterLeave:()=>!0},setup(r,{emit:d,attrs:w,slots:t}){let x=jl(),v=jt(()=>r.show===null&&x!==null?(x.value&Ir.Open)===Ir.Open:r.show);ln(()=>{if(![!0,!1].includes(v.value))throw new Error('A is used but it is missing a `:show="true | false"` prop.')});let s=mt(v.value?"visible":"hidden"),c=mh(()=>{s.value="hidden"}),o=mt(!0),u={show:v,appear:jt(()=>r.appear||!o.value)};return Qr(()=>{ln(()=>{o.value=!1,v.value?s.value="visible":ji(c)||(s.value="hidden")})}),Wr(Tl,c),Wr(El,u),()=>{let g=hh(r,["show","appear","unmount","onBeforeEnter","onBeforeLeave","onAfterEnter","onAfterLeave"]),p={unmount:r.unmount};return To({ourProps:{...p,as:"template"},theirProps:{},slot:{},slots:{...t,default:()=>[rr(u_,{onBeforeEnter:()=>d("beforeEnter"),onAfterEnter:()=>d("afterEnter"),onBeforeLeave:()=>d("beforeLeave"),onAfterLeave:()=>d("afterLeave"),...w,...p,...g},t.default)]},attrs:{},features:yh,visible:s.value==="visible",name:"Transition"})}}});const c_=(r,d)=>{const w=r.__vccOpts||r;for(const[t,x]of d)w[t]=x;return w},d_={},f_={class:"flex min-h-screen flex-col bg-background font-display"},h_={class:"mt-4 flex-1"},p_={class:"flex justify-center"},m_=Lt("div",{class:"rounded-xl bg-black/50 p-6 text-center shadow-lg"},[Lt("div",{class:"text-6xl font-extrabold tracking-widest text-white"}," Yikes! "),Lt("div",{class:"text-base text-gray-200"}," Either the page you're looking for doesn't exist, or something has gone terribly wrong. ")],-1);function y_(r,d){const w=e_,t=gh;return Gr(),ci("body",f_,[pt(w),Lt("main",h_,[Lt("div",p_,[pt(t,{show:"",appear:"",as:"template",enter:"transition transform duration-300 ease-out","enter-from":"translate-x-8 opacity-0","enter-to":"translate-x-0 opacity-100",leave:"transition transform duration-300 ease-in","leave-from":"opacity-100","leave-to":"-translate-x-8 opacity-0"},{default:Ur(()=>[m_]),_:1})])])])}const g_=c_(d_,[["render",y_]]),Gc={__name:"nuxt-root",setup(r){const d=()=>null,w=It(),t=w.deferHydration();if(w.isHydrating){const c=w.hooks.hookOnce("app:error",t);qr().beforeEach(c)}const x=!1;Wr(ps,mi()),w.hooks.callHookWith(c=>c.map(o=>o()),"vue:setup");const v=yi();kd((c,o,u)=>{if(w.hooks.callHook("vue:error",c,o,u).catch(g=>console.error("[nuxt] Error in `vue:error` hook",g)),Cg(c)&&(c.fatal||c.unhandled))return w.runWithContext(()=>lo(c)),!1});const s=!1;return(c,o)=>(Gr(),Xn(nl,{onResolve:Bt(t)},{default:Ur(()=>[Bt(v)?(Gr(),Xn(Bt(g_),{key:0,error:Bt(v)},null,8,["error"])):Bt(s)?(Gr(),Xn(Bt(d),{key:1,context:Bt(s)},null,8,["context"])):Bt(x)?(Gr(),Xn(Fp(Bt(x)),{key:2})):(Gr(),Xn(Bt(o1),{key:3}))]),_:1},8,["onResolve"]))}};let Vc;{let r;Vc=async function(){var s,c;if(r)return r;const t=!!((s=window.__NUXT__)!=null&&s.serverRendered||((c=document.getElementById("__NUXT_DATA__"))==null?void 0:c.dataset.ssr)==="true")?ly(Gc):ay(Gc),x=hg({vueApp:t});async function v(o){await x.callHook("app:error",o),x.payload.error=x.payload.error||gi(o)}t.config.errorHandler=v;try{await mg(x,Yb)}catch(o){v(o)}try{await x.hooks.callHook("app:created",t),await x.hooks.callHook("app:beforeMount",t),t.mount(Mv),await x.hooks.callHook("app:mounted",t),await Fr()}catch(o){v(o)}return t.config.errorHandler===v&&(t.config.errorHandler=void 0),t},r=Vc().catch(d=>{throw console.error("Error while mounting app:",d),d})}export{Eo as $,P_ as A,x_ as B,C_ as C,hr as D,Fr as E,gr as F,_v as G,pi as H,E_ as I,Qs as J,rr as K,rt as L,Tp as M,It as N,w_ as O,Iy as P,Zu as Q,hi as R,gh as S,fs as T,fi as U,O_ as V,Ko as W,zp as X,v_ as Y,gi as Z,a1 as _,Bt as a,Qh as a0,bt as a1,Dp as a2,vo as a3,ar as a4,Ks as a5,__ as a6,S_ as a7,qa as a8,Fp as a9,e_ as aa,Rs as ab,Lt as b,ci as c,pr as d,M_ as e,Xn as f,Ur as g,ao as h,pt as i,mt as j,jt as k,c_ as l,k_ as m,Yn as n,Gr as o,Qr as p,l_ as q,j_ as r,In as s,$h as t,mi as u,ls as v,T_ as w,us as x,b_ as y,Bn as z}; diff --git a/_nuxt/_Au1_THb.js b/_nuxt/_Au1_THb.js new file mode 100644 index 00000000..28ea151a --- /dev/null +++ b/_nuxt/_Au1_THb.js @@ -0,0 +1 @@ +import{l as e,o as r,c}from"./YC8jgtvV.js";const o={};function t(n,s){return r(),c("hr")}const _=e(o,[["render",t]]);export{_ as default}; diff --git a/_nuxt/builds/latest.json b/_nuxt/builds/latest.json index f7bbeab8..f2a5acb7 100644 --- a/_nuxt/builds/latest.json +++ b/_nuxt/builds/latest.json @@ -1 +1 @@ -{"id":"e858341f-e36c-4a7e-a593-6a1877733ce0","timestamp":1718891167294} \ No newline at end of file +{"id":"ec692c5a-cbf0-4ead-bb7d-a040a1fc0357","timestamp":1720229301945} \ No newline at end of file diff --git a/_nuxt/builds/meta/e858341f-e36c-4a7e-a593-6a1877733ce0.json b/_nuxt/builds/meta/e858341f-e36c-4a7e-a593-6a1877733ce0.json deleted file mode 100644 index 24054f3d..00000000 --- a/_nuxt/builds/meta/e858341f-e36c-4a7e-a593-6a1877733ce0.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"e858341f-e36c-4a7e-a593-6a1877733ce0","timestamp":1718891167294,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":["/playground","/card","/playground/french","/playground/palettes/mountains","/examples/nested_transitions","/playground/conway","/playground/metronome","/playground/audio","/playground/midi","/playground/palettes/variance","/playground/plotter","/playground/tiling","/playground/chords","/playground/matrix","/playground/waves","/","/articles","/articles/nuxt-v3-migration","/articles/migrate-truenas-from-core-to-scale","/articles/podcast-transcription-whispercpp","/articles/vim-fugitive-gpg-pinentry","/articles/reset-ipmi-password-from-host-os","/articles/quick-tip-rerunning-bash-commands","/articles/nuxt-content-rss-feed","/articles/doctl","/articles/ssh-ed25519-sk-yubikey","/articles/fennel-initial-exploration","/articles/unit-testing-micropython-with-mocks","/articles/apu2-firmware-upgrade","/articles/persistent-archlinux-usb","/articles/docker-selinux-volumes"]} \ No newline at end of file diff --git a/_nuxt/builds/meta/ec692c5a-cbf0-4ead-bb7d-a040a1fc0357.json b/_nuxt/builds/meta/ec692c5a-cbf0-4ead-bb7d-a040a1fc0357.json new file mode 100644 index 00000000..dbeff2f9 --- /dev/null +++ b/_nuxt/builds/meta/ec692c5a-cbf0-4ead-bb7d-a040a1fc0357.json @@ -0,0 +1 @@ +{"id":"ec692c5a-cbf0-4ead-bb7d-a040a1fc0357","timestamp":1720229301945,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":["/playground/french","/playground","/card","/playground/palettes/mountains","/examples/nested_transitions","/playground/conway","/playground/midi","/playground/metronome","/playground/matrix","/playground/plotter","/playground/chords","/playground/palettes/variance","/playground/tiling","/playground/audio","/playground/waves","/","/articles","/articles/nuxt-v3-migration","/articles/migrate-truenas-from-core-to-scale","/articles/vim-fugitive-gpg-pinentry","/articles/podcast-transcription-whispercpp","/articles/doctl","/articles/nuxt-content-rss-feed","/articles/reset-ipmi-password-from-host-os","/articles/ssh-ed25519-sk-yubikey","/articles/quick-tip-rerunning-bash-commands","/articles/fennel-initial-exploration","/articles/unit-testing-micropython-with-mocks","/articles/apu2-firmware-upgrade","/articles/docker-selinux-volumes","/articles/persistent-archlinux-usb"]} \ No newline at end of file diff --git a/_nuxt/B_2hsy3K.js b/_nuxt/c-8mvODc.js similarity index 78% rename from _nuxt/B_2hsy3K.js rename to _nuxt/c-8mvODc.js index b8c838a5..5b340733 100644 --- a/_nuxt/B_2hsy3K.js +++ b/_nuxt/c-8mvODc.js @@ -1 +1 @@ -import n from"./BTH0oiOj.js";import{d as c,I as l,K as u}from"./D6y6W-Zj.js";import"./T8qFVnUA.js";import"./ElOT_Ul4.js";import"./DvDH6DOc.js";import"./DXU4rfre.js";const p=(r,t)=>u("pre",null,JSON.stringify({message:"You should use slots with ",slot:r,data:t},null,2)),h=c({name:"ContentList",props:{path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0}},render(r){const t=l(),{path:f,query:a}=r,m={...a||{},path:f||(a==null?void 0:a.path)||"/"};return u(n,m,{default:t!=null&&t.default?({data:e,refresh:o,isPartial:d})=>t.default({list:e,refresh:o,isPartial:d,...this.$attrs}):e=>p("default",e.data),empty:e=>t!=null&&t.empty?t.empty(e):p("default",e==null?void 0:e.data),"not-found":e=>{var o;return t!=null&&t["not-found"]?(o=t==null?void 0:t["not-found"])==null?void 0:o.call(t,e):p("not-found",e==null?void 0:e.data)}})}}),i=h;export{i as default}; +import n from"./EFdih8x4.js";import{d as c,I as l,K as u}from"./YC8jgtvV.js";import"./DjmxGRUG.js";import"./NquB2IUV.js";import"./DvDH6DOc.js";import"./JthqPOXk.js";const p=(r,t)=>u("pre",null,JSON.stringify({message:"You should use slots with ",slot:r,data:t},null,2)),h=c({name:"ContentList",props:{path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0}},render(r){const t=l(),{path:f,query:a}=r,m={...a||{},path:f||(a==null?void 0:a.path)||"/"};return u(n,m,{default:t!=null&&t.default?({data:e,refresh:o,isPartial:d})=>t.default({list:e,refresh:o,isPartial:d,...this.$attrs}):e=>p("default",e.data),empty:e=>t!=null&&t.empty?t.empty(e):p("default",e==null?void 0:e.data),"not-found":e=>{var o;return t!=null&&t["not-found"]?(o=t==null?void 0:t["not-found"])==null?void 0:o.call(t,e):p("not-found",e==null?void 0:e.data)}})}}),i=h;export{i as default}; diff --git a/_nuxt/cjxB7njK.js b/_nuxt/cjxB7njK.js new file mode 100644 index 00000000..f3508195 --- /dev/null +++ b/_nuxt/cjxB7njK.js @@ -0,0 +1 @@ +import{l as r,o,c as t,a7 as s}from"./YC8jgtvV.js";const c={};function n(e,a){return o(),t("tr",null,[s(e.$slots,"default")])}const f=r(c,[["render",n]]);export{f as default}; diff --git a/_nuxt/Da1yACaU.js b/_nuxt/eJFH2hOw.js similarity index 64% rename from _nuxt/Da1yACaU.js rename to _nuxt/eJFH2hOw.js index d177fb69..272d74b5 100644 --- a/_nuxt/Da1yACaU.js +++ b/_nuxt/eJFH2hOw.js @@ -1 +1 @@ -import{_ as l}from"./C7cmTvz1.js";import{d as n,o as s,D as i,g as o,b as r,n as g,a8 as u,a7 as d}from"./D6y6W-Zj.js";const h=n({__name:"ProsePre",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null},class:{type:String,default:null},style:{type:[String,Object],default:null}},setup(e){return(a,f)=>{const t=l;return s(),i(t,{code:e.code,language:e.language,filename:e.filename,highlights:e.highlights,meta:e.meta},{default:o(()=>[r("pre",{class:g(a.$props.class),style:u(e.style)},[d(a.$slots,"default")],6)]),_:3},8,["code","language","filename","highlights","meta"])}}});export{h as default}; +import{_ as l}from"./V6DC4L2r.js";import{d as n,o as s,f as i,g as o,b as r,n as g,a8 as u,a7 as f}from"./YC8jgtvV.js";const h=n({__name:"ProsePre",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null},class:{type:String,default:null},style:{type:[String,Object],default:null}},setup(e){return(a,d)=>{const t=l;return s(),i(t,{code:e.code,language:e.language,filename:e.filename,highlights:e.highlights,meta:e.meta},{default:o(()=>[r("pre",{class:g(a.$props.class),style:u(e.style)},[f(a.$slots,"default")],6)]),_:3},8,["code","language","filename","highlights","meta"])}}});export{h as default}; diff --git a/_nuxt/mVZnioK0.js b/_nuxt/mVZnioK0.js deleted file mode 100644 index 79920b9a..00000000 --- a/_nuxt/mVZnioK0.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o,o as r,c as s,a7 as t}from"./D6y6W-Zj.js";const c={};function n(e,a){return r(),s("li",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/mpBF_AdW.js b/_nuxt/mpBF_AdW.js new file mode 100644 index 00000000..d343dcb9 --- /dev/null +++ b/_nuxt/mpBF_AdW.js @@ -0,0 +1 @@ +import{a as d,s as w,u as y,E as D,G as H,H as g,d as S,I as _,J as b,K as p}from"./YC8jgtvV.js";import q from"./Cj9zn9Hh.js";import x from"./EFdih8x4.js";import"./DuCNYxTx.js";import"./C-v3KzvZ.js";import"./Dnd51l0P.js";import"./JthqPOXk.js";import"./DvDH6DOc.js";import"./DjmxGRUG.js";import"./NquB2IUV.js";const a=(u,s=y())=>{const e=d(u),m=g();w(()=>d(u),(n=e)=>{if(!s.path||!n)return;const t=Object.assign({},(n==null?void 0:n.head)||{});t.meta=[...t.meta||[]],t.link=[...t.link||[]];const r=t.title||(n==null?void 0:n.title);r&&(t.title=r),m.public.content.host;const c=(t==null?void 0:t.description)||(n==null?void 0:n.description);c&&t.meta.filter(l=>l.name==="description").length===0&&t.meta.push({name:"description",content:c}),t!=null&&t.image||(n==null||n.image),D(()=>H(t))},{immediate:!0})},$=S({name:"ContentDoc",props:{tag:{type:String,required:!1,default:"div"},excerpt:{type:Boolean,default:!1},path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0},head:{type:Boolean,required:!1,default:void 0}},render(u){const{contentHead:s}=g().public.content,e=_(),{tag:m,excerpt:f,path:n,query:t,head:r}=u,c=r===void 0?s:r,l={...t||{},path:n||(t==null?void 0:t.path)||b(y().path),find:"one"},C=(o,i)=>p("pre",null,JSON.stringify({message:"You should use slots with ",slot:o,data:i},null,2));return p(x,l,{default:e!=null&&e.default?({data:o,refresh:i,isPartial:v})=>{var h;return c&&a(o),(h=e.default)==null?void 0:h.call(e,{doc:o,refresh:i,isPartial:v,excerpt:f,...this.$attrs})}:({data:o})=>(c&&a(o),p(q,{value:o,excerpt:f,tag:m,...this.$attrs},{empty:i=>e!=null&&e.empty?e.empty(i):C("default",o)})),empty:o=>{var i;return((i=e==null?void 0:e.empty)==null?void 0:i.call(e,o))||p("p",null,"Document is empty, overwrite this content with #empty slot in .")},"not-found":o=>{var i;return((i=e==null?void 0:e["not-found"])==null?void 0:i.call(e,o))||p("p",null,"Document not found, overwrite this content with #not-found slot in .")}})}}),G=$;export{G as default}; diff --git a/_nuxt/qnKzmL5n.js b/_nuxt/qnKzmL5n.js deleted file mode 100644 index 6a8279e3..00000000 --- a/_nuxt/qnKzmL5n.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o}from"./CNTXZiWI.js";import"./D6y6W-Zj.js";import"./C-v3KzvZ.js";import"./DXU4rfre.js";import"./DvDH6DOc.js";export{o as default}; diff --git a/_nuxt/vPzKiM2h.js b/_nuxt/vPzKiM2h.js new file mode 100644 index 00000000..fe57bdfc --- /dev/null +++ b/_nuxt/vPzKiM2h.js @@ -0,0 +1 @@ +import{d as p,H as f,k as i,o as t,c as s,a as u,a7 as n}from"./YC8jgtvV.js";const l=["id"],d=["href"],_=p({__name:"ProseH2",props:{id:{}},setup(r){const a=r,{headings:o}=f().public.mdc,c=i(()=>{var e;return a.id&&(typeof(o==null?void 0:o.anchorLinks)=="boolean"&&(o==null?void 0:o.anchorLinks)===!0||typeof(o==null?void 0:o.anchorLinks)=="object"&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h2))});return(e,k)=>(t(),s("h2",{id:e.id},[e.id&&u(c)?(t(),s("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,d)):n(e.$slots,"default",{key:1})],8,l))}});export{_ as default}; diff --git a/_nuxt/yMITBXRA.js b/_nuxt/yMITBXRA.js new file mode 100644 index 00000000..fa68a119 --- /dev/null +++ b/_nuxt/yMITBXRA.js @@ -0,0 +1 @@ +import{l as o,o as r,c as t,a7 as s}from"./YC8jgtvV.js";const c={};function n(e,a){return r(),t("th",null,[s(e.$slots,"default")])}const f=o(c,[["render",n]]);export{f as default}; diff --git a/_payload.json b/_payload.json index 6189ece7..21a14fd9 100644 --- a/_payload.json +++ b/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180654] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314470] \ No newline at end of file diff --git a/api/_content/cache.1718891166808.json b/api/_content/cache.1718891166808.json deleted file mode 100644 index aeda2329..00000000 --- a/api/_content/cache.1718891166808.json +++ /dev/null @@ -1 +0,0 @@ -{"generatedAt":1718891181167,"generateTime":542,"contents":[{"_path":"/articles/apu2-firmware-upgrade","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Upgrading the Firmware on the PCEngines APU2","description":"I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","date":"2019-12-21","draft":false,"tags":["pcengine","apu"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, we will connect to the device over the serial port"}]},{"type":"element","tag":"pre","props":{"code":"screen /dev/tty.usbserial 115200\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"screen /dev/tty.usbserial 115200\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we will install the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"flashrom"}]},{"type":"text","value":" utility that is needed to update the\nfirmware. Because it is not available in the default "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"yum"}]},{"type":"text","value":" repositories, we\nwill enable the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Extra Packages for Enterprise Linux"}]},{"type":"text","value":" (EPEL) repository before\ninstallation."}]},{"type":"element","tag":"pre","props":{"code":"sudo yum install epel-release\nsudo yum install flashrom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" epel-release\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we will download the latest version of the firmware that is compatible\nwith the APU2 device from the PC Engines release website:\n"},{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"curl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, we will flash the firmware..."}]},{"type":"element","tag":"pre","props":{"code":"sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -w"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" apu2_v4.11.0.1.rom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -p"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" internal:boardmismatch=force\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References:"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.ch/apu2.htm"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/elad/openbsd-apu2","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/elad/openbsd-apu2"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:apu2-firmware-upgrade.md","_source":"content","_file":"articles/apu2-firmware-upgrade.md","_extension":"md"},{"_path":"/articles/docker-selinux-volumes","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Docker Volume Permissions with SELinux","description":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","date":"2019-12-26","draft":false,"tags":["docker","selinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]},{"type":"element","tag":"pre","props":{"code":"mkdir: can't create directory '/data': Permission denied\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"mkdir: can't create directory '/data': Permission denied\n"}]}]}]}]},{"type":"element","tag":"hr","props":{},"children":[]},{"type":"element","tag":"pre","props":{"code":"$ docker info --format '{{json .SecurityOptions}}'\n[\n \"name=seccomp,profile=/etc/docker/seccomp.json\",\n \"name=selinux\"\n]\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" docker"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" info"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '{{json .SecurityOptions}}'\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=seccomp,profile=/etc/docker/seccomp.json\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=selinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It turns out that this can be resolved by appending the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":":z"}]},{"type":"text","value":" flag to the volume\nmappings in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"docker-compose.yml"}]},{"type":"text","value":" file, indicating that the volume content\nis shared."}]},{"type":"element","tag":"pre","props":{"code":"services:\n server:\n volumes:\n - ./data:/data:z\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"services:\n server:\n volumes:\n - ./data:/data:z\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From the Docker documentation:"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"z"}]},{"type":"text","value":" option tells Docker that two containers share the volume content. As\na result, Docker labels the content with a shared content label. Shared\nvolume labels allow all containers to read/write content."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/info/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Docker Info"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Mounting Volumes"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:docker-selinux-volumes.md","_source":"content","_file":"articles/docker-selinux-volumes.md","_extension":"md"},{"_path":"/articles/doctl","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Exploring the Digital Ocean `doctl` Utility","description":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","date":"2023-01-01","tags":["linux","digital-ocean"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To start things off, I had to install and setup authentication to Digital Ocean. Doing\nthis on my Mac machine, I opted to use "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"# install `doctl`\nbrew install doctl\n\n# setup authentication\ndoctl auth init\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# install `doctl`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" doctl\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# setup authentication\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" auth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" init\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the online "},{"type":"element","tag":"a","props":{"href":"https://docs.digitalocean.com/reference/doctl/reference/compute/droplet/create/","rel":["nofollow"]},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":" is fantastic, I instead found myself mostly referencing the outputs of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--help"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create --help\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --help\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I had to find the image name of the version of Ubuntu I wanted to install:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute image list --public | grep ubuntu-22\n\n# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --public"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" grep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And also the slug of the compute size:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute size list\n\n# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've also configured a few SSH keys with Digital Ocean, and I can have the key (specified by ID) provisioned to the machine using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--ssh-keys"}]},{"type":"text","value":" flag."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh-key list\n\n# ID Name FingerPrint\n# 1234 mini \n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# ID Name FingerPrint\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 1234 mini \n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Also, I wanted to install a few packages to the box upon creation, this can be done easily with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--user-data-file"}]},{"type":"text","value":" flag to run an initialization script."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"echo 'apt install -y imagemagick zip' > bootstrap.sh\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'apt install -y imagemagick zip'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" >"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bootstrap.sh\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Putting it all together, here is the simple command for creating a small compute instance!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create \\\n --image ubuntu-22-10-x64 \\\n --size s-1vcpu-512mb-10gb \\\n --region nyc1 \\\n --ssh-keys 1234 \\\n --user-data-file boostrap.sh \\\n ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22-10-x64"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" s-1vcpu-512mb-10gb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --region"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" nyc1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --ssh-keys"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --user-data-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" boostrap.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, I can connect, do my thing, and destroy the instance."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet delete --force ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" delete"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --force"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"All-in-all, I was up and running in about 20 minutes. What a handy utility!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:doctl.md","_source":"content","_file":"articles/doctl.md","_extension":"md"},{"_path":"/articles/fennel-initial-exploration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Impressions of Fennel with Hammerspoon","description":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","draft":false,"date":"2023-10-22","tags":["lisp","hammerspoon","fennel"],"categories":["lisp"],"cover_image":"/images/dall-e-fennel-hammer.jpeg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Fennel"}]},{"type":"text","value":" programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: "},{"type":"element","tag":"a","props":{"href":"https://www.hammerspoon.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Hammerspoon"}]},{"type":"text","value":", and "},{"type":"element","tag":"a","props":{"href":"https://neovim.io/","rel":["nofollow"]},"children":[{"type":"text","value":"Neovim"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"initial-observations"},"children":[{"type":"text","value":"Initial Observations"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/tree/795749fa17e1310bb001bb7deaa22be8689f0027/hammerspoon/.hammerspoon/modules","rel":["nofollow"]},"children":[{"type":"text","value":"modules"}]},{"type":"text","value":" that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project..."}]},{"type":"element","tag":"h2","props":{"id":"integrating-fennel-with-hammerspoon"},"children":[{"type":"text","value":"Integrating Fennel with Hammerspoon"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While official documentation exists describing how to "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/setup#embedding-fennel","rel":["nofollow"]},"children":[{"type":"text","value":"embed fennel"}]},{"type":"text","value":" into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.path"}]},{"type":"text","value":" and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.cpath"}]},{"type":"text","value":" properties in Lua, but I was unable to get this to\nwork."}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://blog.exupero.org/hammerspoon-with-fennel/","rel":["nofollow"]},"children":[{"type":"text","value":"https://blog.exupero.org/hammerspoon-with-fennel/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer/blob/master/init.lua","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/agzam/spacehammer/blob/master/init.lua"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Ultimately, I opted to include the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.lua"}]},{"type":"text","value":" file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.path"}]},{"type":"text","value":" to point to the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"*.fnl"}]},{"type":"text","value":" files in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":".hammerspoon/"}]},{"type":"text","value":" directory, and\nttranslating these modules can begin!"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"/.hammerspoon/?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"-- init.lua\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"local"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" fennel "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'fennel'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" .."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \";\" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.getenv"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"HOME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"/.hammerspoon/?.fnl\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"table.insert"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"package.loaders"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" or"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.searchers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"searcher"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'main'\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"translating-lua-to-fennel"},"children":[{"type":"text","value":"Translating Lua to Fennel"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/see","rel":["nofollow"]},"children":[{"type":"text","value":"anti-fennel"}]},{"type":"text","value":", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sleep"}]},{"type":"text","value":" function\nfrom the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"helpers"}]},{"type":"text","value":" module into the compiler:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"function sleep(ms)\n os.execute(\"sleep \" .. tonumber(ms) / 1000)\nend\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.execute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" tonumber"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(fn sleep [ms]\n (os.execute (.. \"sleep \" (/ (tonumber ms) 1000))))\n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(fn "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [ms]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (os.execute (.. "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (tonumber ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As another example, here is the output for my "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"caffeine"}]},{"type":"text","value":" toggle:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"hs.hotkey.bind(HYPER, \"0\", function()\n hs.caffeinate.toggle(\"displayIdle\")\n if hs.caffeinate.get(\"displayIdle\") then\n helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n else\n helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n end\nend)\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hotkey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"bind"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(HYPER, "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"0\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"toggle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"get"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"then\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"success"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"check"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" else\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ban"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(hs.hotkey.bind HYPER :0\n (fn [] (hs.caffeinate.toggle :displayIdle)\n (if (hs.caffeinate.get :displayIdle)\n (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban)))) \n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(hs.hotkey.bind HYPER "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":0\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (fn [] (hs.caffeinate.toggle "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (hs.caffeinate.get "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.success helpers.assets.check)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.error helpers.assets.ban))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This was especially helpful for more gnarly modules like the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"window"}]},{"type":"text","value":" module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!"}]},{"type":"element","tag":"h2","props":{"id":"next-steps"},"children":[{"type":"text","value":"Next Steps"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Additionally, before beginning this endeavor, I was already aware of projects like\n"},{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer","rel":["nofollow"]},"children":[{"type":"text","value":"spacehammer"}]},{"type":"text","value":"; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/pull/19/files","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/cmpadden/dotfiles/pull/19/files"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"initial-observations","depth":2,"text":"Initial Observations"},{"id":"integrating-fennel-with-hammerspoon","depth":2,"text":"Integrating Fennel with Hammerspoon"},{"id":"translating-lua-to-fennel","depth":2,"text":"Translating Lua to Fennel"},{"id":"next-steps","depth":2,"text":"Next Steps"}]}},"_type":"markdown","_id":"content:articles:fennel-initial-exploration.md","_source":"content","_file":"articles/fennel-initial-exploration.md","_extension":"md"},{"_path":"/articles/migrate-truenas-from-core-to-scale","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Migrate to TrueNAS Scale from TrueNAS Core","description":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","date":"2021-12-28","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":" in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Make a backup of your system’s configuration\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"System > General"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save Config"}]},{"type":"text","value":", check the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Export Secret Seed"}]},{"type":"text","value":" box, and click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Export dataset keys for the encrypted pools\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Storage > Pools"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click the cog icon, and select "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Export Dataset Keys"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Insert the TrueNAS Core bootable USB into the NAS"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the Supermicro IPMI interface select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Remote Control"}]},{"type":"text","value":" and "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"iKVM/HTML5"}]},{"type":"text","value":" and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Reboot"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Select the bootable USB as the boot device"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the TrueNAS installation wizard, select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":", select the drive that contains the TrueNAS installation, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Upgrade Install"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference "},{"type":"element","tag":"a","props":{"href":"https://www.truenas.com/help-me-choose/","rel":["nofollow"]},"children":[{"type":"text","value":"this table"}]},{"type":"text","value":"."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:migrate-truenas-from-core-to-scale.md","_source":"content","_file":"articles/migrate-truenas-from-core-to-scale.md","_extension":"md"},{"_path":"/articles/nuxt-content-rss-feed","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"How To Add an RSS Feed to a Nuxt Website","description":"If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","draft":false,"date":"2024-01-06","tags":["nuxt","rss"],"categories":["programming"],"cover_image":"/images/nuxt-content-rss-feed.jpg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In version 2 of Nuxt, the community module, "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module","rel":["nofollow"]},"children":[{"type":"text","value":"nuxt-community/feed-module"}]},{"type":"text","value":" was a popular choice for adding an RSS feed to your website. However, there has been an unresolved "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module/issues/106","rel":["nofollow"]},"children":[{"type":"text","value":"open issue"}]},{"type":"text","value":" since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward."}]},{"type":"element","tag":"h2","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, install the "},{"type":"element","tag":"a","props":{"href":"https://www.npmjs.com/package/feed","rel":["nofollow"]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library into your project:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D feed\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" feed\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/"}]},{"type":"text","value":" folder in your project if it does not already exist, and create a file named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/atom.ts"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Here, we will leverage the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library and construct an XML representation of our Nuxt content. As you can see, we first define our "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"serverQueryContent"}]},{"type":"text","value":" and append a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed.addItem"}]},{"type":"text","value":" for each article."}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { Feed } from 'feed';\n\nconst BASE_URL = \"https://mywebsite.com\"\nconst AUTHOR_NAME = \"Firstname Lastname\"\n\nexport default defineEventHandler(async (event) => {\n\n const feed = new Feed({\n title: \"My Title\",\n description: \"My Description\",\n id: BASE_URL,\n link: BASE_URL,\n language: \"en\",\n image: `${BASE_URL}/images/placeholder.png`,\n favicon: `${BASE_URL}/favicon.ico`,\n copyright: `All rights reserved ${new Date().getFullYear()}, ${AUTHOR_NAME}`,\n updated: new Date(),\n generator: \"Nuxt static site generation + Feed for Node.js\",\n feedLinks: {\n atom: `${BASE_URL}/atom`\n },\n author: {\n name: AUTHOR_NAME,\n }\n });\n\n const articles = await serverQueryContent(event).find();\n\n articles.forEach((article) => {\n feed.addItem({\n title: article.title ? article.title : \"Missing Title\",\n id: article._path,\n link: `${BASE_URL}${article._path}`,\n description: article.description,\n author: [\n {\n name: AUTHOR_NAME,\n },\n ],\n date: new Date(article.date),\n image: article.cover_image ? `${BASE_URL}/${article.cover_image}` : undefined\n });\n });\n\n return feed.atom1();\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { Feed } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'feed'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://mywebsite.com\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Firstname Lastname\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Description\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" language: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"en\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/images/placeholder.png`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" favicon: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/favicon.ico`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" copyright: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`All rights reserved ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"getFullYear"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}, ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" updated: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":19},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" generator: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Nuxt static site generation + Feed for Node.js\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":20},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feedLinks: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":21},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" atom: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/atom`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":22},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":23},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":24},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":25},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":26},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":27},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":28},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":29},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":30},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":31},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"addItem"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":32},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Missing Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":33},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: article._path,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":34},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"_path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":35},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: article.description,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":36},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: [\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":37},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":38},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":39},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":40},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ],\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":41},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" date: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(article.date),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":42},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: article.cover_image "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" `${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"cover_image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" :"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" undefined\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":43},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":44},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":45},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":46},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"atom1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":47},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's just about it! Except, if you are statically generating your website with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt generate"}]},{"type":"text","value":" command, you will need to configure this server-side route to be pre-rendered on site generation. This is as simple as adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nitro"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" definition in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":" file, like so:"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"bonus"},"children":[{"type":"text","value":"Bonus"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may also be interested in adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sitemap.xml"}]},{"type":"text","value":" to your website. This can be done in almost an identical fashion!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Install the dependency:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D sitemap\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sitemap\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a route at "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/sitemap.xml.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { SitemapStream, streamToPromise } from 'sitemap';\n\nexport default defineEventHandler(async (event) => {\n const articles = await serverQueryContent(event).find();\n\n const sitemap = new SitemapStream({ hostname: 'https://my-website.com/' });\n\n // Add non nuxt content endpoints here\n sitemap.write({ url: '/' });\n sitemap.write({ url: '/articles' });\n\n // Dynamically generate routes for Nuxt markdown content\n articles.forEach((article) => sitemap.write({ url: article._path, changefreq: 'monthly' }));\n sitemap.end();\n\n return (await streamToPromise(sitemap));\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { SitemapStream, streamToPromise } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'sitemap'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" sitemap"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" SitemapStream"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ hostname: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'https://my-website.com/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Add non nuxt content endpoints here\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/articles'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Dynamically generate routes for Nuxt markdown content\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: article._path, changefreq: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'monthly'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" streamToPromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(sitemap));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And add the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" entry in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/sitemap.xml', '/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/sitemap.xml'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"instructions","depth":2,"text":"Instructions"},{"id":"bonus","depth":2,"text":"Bonus"}]}},"_type":"markdown","_id":"content:articles:nuxt-content-rss-feed.md","_source":"content","_file":"articles/nuxt-content-rss-feed.md","_extension":"md"},{"_path":"/articles/nuxt-v3-migration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"This Website Has Been Migrated to Nuxt 3 🎉","description":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","date":"2022-12-31","tags":["nuxt"],"categories":["web"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you're curious what changes were required to make the migration, you can check out "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/cmpadden.github.io/pull/3","rel":["nofollow"]},"children":[{"type":"text","value":"pull request #3"}]},{"type":"text","value":" in the GitHub repository."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"img","props":{"alt":"Screenshot of Nuxt Migration Pull Request","src":"/images/nuxt-migration-pr.png"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious.\nFor this reason, I opted to generate a new project entirely, and port existing code to this clean slate.\nI believe that this resulted in a project with a bit less cruft."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The most valuable resources for making these changes include:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/migration/overview","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Migration Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/getting-started/introduction","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Framework Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://tailwindcss.nuxt.dev/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Tailwind Module Documentation"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content Module Documentation"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Part of the delay for doing this upgrade was in waiting for module developers to support this major release.\nI'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available!\nI just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:nuxt-v3-migration.md","_source":"content","_file":"articles/nuxt-v3-migration.md","_extension":"md"},{"_path":"/articles/persistent-archlinux-usb","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Create a Persistent Arch Linux Bootable USB with Vagrant","description":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","date":"2020-01-09","draft":false,"tags":["vagrant","archlinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]},{"type":"element","tag":"h1","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The original intention was to use Docker for this process -- leveraging the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--device"}]},{"type":"text","value":" flag and mounting the target USB device in the Docker container,\nbut the underlying hypervisor in Docker Desktop for Mac does not support this.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"2"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"3"}]}]},{"type":"text","value":" While there are workarounds using Docker\nMachine, Vagrant felt like the path of least resistance."}]},{"type":"element","tag":"h1","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"h2","props":{"id":"create-an-arch-linux-virtual-machine-with-vagrant"},"children":[{"type":"text","value":"Create an Arch Linux Virtual Machine with Vagrant"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Get the latest Arch Linux image "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"4"}]}]},{"type":"text","value":" from the Vagrant Cloud Box\nCatalog."}]},{"type":"element","tag":"pre","props":{"code":"vagrant box add archlinux/archlinux\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" box"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" add"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" archlinux/archlinux\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Determine the USB vendor information for the thumb-drive that we will\npass-through to the virtual machine. Using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" utility that comes\nwith Virtual Box, list the devices, and make note of the Vendor and Product ID."}]},{"type":"element","tag":"pre","props":{"code":" VBoxManage list usbhost\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" VBoxManage"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" usbhost\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Vagrantfile"}]},{"type":"text","value":" with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"archlinx/archlinux"}]},{"type":"text","value":" as the target box, and the USB\ndevice information that is passed through. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"6"}]}]},{"type":"text","value":" Vagrant\noffers a handy customization parameter "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" that calls the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" command under-the-hood, allowing one to enable the guest machine\nto access the host machine's USB devices."}]},{"type":"element","tag":"pre","props":{"code":"# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\nVagrant.configure(\"2\") do |config|\n config.vm.box = \"archlinux/archlinux\"\n config.vm.provider \"virtualbox\" do |vb|\n vb.name = \"archlinux\"\n vb.customize ['modifyvm', :id, '--usb', 'on']\n vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n end\nend\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# -*- mode: ruby -*-\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# vi: set ft=ruby :\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Vagrant.configure(\"2\") do |config|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.box = \"archlinux/archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.provider \"virtualbox\" do |vb|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.name = \"archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['modifyvm', :id, '--usb', 'on']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When virtual machine is brought up, the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"usbfilter"}]},{"type":"text","value":" is applied, and the guest\nis able to access to the host machine's USB device that was specified in the\nfilter."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Start the machine, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" into the guest, and list the devices to confirm that\nthe USB device is available (see: "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"/dev/sdb"}]},{"type":"text","value":")."}]},{"type":"element","tag":"pre","props":{"code":"$ vagrant up\n$ vagrant ssh\n[vagrant@archlinux ~]$ lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 20G 0 disk\n├─sda1 8:1 0 1.9G 0 part [SWAP]\n└─sda2 8:2 0 18.1G 0 part /\nsdb 8:16 1 28.7G 0 disk\n└─sdb1 8:17 1 8G 0 part\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" up\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[vagrant@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]$ lsblk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MAJ:MIN"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RM"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" SIZE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RO"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" TYPE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MOUNTPOINT\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sda"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 20G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"├─sda1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 1.9G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [SWAP]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sda2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 18.1G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" /\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sdb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:16"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 28.7G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sdb1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:17"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"install-arch-linux-on-the-usb-drive"},"children":[{"type":"text","value":"Install Arch Linux on the USB Drive"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Installation Guide"}]},{"type":"text","value":" outlines the installation procedure in\ngreat detail -- the following steps follow this closely with a few alteration\ndue to installing onto removable media."}]},{"type":"element","tag":"h3","props":{"id":"partition-the-disk-uefi-with-gpt"},"children":[{"type":"text","value":"Partition the Disk (UEFI with GPT)"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# fdisk /dev/sdb\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# fdisk /dev/sdb\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command (m for help): p\nDisk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\nDisk model: Ultra Fit\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 1050623 1048576 512M EFI System\n/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n\nFilesystem/RAID signature on partition 1 will be wiped.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command (m for help): p\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk model: Ultra Fit\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Units: sectors of 1 * 512 = 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Sector size (logical/physical): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"I/O size (minimum/optimal): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disklabel type: gpt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Device Start End Sectors Size Type\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb1 2048 1050623 1048576 512M EFI System\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Filesystem/RAID signature on partition 1 will be wiped.\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"format-the-partitions"},"children":[{"type":"text","value":"Format the Partitions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The UEFI specification mandates support for FAT file-systems, and FAT32 is\nrecommended for removable media. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"7"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -Sy dosfstools\n[root@archlinux ~]# mkfs.fat -F32 /dev/sdb1\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -Sy dosfstools\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.fat -F32 /dev/sdb1\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for the root partition, it is recommended to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ext4"}]},{"type":"text","value":" without a journal to\nreduce the reads and writes to the file-system as this is detrimental to the\nflash-based USB drive. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"8"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mkfs.ext4 -O \"^has_journal\" /dev/sdb2\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.ext4 -O "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"^has_journal\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /dev/sdb2\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"mount-the-partitions-and-bootstrap-the-environment"},"children":[{"type":"text","value":"Mount the Partitions and Bootstrap the Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mount /dev/sdb2 /mnt\n[root@archlinux ~]# mkdir -p /mnt/boot/efi\n[root@archlinux ~]# mount /dev/sdb1 /mnt/boot/efi\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb2 /mnt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkdir -p /mnt/boot/efi\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb1 /mnt/boot/efi\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -S arch-install-scripts\n[root@archlinux ~]# pacstrap /mnt base linux linux-firmware\n[root@archlinux ~]# genfstab -U /mnt >> /mnt/etc/fstab\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -S arch-install-scripts\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacstrap /mnt base linux linux-firmware\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# genfstab -U /mnt "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":">>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /mnt/etc/fstab\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"configure-the-new-environment"},"children":[{"type":"text","value":"Configure the New Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# arch-chroot /mnt\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux ~]# arch-chroot /mnt\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Note, one difference here from a standard installation is that the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--removable"}]},{"type":"text","value":" flag is specified when installing the GRUB bootloader.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"10"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Shutdown the virtual machine, restart the host machine, and boot the newly\ncreated Arch Linux thumb-drive!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"🎉"}]},{"type":"element","tag":"h2","props":{"id":"side-note"},"children":[{"type":"text","value":"Side-note"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It was attempted to use the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"controlvm usbattach"}]},{"type":"text","value":" command to pass the USB\ndevice to the guest machine, but this did not work as it expects the virtual\nmachine to already be running, and the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" option runs prior to\nbooting the machine. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"11"}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n\nStderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Desktop on Mac vs. Docker Toolbox"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - HyperKit"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - Docker for Mac - Issue #900"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant Cloud - Arch Linux"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"Attaching USB Devices to VirtualBox Guests using VBoxManage"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub Gist - Vagrant USB Filter"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - EFI System Partition - Format Partitions"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Arch Linux on USB - Installation Tweaks"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Installation Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - GRUB - UEFI Systems"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant VBoxManage Customizations "}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"create-an-arch-linux-virtual-machine-with-vagrant","depth":2,"text":"Create an Arch Linux Virtual Machine with Vagrant"},{"id":"install-arch-linux-on-the-usb-drive","depth":2,"text":"Install Arch Linux on the USB Drive","children":[{"id":"partition-the-disk-uefi-with-gpt","depth":3,"text":"Partition the Disk (UEFI with GPT)"},{"id":"format-the-partitions","depth":3,"text":"Format the Partitions"},{"id":"mount-the-partitions-and-bootstrap-the-environment","depth":3,"text":"Mount the Partitions and Bootstrap the Environment"},{"id":"configure-the-new-environment","depth":3,"text":"Configure the New Environment"}]},{"id":"side-note","depth":2,"text":"Side-note"},{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:persistent-archlinux-usb.md","_source":"content","_file":"articles/persistent-archlinux-usb.md","_extension":"md"},{"_path":"/articles/podcast-transcription-whispercpp","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Easily Transcribe Podcasts with Whisper.cpp","description":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","draft":false,"date":"2024-01-08","tags":["whisper.cpp","ml"],"categories":["programming"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]},{"type":"element","tag":"h2","props":{"id":"obtain-audio-files"},"children":[{"type":"text","value":"Obtain Audio File(s)"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, let's get the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" file from YouTube using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"youtube-dl"}]},{"type":"text","value":" utility. It should be noted that "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" filetypes, and this utility defaults to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"mp3"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":" $ youtube-dl \\\n --extract-audio \\\n --audio-format wav \\\n --output podcast.wav \\\n \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" youtube-dl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --extract-audio"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --audio-format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This file has a 44.1 kHz sample rate, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects 16 kHz, so let's go ahead and convert that."}]},{"type":"element","tag":"pre","props":{"code":" $ file podcast.wav\npodcast.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n\n $ ffmpeg -i podcast.wav -ar 16000 podcast-16khz.wav\n\n $ file podcast-16khz.wav\npodcast-16khz.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n\n# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n# flag to the `youtube-dl` command -- I will explore this further next time...\n# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ffmpeg"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -ar"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 16000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast-16khz.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# flag to the `youtube-dl` command -- I will explore this further next time...\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"build-whispercpp-transcribe-audio"},"children":[{"type":"text","value":"Build "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" & Transcribe Audio"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's get the latest version of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":", download the English Whisper model, and build the example."}]},{"type":"element","tag":"pre","props":{"code":"# Clone the `whisper.cpp` repository\n $ git clone --depth 1 git@github.com:ggerganov/whisper.cpp && cd whisper.cpp\n\n# Download the English Whisper model in `ggml` format\n $ bash ./models/download-ggml-model.sh base.en\n\n# Build the main example\n $ make\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Clone the `whisper.cpp` repository\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" clone"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --depth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git@github.com:ggerganov/whisper.cpp"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" && "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"cd"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" whisper.cpp\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Download the English Whisper model in `ggml` format\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bash"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./models/download-ggml-model.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" base.en\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Build the main example\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" make\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, let's transcribe that podcast!"}]},{"type":"element","tag":"pre","props":{"code":" $ ./main \\\n -m ~/workspace/whisper.cpp/models/ggml-base.en.bin \\\n -f ~/Downloads/podcast-16khz.wav \\\n --output-vtt \\\n --output-file out\n\n# whisper_print_timings: load time = 114.71 ms\n# whisper_print_timings: fallbacks = 0 p / 0 h\n# whisper_print_timings: mel time = 692.20 ms\n# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n# whisper_print_timings: total time = 80709.54 ms\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./main"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -m"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/workspace/whisper.cpp/models/ggml-base.en.bin"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -f"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/Downloads/podcast-16khz.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-vtt"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" out\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: load time = 114.71 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: fallbacks = 0 p / 0 h\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: mel time = 692.20 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: total time = 80709.54 ms\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A full podcast transcribed in ~80 seconds on an M1 Mac Mini -- not too bad!"}]},{"type":"element","tag":"pre","props":{"code":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"obtain-audio-files","depth":2,"text":"Obtain Audio File(s)"},{"id":"build-whispercpp-transcribe-audio","depth":2,"text":"Build whisper.cpp & Transcribe Audio"}]}},"_type":"markdown","_id":"content:articles:podcast-transcription-whispercpp.md","_source":"content","_file":"articles/podcast-transcription-whispercpp.md","_extension":"md"},{"_path":"/articles/quick-tip-rerunning-bash-commands","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Tip: Re-running Bash Commands","description":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","date":"2021-09-22","draft":false,"tags":["tip","bash"],"categories":["tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ pacman -Syu\nerror: you cannot perform this operation unless you are root.\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" cannot"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" perform"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" this"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" operation"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" unless"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" are"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" root.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Well, I have good news for you -- you can easily re-issue a command with the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" designator! Simply type "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" followed by "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" and you're good to go."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ sudo !!\nsudo pacman -Syu\n[sudo] password for colton:\n:: Synchronizing package databases...\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !!\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[sudo] password "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" colton:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"::"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" Synchronizing"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" package"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" databases...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Commands that are prefixed with a bang, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":", are considered "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event\nDesignators,"}]},{"type":"text","value":" and are references to your command-line history. You can take a\nlook at your history with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"history"}]},{"type":"text","value":" command."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ history\n 1021 touch hello_world.txt\n 1022 ls\n 1023 echo \"Here we go again!\"\n 1024 find . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" history\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1021"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" hello_world.txt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1022"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1023"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1024"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are many ways to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":" in your shell. For example, if you wanted to\nre-issue a specific command in your history, you could use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!n"}]},{"type":"text","value":" where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" is\nthe number next to the command in your history."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !1023\necho \"Here we go again!\"\nHere we go again!\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !1023\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Here"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" we"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" go"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" again!\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the command you issued 4-commands ago, you can use\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!-4"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !-4\nls\nhello_world.txt\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !-4\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hello_world.txt\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the last command that started with the string\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":", you can use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!find"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !find\nfind . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !find\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Be sure to check out the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event Designators"}]},{"type":"text","value":" section of the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"bash"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"man"}]},{"type":"text","value":" pages\nfor more information!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As an aside, for even faster command-line history navigation, be sure to check\nout the excellent "},{"type":"element","tag":"a","props":{"href":"https://github.com/junegunn/fzf","rel":["nofollow"]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" utility by "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"junegunn."}]},{"type":"text","value":"\nOne of the many features of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" is browsing and re-issuing commands from your\ncommand-line history with a fuzzy-finder!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:quick-tip-rerunning-bash-commands.md","_source":"content","_file":"articles/quick-tip-rerunning-bash-commands.md","_extension":"md"},{"_path":"/articles/reset-ipmi-password-from-host-os","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Reset IPMI Credentials from the Host OS","description":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","date":"2021-12-27","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from\nthe web interface. This is done by navigating to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Network > IPMI"}]},{"type":"text","value":", and simply entering a new value in the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"IPMI\nPassword Reset"}]},{"type":"text","value":" field."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using some other OS that doesn't have this feature, you can achieve similar results by using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ipmitool"}]},{"type":"text","value":"\ncommand-line utility."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, you'll want to determine the user ID associated with the user for whom you'd like to reset the password."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this case, we will be resetting the password for "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ADMIN"}]},{"type":"text","value":" who has a user ID of "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"2"}]},{"type":"text","value":". Then we'll assign the new\npassword like so:"}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user set password 2 \n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user set password 2 \n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And you should be good to go!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"..."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Alternatively, if you'd like to factory reset the baseboard management controller (BMC), which will reset the IPMI\ncredentials to their default value, you can issue the following command."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool raw 0x3c 0x40\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool raw 0x3c 0x40\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x3c"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":" argument, a.k.a. the network function code that defines the functional routing for\nmessages, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x40"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":". According to section 5.1 of the "},{"type":"element","tag":"a","props":{"href":"https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf","rel":["nofollow"]},"children":[{"type":"text","value":"IPMI interface\nspecification"}]},{"type":"text","value":",\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"netfn"}]},{"type":"text","value":" codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some\nSupermicro references on these vendor specific network functions without much luck other than various "},{"type":"element","tag":"a","props":{"href":"https://www.supermicro.com/support/faqs/faq.cfm?faq=15448","rel":["nofollow"]},"children":[{"type":"text","value":"support\nresponses"}]},{"type":"text","value":" on how to reset a device. Bummer!"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:reset-ipmi-password-from-host-os.md","_source":"content","_file":"articles/reset-ipmi-password-from-host-os.md","_extension":"md"},{"_path":"/articles/ssh-ed25519-sk-yubikey","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Configuring a YubiKey for use with OpenSSH","description":"YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","draft":false,"date":"2024-06-09","tags":["unix","configurations"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In "},{"type":"element","tag":"a","props":{"href":"https://www.openssh.com/txt/release-8.2","rel":["nofollow"]},"children":[{"type":"text","value":"release 8.2 of OpenSSH"}]},{"type":"text","value":" support for FIDO devices was added with public key types \"ecdsa-sk\" and \"ed25519-sk\" (-sk standing for \"security key\"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types \"ecdsa-sk\" and \"ed25519-sk\", along with corresponding certificate types."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's get started by installing the latest version of OpenSSH via "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":", along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ brew install openssh ykman\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" openssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman list\nYubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"YubiKey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 5Ci"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (5.4.3) [OTP+FIDO+CCID]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we'll go ahead and enable a pin on our device via the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"change-pin"}]},{"type":"text","value":" command, as this a requirement for our use."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman fido access change-pin\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" fido"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" access"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" change-pin\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And last, we'll generate the key on our device!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ssh-keygen -t ed25519-sk -O resident\nGenerating public/private ed25519-sk key pair.\nYou may need to touch your authenticator to authorize key generation.\n...\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-keygen"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -t"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Generating"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" public/private"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pair.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"You"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" may"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" need"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" your"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authenticator"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authorize"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" generation.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We specify "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"resident"}]},{"type":"text","value":" to indicate that the key handle is to be stored on the YubiKey itself, since we will be using this device with multiple computers."}]},{"type":"element","tag":"pre","props":{"className":"language-txt shiki shiki-themes github-light","code":"resident\n Indicate that the key handle should be stored on the FIDO\n authenticator itself. This makes it easier to use the\n authenticator on multiple computers. Resident keys may be\n supported on FIDO2 authenticators and typically require that a PIN\n be set on the authenticator prior to generation. Resident keys\n may be loaded off the authenticator using ssh-add(1). Storing\n both parts of a key on a FIDO authenticator increases the\n likelihood of an attacker being able to use a stolen authenticator\n device.\n","language":"txt","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" Indicate that the key handle should be stored on the FIDO\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator itself. This makes it easier to use the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator on multiple computers. Resident keys may be\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" supported on FIDO2 authenticators and typically require that a PIN\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" be set on the authenticator prior to generation. Resident keys\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" may be loaded off the authenticator using ssh-add(1). Storing\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" both parts of a key on a FIDO authenticator increases the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" likelihood of an attacker being able to use a stolen authenticator\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" device.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's all it takes -- simple enough. Now, when interacting with "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" or "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"git"}]},{"type":"text","value":" you will be prompted to touch the YubiKey to bring that little bit of physical 2FA."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:ssh-ed25519-sk-yubikey.md","_source":"content","_file":"articles/ssh-ed25519-sk-yubikey.md","_extension":"md"},{"_path":"/articles/unit-testing-micropython-with-mocks","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Unit Testing in MicroPython with Mocks","description":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","date":"2020-02-07","draft":false,"tags":["micropython","testing","mocks","tutorial"],"categories":["python","embedded"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]},{"type":"element","tag":"h1","props":{"id":"mocking"},"children":[{"type":"text","value":"Mocking"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed."}]},{"type":"element","tag":"h1","props":{"id":"a-micropython-mocking-example"},"children":[{"type":"text","value":"A MicroPython Mocking Example"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this example, we will be unit testing a module named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":", that\ndepends on the MicroPython library "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" to log the most recent Epoch time to\na file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# time_logger.py\n\nclass TimeLogger(object):\n\n def save_time(self):\n \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n \"\"\"\n with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n f.write(str(utime.time()))\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"w+\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f.write("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"str"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(utime.time()))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, because the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module is not installed on the machine that the unit\ntests on, we must mock "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module before importing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":" in our\nunit test file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# test_time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"sys.modules["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'utime'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"] "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" time_logger "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we can write a test that patches the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time"}]},{"type":"text","value":" functionality so that\nit returns a value of our choosing -- in this case, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"class TestTimeLogger(unittest.TestCase):\n\n def test_save_time(self):\n \"\"\" Verify that the Epoch time is written to file\n \"\"\"\n with unittest.mock.patch(\"utime.time\", return_value=1234):\n t = TimeLogger()\n t.save_time()\n with open(\"LAST_KNOWN_TIME\") as f:\n self.assertEqual(\"1234\", f.read())\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TestTimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"unittest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"TestCase"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" test_save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Verify that the Epoch time is written to file\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock.patch("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"utime.time\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"return_value"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t.save_time()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" self"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":".assertEqual("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"1234\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", f.read())\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now, when the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"save_time"}]},{"type":"text","value":" method gets the latest time from "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time()"}]},{"type":"text","value":", the\nvalue will be patched to return "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":". That value will be written to a file,\nand our unit test will pass!"}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/unittest.html","rel":["nofollow"]},"children":[{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"unittest"}]},{"type":"text","value":" — Unit testing framework"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:unit-testing-micropython-with-mocks.md","_source":"content","_file":"articles/unit-testing-micropython-with-mocks.md","_extension":"md"},{"_path":"/articles/vim-fugitive-gpg-pinentry","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Using pinentry-mac to sign commits from vim-fugitive","description":"In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","draft":false,"date":"2024-05-11","tags":["vim","tip"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The man, the myth, the legend, Timothy Popallopollis himself "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive/issues/846#issuecomment-253816577","rel":["nofollow"]},"children":[{"type":"text","value":"recommends"}]},{"type":"text","value":" configuring your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":". On macOS this can be done quite by simply installing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-mac"}]},{"type":"text","value":", and updating your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent.conf"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"configuration"},"children":[{"type":"text","value":"Configuration"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First things first, let's install the pinentry program."}]},{"type":"element","tag":"pre","props":{"code":"$ brew install pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, all we need to do is set the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":" option in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"~/.gnupg/gpg-agent.conf"}]},{"type":"text","value":" file."}]},{"type":"element","tag":"pre","props":{"code":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If your don't know the path to your pinentry program, you can throw down a quick "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"which"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"$ which pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" which"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or use your Homebrew prefix."}]},{"type":"element","tag":"pre","props":{"code":"$ echo $(brew --prefix)/bin/pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" $("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --prefix"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"configuration","depth":2,"text":"Configuration"}]}},"_type":"markdown","_id":"content:articles:vim-fugitive-gpg-pinentry.md","_source":"content","_file":"articles/vim-fugitive-gpg-pinentry.md","_extension":"md"}],"navigation":[{"title":"Articles","_path":"/articles","children":[{"title":"Upgrading the Firmware on the PCEngines APU2","_path":"/articles/apu2-firmware-upgrade"},{"title":"Docker Volume Permissions with SELinux","_path":"/articles/docker-selinux-volumes"},{"title":"Exploring the Digital Ocean `doctl` Utility","_path":"/articles/doctl"},{"title":"Impressions of Fennel with Hammerspoon","_path":"/articles/fennel-initial-exploration"},{"title":"Migrate to TrueNAS Scale from TrueNAS Core","_path":"/articles/migrate-truenas-from-core-to-scale"},{"title":"How To Add an RSS Feed to a Nuxt Website","_path":"/articles/nuxt-content-rss-feed"},{"title":"This Website Has Been Migrated to Nuxt 3 🎉","_path":"/articles/nuxt-v3-migration"},{"title":"Create a Persistent Arch Linux Bootable USB with Vagrant","_path":"/articles/persistent-archlinux-usb"},{"title":"Easily Transcribe Podcasts with Whisper.cpp","_path":"/articles/podcast-transcription-whispercpp"},{"title":"Tip: Re-running Bash Commands","_path":"/articles/quick-tip-rerunning-bash-commands"},{"title":"Reset IPMI Credentials from the Host OS","_path":"/articles/reset-ipmi-password-from-host-os"},{"title":"Configuring a YubiKey for use with OpenSSH","_path":"/articles/ssh-ed25519-sk-yubikey"},{"title":"Unit Testing in MicroPython with Mocks","_path":"/articles/unit-testing-micropython-with-mocks"},{"title":"Using pinentry-mac to sign commits from vim-fugitive","_path":"/articles/vim-fugitive-gpg-pinentry"}]}]} \ No newline at end of file diff --git a/api/_content/cache.1720229301475.json b/api/_content/cache.1720229301475.json new file mode 100644 index 00000000..008e5398 --- /dev/null +++ b/api/_content/cache.1720229301475.json @@ -0,0 +1 @@ +{"generatedAt":1720229314958,"generateTime":523,"contents":[{"_path":"/articles/apu2-firmware-upgrade","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Upgrading the Firmware on the PCEngines APU2","description":"I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","date":"2019-12-21","draft":false,"tags":["pcengine","apu"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, we will connect to the device over the serial port"}]},{"type":"element","tag":"pre","props":{"code":"screen /dev/tty.usbserial 115200\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"screen /dev/tty.usbserial 115200\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we will install the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"flashrom"}]},{"type":"text","value":" utility that is needed to update the\nfirmware. Because it is not available in the default "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"yum"}]},{"type":"text","value":" repositories, we\nwill enable the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Extra Packages for Enterprise Linux"}]},{"type":"text","value":" (EPEL) repository before\ninstallation."}]},{"type":"element","tag":"pre","props":{"code":"sudo yum install epel-release\nsudo yum install flashrom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" epel-release\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we will download the latest version of the firmware that is compatible\nwith the APU2 device from the PC Engines release website:\n"},{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"curl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, we will flash the firmware..."}]},{"type":"element","tag":"pre","props":{"code":"sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -w"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" apu2_v4.11.0.1.rom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -p"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" internal:boardmismatch=force\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References:"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.ch/apu2.htm"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/elad/openbsd-apu2","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/elad/openbsd-apu2"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:apu2-firmware-upgrade.md","_source":"content","_file":"articles/apu2-firmware-upgrade.md","_stem":"articles/apu2-firmware-upgrade","_extension":"md"},{"_path":"/articles/docker-selinux-volumes","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Docker Volume Permissions with SELinux","description":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","date":"2019-12-26","draft":false,"tags":["docker","selinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]},{"type":"element","tag":"pre","props":{"code":"mkdir: can't create directory '/data': Permission denied\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"mkdir: can't create directory '/data': Permission denied\n"}]}]}]}]},{"type":"element","tag":"hr","props":{},"children":[]},{"type":"element","tag":"pre","props":{"code":"$ docker info --format '{{json .SecurityOptions}}'\n[\n \"name=seccomp,profile=/etc/docker/seccomp.json\",\n \"name=selinux\"\n]\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" docker"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" info"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '{{json .SecurityOptions}}'\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=seccomp,profile=/etc/docker/seccomp.json\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=selinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It turns out that this can be resolved by appending the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":":z"}]},{"type":"text","value":" flag to the volume\nmappings in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"docker-compose.yml"}]},{"type":"text","value":" file, indicating that the volume content\nis shared."}]},{"type":"element","tag":"pre","props":{"code":"services:\n server:\n volumes:\n - ./data:/data:z\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"services:\n server:\n volumes:\n - ./data:/data:z\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From the Docker documentation:"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"z"}]},{"type":"text","value":" option tells Docker that two containers share the volume content. As\na result, Docker labels the content with a shared content label. Shared\nvolume labels allow all containers to read/write content."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/info/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Docker Info"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Mounting Volumes"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:docker-selinux-volumes.md","_source":"content","_file":"articles/docker-selinux-volumes.md","_stem":"articles/docker-selinux-volumes","_extension":"md"},{"_path":"/articles/doctl","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Exploring the Digital Ocean `doctl` Utility","description":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","date":"2023-01-01","tags":["linux","digital-ocean"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To start things off, I had to install and setup authentication to Digital Ocean. Doing\nthis on my Mac machine, I opted to use "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"# install `doctl`\nbrew install doctl\n\n# setup authentication\ndoctl auth init\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# install `doctl`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" doctl\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# setup authentication\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" auth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" init\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the online "},{"type":"element","tag":"a","props":{"href":"https://docs.digitalocean.com/reference/doctl/reference/compute/droplet/create/","rel":["nofollow"]},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":" is fantastic, I instead found myself mostly referencing the outputs of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--help"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create --help\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --help\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I had to find the image name of the version of Ubuntu I wanted to install:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute image list --public | grep ubuntu-22\n\n# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --public"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" grep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And also the slug of the compute size:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute size list\n\n# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've also configured a few SSH keys with Digital Ocean, and I can have the key (specified by ID) provisioned to the machine using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--ssh-keys"}]},{"type":"text","value":" flag."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh-key list\n\n# ID Name FingerPrint\n# 1234 mini \n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# ID Name FingerPrint\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 1234 mini \n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Also, I wanted to install a few packages to the box upon creation, this can be done easily with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--user-data-file"}]},{"type":"text","value":" flag to run an initialization script."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"echo 'apt install -y imagemagick zip' > bootstrap.sh\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'apt install -y imagemagick zip'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" >"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bootstrap.sh\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Putting it all together, here is the simple command for creating a small compute instance!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create \\\n --image ubuntu-22-10-x64 \\\n --size s-1vcpu-512mb-10gb \\\n --region nyc1 \\\n --ssh-keys 1234 \\\n --user-data-file boostrap.sh \\\n ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22-10-x64"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" s-1vcpu-512mb-10gb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --region"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" nyc1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --ssh-keys"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --user-data-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" boostrap.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, I can connect, do my thing, and destroy the instance."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet delete --force ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" delete"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --force"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"All-in-all, I was up and running in about 20 minutes. What a handy utility!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:doctl.md","_source":"content","_file":"articles/doctl.md","_stem":"articles/doctl","_extension":"md"},{"_path":"/articles/fennel-initial-exploration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Impressions of Fennel with Hammerspoon","description":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","draft":false,"date":"2023-10-22","tags":["lisp","hammerspoon","fennel"],"categories":["lisp"],"cover_image":"/images/dall-e-fennel-hammer.jpeg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Fennel"}]},{"type":"text","value":" programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: "},{"type":"element","tag":"a","props":{"href":"https://www.hammerspoon.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Hammerspoon"}]},{"type":"text","value":", and "},{"type":"element","tag":"a","props":{"href":"https://neovim.io/","rel":["nofollow"]},"children":[{"type":"text","value":"Neovim"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"initial-observations"},"children":[{"type":"text","value":"Initial Observations"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/tree/795749fa17e1310bb001bb7deaa22be8689f0027/hammerspoon/.hammerspoon/modules","rel":["nofollow"]},"children":[{"type":"text","value":"modules"}]},{"type":"text","value":" that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project..."}]},{"type":"element","tag":"h2","props":{"id":"integrating-fennel-with-hammerspoon"},"children":[{"type":"text","value":"Integrating Fennel with Hammerspoon"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While official documentation exists describing how to "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/setup#embedding-fennel","rel":["nofollow"]},"children":[{"type":"text","value":"embed fennel"}]},{"type":"text","value":" into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.path"}]},{"type":"text","value":" and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.cpath"}]},{"type":"text","value":" properties in Lua, but I was unable to get this to\nwork."}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://blog.exupero.org/hammerspoon-with-fennel/","rel":["nofollow"]},"children":[{"type":"text","value":"https://blog.exupero.org/hammerspoon-with-fennel/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer/blob/master/init.lua","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/agzam/spacehammer/blob/master/init.lua"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Ultimately, I opted to include the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.lua"}]},{"type":"text","value":" file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.path"}]},{"type":"text","value":" to point to the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"*.fnl"}]},{"type":"text","value":" files in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":".hammerspoon/"}]},{"type":"text","value":" directory, and\nttranslating these modules can begin!"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"/.hammerspoon/?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"-- init.lua\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"local"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" fennel "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'fennel'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" .."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \";\" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.getenv"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"HOME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"/.hammerspoon/?.fnl\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"table.insert"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"package.loaders"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" or"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.searchers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"searcher"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'main'\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"translating-lua-to-fennel"},"children":[{"type":"text","value":"Translating Lua to Fennel"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/see","rel":["nofollow"]},"children":[{"type":"text","value":"anti-fennel"}]},{"type":"text","value":", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sleep"}]},{"type":"text","value":" function\nfrom the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"helpers"}]},{"type":"text","value":" module into the compiler:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"function sleep(ms)\n os.execute(\"sleep \" .. tonumber(ms) / 1000)\nend\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.execute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" tonumber"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(fn sleep [ms]\n (os.execute (.. \"sleep \" (/ (tonumber ms) 1000))))\n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(fn "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [ms]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (os.execute (.. "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (tonumber ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As another example, here is the output for my "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"caffeine"}]},{"type":"text","value":" toggle:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"hs.hotkey.bind(HYPER, \"0\", function()\n hs.caffeinate.toggle(\"displayIdle\")\n if hs.caffeinate.get(\"displayIdle\") then\n helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n else\n helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n end\nend)\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hotkey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"bind"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(HYPER, "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"0\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"toggle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"get"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"then\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"success"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"check"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" else\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ban"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(hs.hotkey.bind HYPER :0\n (fn [] (hs.caffeinate.toggle :displayIdle)\n (if (hs.caffeinate.get :displayIdle)\n (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban)))) \n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(hs.hotkey.bind HYPER "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":0\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (fn [] (hs.caffeinate.toggle "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (hs.caffeinate.get "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.success helpers.assets.check)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.error helpers.assets.ban))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This was especially helpful for more gnarly modules like the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"window"}]},{"type":"text","value":" module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!"}]},{"type":"element","tag":"h2","props":{"id":"next-steps"},"children":[{"type":"text","value":"Next Steps"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Additionally, before beginning this endeavor, I was already aware of projects like\n"},{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer","rel":["nofollow"]},"children":[{"type":"text","value":"spacehammer"}]},{"type":"text","value":"; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/pull/19/files","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/cmpadden/dotfiles/pull/19/files"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"initial-observations","depth":2,"text":"Initial Observations"},{"id":"integrating-fennel-with-hammerspoon","depth":2,"text":"Integrating Fennel with Hammerspoon"},{"id":"translating-lua-to-fennel","depth":2,"text":"Translating Lua to Fennel"},{"id":"next-steps","depth":2,"text":"Next Steps"}]}},"_type":"markdown","_id":"content:articles:fennel-initial-exploration.md","_source":"content","_file":"articles/fennel-initial-exploration.md","_stem":"articles/fennel-initial-exploration","_extension":"md"},{"_path":"/articles/migrate-truenas-from-core-to-scale","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Migrate to TrueNAS Scale from TrueNAS Core","description":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","date":"2021-12-28","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":" in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Make a backup of your system’s configuration\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"System > General"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save Config"}]},{"type":"text","value":", check the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Export Secret Seed"}]},{"type":"text","value":" box, and click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Export dataset keys for the encrypted pools\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Storage > Pools"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click the cog icon, and select "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Export Dataset Keys"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Insert the TrueNAS Core bootable USB into the NAS"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the Supermicro IPMI interface select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Remote Control"}]},{"type":"text","value":" and "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"iKVM/HTML5"}]},{"type":"text","value":" and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Reboot"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Select the bootable USB as the boot device"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the TrueNAS installation wizard, select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":", select the drive that contains the TrueNAS installation, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Upgrade Install"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference "},{"type":"element","tag":"a","props":{"href":"https://www.truenas.com/help-me-choose/","rel":["nofollow"]},"children":[{"type":"text","value":"this table"}]},{"type":"text","value":"."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:migrate-truenas-from-core-to-scale.md","_source":"content","_file":"articles/migrate-truenas-from-core-to-scale.md","_stem":"articles/migrate-truenas-from-core-to-scale","_extension":"md"},{"_path":"/articles/nuxt-content-rss-feed","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"How To Add an RSS Feed to a Nuxt Website","description":"If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","draft":false,"date":"2024-01-06","tags":["nuxt","rss"],"categories":["programming"],"cover_image":"/images/nuxt-content-rss-feed.jpg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In version 2 of Nuxt, the community module, "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module","rel":["nofollow"]},"children":[{"type":"text","value":"nuxt-community/feed-module"}]},{"type":"text","value":" was a popular choice for adding an RSS feed to your website. However, there has been an unresolved "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module/issues/106","rel":["nofollow"]},"children":[{"type":"text","value":"open issue"}]},{"type":"text","value":" since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward."}]},{"type":"element","tag":"h2","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, install the "},{"type":"element","tag":"a","props":{"href":"https://www.npmjs.com/package/feed","rel":["nofollow"]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library into your project:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D feed\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" feed\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/"}]},{"type":"text","value":" folder in your project if it does not already exist, and create a file named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/atom.ts"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Here, we will leverage the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library and construct an XML representation of our Nuxt content. As you can see, we first define our "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"serverQueryContent"}]},{"type":"text","value":" and append a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed.addItem"}]},{"type":"text","value":" for each article."}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { Feed } from 'feed';\n\nconst BASE_URL = \"https://mywebsite.com\"\nconst AUTHOR_NAME = \"Firstname Lastname\"\n\nexport default defineEventHandler(async (event) => {\n\n const feed = new Feed({\n title: \"My Title\",\n description: \"My Description\",\n id: BASE_URL,\n link: BASE_URL,\n language: \"en\",\n image: `${BASE_URL}/images/placeholder.png`,\n favicon: `${BASE_URL}/favicon.ico`,\n copyright: `All rights reserved ${new Date().getFullYear()}, ${AUTHOR_NAME}`,\n updated: new Date(),\n generator: \"Nuxt static site generation + Feed for Node.js\",\n feedLinks: {\n atom: `${BASE_URL}/atom`\n },\n author: {\n name: AUTHOR_NAME,\n }\n });\n\n const articles = await serverQueryContent(event).find();\n\n articles.forEach((article) => {\n feed.addItem({\n title: article.title ? article.title : \"Missing Title\",\n id: article._path,\n link: `${BASE_URL}${article._path}`,\n description: article.description,\n author: [\n {\n name: AUTHOR_NAME,\n },\n ],\n date: new Date(article.date),\n image: article.cover_image ? `${BASE_URL}/${article.cover_image}` : undefined\n });\n });\n\n return feed.atom1();\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { Feed } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'feed'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://mywebsite.com\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Firstname Lastname\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Description\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" language: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"en\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/images/placeholder.png`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" favicon: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/favicon.ico`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" copyright: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`All rights reserved ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"getFullYear"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}, ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" updated: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":19},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" generator: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Nuxt static site generation + Feed for Node.js\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":20},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feedLinks: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":21},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" atom: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/atom`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":22},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":23},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":24},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":25},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":26},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":27},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":28},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":29},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":30},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":31},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"addItem"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":32},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Missing Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":33},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: article._path,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":34},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"_path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":35},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: article.description,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":36},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: [\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":37},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":38},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":39},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":40},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ],\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":41},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" date: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(article.date),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":42},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: article.cover_image "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" `${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"cover_image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" :"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" undefined\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":43},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":44},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":45},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":46},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"atom1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":47},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's just about it! Except, if you are statically generating your website with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt generate"}]},{"type":"text","value":" command, you will need to configure this server-side route to be pre-rendered on site generation. This is as simple as adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nitro"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" definition in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":" file, like so:"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"bonus"},"children":[{"type":"text","value":"Bonus"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may also be interested in adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sitemap.xml"}]},{"type":"text","value":" to your website. This can be done in almost an identical fashion!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Install the dependency:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D sitemap\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sitemap\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a route at "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/sitemap.xml.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { SitemapStream, streamToPromise } from 'sitemap';\n\nexport default defineEventHandler(async (event) => {\n const articles = await serverQueryContent(event).find();\n\n const sitemap = new SitemapStream({ hostname: 'https://my-website.com/' });\n\n // Add non nuxt content endpoints here\n sitemap.write({ url: '/' });\n sitemap.write({ url: '/articles' });\n\n // Dynamically generate routes for Nuxt markdown content\n articles.forEach((article) => sitemap.write({ url: article._path, changefreq: 'monthly' }));\n sitemap.end();\n\n return (await streamToPromise(sitemap));\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { SitemapStream, streamToPromise } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'sitemap'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" sitemap"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" SitemapStream"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ hostname: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'https://my-website.com/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Add non nuxt content endpoints here\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/articles'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Dynamically generate routes for Nuxt markdown content\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: article._path, changefreq: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'monthly'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" streamToPromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(sitemap));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And add the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" entry in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/sitemap.xml', '/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/sitemap.xml'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"instructions","depth":2,"text":"Instructions"},{"id":"bonus","depth":2,"text":"Bonus"}]}},"_type":"markdown","_id":"content:articles:nuxt-content-rss-feed.md","_source":"content","_file":"articles/nuxt-content-rss-feed.md","_stem":"articles/nuxt-content-rss-feed","_extension":"md"},{"_path":"/articles/nuxt-v3-migration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"This Website Has Been Migrated to Nuxt 3 🎉","description":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","date":"2022-12-31","tags":["nuxt"],"categories":["web"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you're curious what changes were required to make the migration, you can check out "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/cmpadden.github.io/pull/3","rel":["nofollow"]},"children":[{"type":"text","value":"pull request #3"}]},{"type":"text","value":" in the GitHub repository."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"img","props":{"alt":"Screenshot of Nuxt Migration Pull Request","src":"/images/nuxt-migration-pr.png"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious.\nFor this reason, I opted to generate a new project entirely, and port existing code to this clean slate.\nI believe that this resulted in a project with a bit less cruft."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The most valuable resources for making these changes include:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/migration/overview","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Migration Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/getting-started/introduction","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Framework Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://tailwindcss.nuxt.dev/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Tailwind Module Documentation"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content Module Documentation"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Part of the delay for doing this upgrade was in waiting for module developers to support this major release.\nI'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available!\nI just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:nuxt-v3-migration.md","_source":"content","_file":"articles/nuxt-v3-migration.md","_stem":"articles/nuxt-v3-migration","_extension":"md"},{"_path":"/articles/persistent-archlinux-usb","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Create a Persistent Arch Linux Bootable USB with Vagrant","description":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","date":"2020-01-09","draft":false,"tags":["vagrant","archlinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]},{"type":"element","tag":"h1","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The original intention was to use Docker for this process -- leveraging the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--device"}]},{"type":"text","value":" flag and mounting the target USB device in the Docker container,\nbut the underlying hypervisor in Docker Desktop for Mac does not support this.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"2"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"3"}]}]},{"type":"text","value":" While there are workarounds using Docker\nMachine, Vagrant felt like the path of least resistance."}]},{"type":"element","tag":"h1","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"h2","props":{"id":"create-an-arch-linux-virtual-machine-with-vagrant"},"children":[{"type":"text","value":"Create an Arch Linux Virtual Machine with Vagrant"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Get the latest Arch Linux image "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"4"}]}]},{"type":"text","value":" from the Vagrant Cloud Box\nCatalog."}]},{"type":"element","tag":"pre","props":{"code":"vagrant box add archlinux/archlinux\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" box"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" add"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" archlinux/archlinux\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Determine the USB vendor information for the thumb-drive that we will\npass-through to the virtual machine. Using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" utility that comes\nwith Virtual Box, list the devices, and make note of the Vendor and Product ID."}]},{"type":"element","tag":"pre","props":{"code":" VBoxManage list usbhost\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" VBoxManage"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" usbhost\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Vagrantfile"}]},{"type":"text","value":" with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"archlinx/archlinux"}]},{"type":"text","value":" as the target box, and the USB\ndevice information that is passed through. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"6"}]}]},{"type":"text","value":" Vagrant\noffers a handy customization parameter "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" that calls the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" command under-the-hood, allowing one to enable the guest machine\nto access the host machine's USB devices."}]},{"type":"element","tag":"pre","props":{"code":"# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\nVagrant.configure(\"2\") do |config|\n config.vm.box = \"archlinux/archlinux\"\n config.vm.provider \"virtualbox\" do |vb|\n vb.name = \"archlinux\"\n vb.customize ['modifyvm', :id, '--usb', 'on']\n vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n end\nend\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# -*- mode: ruby -*-\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# vi: set ft=ruby :\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Vagrant.configure(\"2\") do |config|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.box = \"archlinux/archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.provider \"virtualbox\" do |vb|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.name = \"archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['modifyvm', :id, '--usb', 'on']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When virtual machine is brought up, the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"usbfilter"}]},{"type":"text","value":" is applied, and the guest\nis able to access to the host machine's USB device that was specified in the\nfilter."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Start the machine, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" into the guest, and list the devices to confirm that\nthe USB device is available (see: "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"/dev/sdb"}]},{"type":"text","value":")."}]},{"type":"element","tag":"pre","props":{"code":"$ vagrant up\n$ vagrant ssh\n[vagrant@archlinux ~]$ lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 20G 0 disk\n├─sda1 8:1 0 1.9G 0 part [SWAP]\n└─sda2 8:2 0 18.1G 0 part /\nsdb 8:16 1 28.7G 0 disk\n└─sdb1 8:17 1 8G 0 part\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" up\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[vagrant@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]$ lsblk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MAJ:MIN"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RM"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" SIZE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RO"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" TYPE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MOUNTPOINT\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sda"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 20G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"├─sda1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 1.9G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [SWAP]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sda2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 18.1G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" /\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sdb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:16"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 28.7G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sdb1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:17"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"install-arch-linux-on-the-usb-drive"},"children":[{"type":"text","value":"Install Arch Linux on the USB Drive"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Installation Guide"}]},{"type":"text","value":" outlines the installation procedure in\ngreat detail -- the following steps follow this closely with a few alteration\ndue to installing onto removable media."}]},{"type":"element","tag":"h3","props":{"id":"partition-the-disk-uefi-with-gpt"},"children":[{"type":"text","value":"Partition the Disk (UEFI with GPT)"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# fdisk /dev/sdb\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# fdisk /dev/sdb\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command (m for help): p\nDisk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\nDisk model: Ultra Fit\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 1050623 1048576 512M EFI System\n/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n\nFilesystem/RAID signature on partition 1 will be wiped.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command (m for help): p\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk model: Ultra Fit\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Units: sectors of 1 * 512 = 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Sector size (logical/physical): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"I/O size (minimum/optimal): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disklabel type: gpt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Device Start End Sectors Size Type\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb1 2048 1050623 1048576 512M EFI System\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Filesystem/RAID signature on partition 1 will be wiped.\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"format-the-partitions"},"children":[{"type":"text","value":"Format the Partitions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The UEFI specification mandates support for FAT file-systems, and FAT32 is\nrecommended for removable media. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"7"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -Sy dosfstools\n[root@archlinux ~]# mkfs.fat -F32 /dev/sdb1\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -Sy dosfstools\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.fat -F32 /dev/sdb1\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for the root partition, it is recommended to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ext4"}]},{"type":"text","value":" without a journal to\nreduce the reads and writes to the file-system as this is detrimental to the\nflash-based USB drive. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"8"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mkfs.ext4 -O \"^has_journal\" /dev/sdb2\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.ext4 -O "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"^has_journal\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /dev/sdb2\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"mount-the-partitions-and-bootstrap-the-environment"},"children":[{"type":"text","value":"Mount the Partitions and Bootstrap the Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mount /dev/sdb2 /mnt\n[root@archlinux ~]# mkdir -p /mnt/boot/efi\n[root@archlinux ~]# mount /dev/sdb1 /mnt/boot/efi\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb2 /mnt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkdir -p /mnt/boot/efi\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb1 /mnt/boot/efi\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -S arch-install-scripts\n[root@archlinux ~]# pacstrap /mnt base linux linux-firmware\n[root@archlinux ~]# genfstab -U /mnt >> /mnt/etc/fstab\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -S arch-install-scripts\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacstrap /mnt base linux linux-firmware\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# genfstab -U /mnt "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":">>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /mnt/etc/fstab\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"configure-the-new-environment"},"children":[{"type":"text","value":"Configure the New Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# arch-chroot /mnt\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux ~]# arch-chroot /mnt\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Note, one difference here from a standard installation is that the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--removable"}]},{"type":"text","value":" flag is specified when installing the GRUB bootloader.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"10"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Shutdown the virtual machine, restart the host machine, and boot the newly\ncreated Arch Linux thumb-drive!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"🎉"}]},{"type":"element","tag":"h2","props":{"id":"side-note"},"children":[{"type":"text","value":"Side-note"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It was attempted to use the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"controlvm usbattach"}]},{"type":"text","value":" command to pass the USB\ndevice to the guest machine, but this did not work as it expects the virtual\nmachine to already be running, and the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" option runs prior to\nbooting the machine. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"11"}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n\nStderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Desktop on Mac vs. Docker Toolbox"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - HyperKit"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - Docker for Mac - Issue #900"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant Cloud - Arch Linux"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"Attaching USB Devices to VirtualBox Guests using VBoxManage"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub Gist - Vagrant USB Filter"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - EFI System Partition - Format Partitions"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Arch Linux on USB - Installation Tweaks"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Installation Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - GRUB - UEFI Systems"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant VBoxManage Customizations "}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"create-an-arch-linux-virtual-machine-with-vagrant","depth":2,"text":"Create an Arch Linux Virtual Machine with Vagrant"},{"id":"install-arch-linux-on-the-usb-drive","depth":2,"text":"Install Arch Linux on the USB Drive","children":[{"id":"partition-the-disk-uefi-with-gpt","depth":3,"text":"Partition the Disk (UEFI with GPT)"},{"id":"format-the-partitions","depth":3,"text":"Format the Partitions"},{"id":"mount-the-partitions-and-bootstrap-the-environment","depth":3,"text":"Mount the Partitions and Bootstrap the Environment"},{"id":"configure-the-new-environment","depth":3,"text":"Configure the New Environment"}]},{"id":"side-note","depth":2,"text":"Side-note"},{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:persistent-archlinux-usb.md","_source":"content","_file":"articles/persistent-archlinux-usb.md","_stem":"articles/persistent-archlinux-usb","_extension":"md"},{"_path":"/articles/podcast-transcription-whispercpp","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Easily Transcribe Podcasts with Whisper.cpp","description":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","draft":false,"date":"2024-01-08","tags":["whisper.cpp","ml"],"categories":["programming"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]},{"type":"element","tag":"h2","props":{"id":"obtain-audio-files"},"children":[{"type":"text","value":"Obtain Audio File(s)"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, let's get the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" file from YouTube using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"youtube-dl"}]},{"type":"text","value":" utility. It should be noted that "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" filetypes, and this utility defaults to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"mp3"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":" $ youtube-dl \\\n --extract-audio \\\n --audio-format wav \\\n --output podcast.wav \\\n \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" youtube-dl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --extract-audio"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --audio-format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This file has a 44.1 kHz sample rate, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects 16 kHz, so let's go ahead and convert that."}]},{"type":"element","tag":"pre","props":{"code":" $ file podcast.wav\npodcast.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n\n $ ffmpeg -i podcast.wav -ar 16000 podcast-16khz.wav\n\n $ file podcast-16khz.wav\npodcast-16khz.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n\n# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n# flag to the `youtube-dl` command -- I will explore this further next time...\n# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ffmpeg"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -ar"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 16000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast-16khz.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# flag to the `youtube-dl` command -- I will explore this further next time...\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"build-whispercpp-transcribe-audio"},"children":[{"type":"text","value":"Build "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" & Transcribe Audio"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's get the latest version of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":", download the English Whisper model, and build the example."}]},{"type":"element","tag":"pre","props":{"code":"# Clone the `whisper.cpp` repository\n $ git clone --depth 1 git@github.com:ggerganov/whisper.cpp && cd whisper.cpp\n\n# Download the English Whisper model in `ggml` format\n $ bash ./models/download-ggml-model.sh base.en\n\n# Build the main example\n $ make\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Clone the `whisper.cpp` repository\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" clone"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --depth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git@github.com:ggerganov/whisper.cpp"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" && "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"cd"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" whisper.cpp\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Download the English Whisper model in `ggml` format\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bash"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./models/download-ggml-model.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" base.en\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Build the main example\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" make\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, let's transcribe that podcast!"}]},{"type":"element","tag":"pre","props":{"code":" $ ./main \\\n -m ~/workspace/whisper.cpp/models/ggml-base.en.bin \\\n -f ~/Downloads/podcast-16khz.wav \\\n --output-vtt \\\n --output-file out\n\n# whisper_print_timings: load time = 114.71 ms\n# whisper_print_timings: fallbacks = 0 p / 0 h\n# whisper_print_timings: mel time = 692.20 ms\n# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n# whisper_print_timings: total time = 80709.54 ms\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./main"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -m"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/workspace/whisper.cpp/models/ggml-base.en.bin"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -f"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/Downloads/podcast-16khz.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-vtt"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" out\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: load time = 114.71 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: fallbacks = 0 p / 0 h\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: mel time = 692.20 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: total time = 80709.54 ms\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A full podcast transcribed in ~80 seconds on an M1 Mac Mini -- not too bad!"}]},{"type":"element","tag":"pre","props":{"code":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"obtain-audio-files","depth":2,"text":"Obtain Audio File(s)"},{"id":"build-whispercpp-transcribe-audio","depth":2,"text":"Build whisper.cpp & Transcribe Audio"}]}},"_type":"markdown","_id":"content:articles:podcast-transcription-whispercpp.md","_source":"content","_file":"articles/podcast-transcription-whispercpp.md","_stem":"articles/podcast-transcription-whispercpp","_extension":"md"},{"_path":"/articles/quick-tip-rerunning-bash-commands","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Tip: Re-running Bash Commands","description":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","date":"2021-09-22","draft":false,"tags":["tip","bash"],"categories":["tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ pacman -Syu\nerror: you cannot perform this operation unless you are root.\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" cannot"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" perform"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" this"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" operation"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" unless"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" are"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" root.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Well, I have good news for you -- you can easily re-issue a command with the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" designator! Simply type "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" followed by "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" and you're good to go."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ sudo !!\nsudo pacman -Syu\n[sudo] password for colton:\n:: Synchronizing package databases...\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !!\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[sudo] password "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" colton:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"::"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" Synchronizing"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" package"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" databases...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Commands that are prefixed with a bang, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":", are considered "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event\nDesignators,"}]},{"type":"text","value":" and are references to your command-line history. You can take a\nlook at your history with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"history"}]},{"type":"text","value":" command."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ history\n 1021 touch hello_world.txt\n 1022 ls\n 1023 echo \"Here we go again!\"\n 1024 find . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" history\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1021"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" hello_world.txt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1022"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1023"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1024"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are many ways to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":" in your shell. For example, if you wanted to\nre-issue a specific command in your history, you could use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!n"}]},{"type":"text","value":" where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" is\nthe number next to the command in your history."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !1023\necho \"Here we go again!\"\nHere we go again!\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !1023\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Here"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" we"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" go"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" again!\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the command you issued 4-commands ago, you can use\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!-4"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !-4\nls\nhello_world.txt\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !-4\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hello_world.txt\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the last command that started with the string\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":", you can use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!find"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !find\nfind . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !find\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Be sure to check out the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event Designators"}]},{"type":"text","value":" section of the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"bash"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"man"}]},{"type":"text","value":" pages\nfor more information!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As an aside, for even faster command-line history navigation, be sure to check\nout the excellent "},{"type":"element","tag":"a","props":{"href":"https://github.com/junegunn/fzf","rel":["nofollow"]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" utility by "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"junegunn."}]},{"type":"text","value":"\nOne of the many features of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" is browsing and re-issuing commands from your\ncommand-line history with a fuzzy-finder!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:quick-tip-rerunning-bash-commands.md","_source":"content","_file":"articles/quick-tip-rerunning-bash-commands.md","_stem":"articles/quick-tip-rerunning-bash-commands","_extension":"md"},{"_path":"/articles/reset-ipmi-password-from-host-os","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Reset IPMI Credentials from the Host OS","description":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","date":"2021-12-27","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from\nthe web interface. This is done by navigating to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Network > IPMI"}]},{"type":"text","value":", and simply entering a new value in the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"IPMI\nPassword Reset"}]},{"type":"text","value":" field."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using some other OS that doesn't have this feature, you can achieve similar results by using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ipmitool"}]},{"type":"text","value":"\ncommand-line utility."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, you'll want to determine the user ID associated with the user for whom you'd like to reset the password."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this case, we will be resetting the password for "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ADMIN"}]},{"type":"text","value":" who has a user ID of "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"2"}]},{"type":"text","value":". Then we'll assign the new\npassword like so:"}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user set password 2 \n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user set password 2 \n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And you should be good to go!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"..."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Alternatively, if you'd like to factory reset the baseboard management controller (BMC), which will reset the IPMI\ncredentials to their default value, you can issue the following command."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool raw 0x3c 0x40\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool raw 0x3c 0x40\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x3c"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":" argument, a.k.a. the network function code that defines the functional routing for\nmessages, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x40"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":". According to section 5.1 of the "},{"type":"element","tag":"a","props":{"href":"https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf","rel":["nofollow"]},"children":[{"type":"text","value":"IPMI interface\nspecification"}]},{"type":"text","value":",\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"netfn"}]},{"type":"text","value":" codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some\nSupermicro references on these vendor specific network functions without much luck other than various "},{"type":"element","tag":"a","props":{"href":"https://www.supermicro.com/support/faqs/faq.cfm?faq=15448","rel":["nofollow"]},"children":[{"type":"text","value":"support\nresponses"}]},{"type":"text","value":" on how to reset a device. Bummer!"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:reset-ipmi-password-from-host-os.md","_source":"content","_file":"articles/reset-ipmi-password-from-host-os.md","_stem":"articles/reset-ipmi-password-from-host-os","_extension":"md"},{"_path":"/articles/ssh-ed25519-sk-yubikey","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Configuring a YubiKey for use with OpenSSH","description":"YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","draft":false,"date":"2024-06-09","tags":["unix","configurations"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In "},{"type":"element","tag":"a","props":{"href":"https://www.openssh.com/txt/release-8.2","rel":["nofollow"]},"children":[{"type":"text","value":"release 8.2 of OpenSSH"}]},{"type":"text","value":" support for FIDO devices was added with public key types \"ecdsa-sk\" and \"ed25519-sk\" (-sk standing for \"security key\"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types \"ecdsa-sk\" and \"ed25519-sk\", along with corresponding certificate types."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's get started by installing the latest version of OpenSSH via "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":", along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ brew install openssh ykman\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" openssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman list\nYubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"YubiKey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 5Ci"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (5.4.3) [OTP+FIDO+CCID]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we'll go ahead and enable a pin on our device via the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"change-pin"}]},{"type":"text","value":" command, as this a requirement for our use."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman fido access change-pin\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" fido"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" access"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" change-pin\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And last, we'll generate the key on our device!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ssh-keygen -t ed25519-sk -O resident\nGenerating public/private ed25519-sk key pair.\nYou may need to touch your authenticator to authorize key generation.\n...\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-keygen"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -t"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Generating"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" public/private"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pair.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"You"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" may"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" need"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" your"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authenticator"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authorize"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" generation.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We specify "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"resident"}]},{"type":"text","value":" to indicate that the key handle is to be stored on the YubiKey itself, since we will be using this device with multiple computers."}]},{"type":"element","tag":"pre","props":{"className":"language-txt shiki shiki-themes github-light","code":"resident\n Indicate that the key handle should be stored on the FIDO\n authenticator itself. This makes it easier to use the\n authenticator on multiple computers. Resident keys may be\n supported on FIDO2 authenticators and typically require that a PIN\n be set on the authenticator prior to generation. Resident keys\n may be loaded off the authenticator using ssh-add(1). Storing\n both parts of a key on a FIDO authenticator increases the\n likelihood of an attacker being able to use a stolen authenticator\n device.\n","language":"txt","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" Indicate that the key handle should be stored on the FIDO\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator itself. This makes it easier to use the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator on multiple computers. Resident keys may be\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" supported on FIDO2 authenticators and typically require that a PIN\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" be set on the authenticator prior to generation. Resident keys\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" may be loaded off the authenticator using ssh-add(1). Storing\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" both parts of a key on a FIDO authenticator increases the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" likelihood of an attacker being able to use a stolen authenticator\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" device.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's all it takes -- simple enough. Now, when interacting with "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" or "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"git"}]},{"type":"text","value":" you will be prompted to touch the YubiKey to bring that little bit of physical 2FA."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:ssh-ed25519-sk-yubikey.md","_source":"content","_file":"articles/ssh-ed25519-sk-yubikey.md","_stem":"articles/ssh-ed25519-sk-yubikey","_extension":"md"},{"_path":"/articles/unit-testing-micropython-with-mocks","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Unit Testing in MicroPython with Mocks","description":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","date":"2020-02-07","draft":false,"tags":["micropython","testing","mocks","tutorial"],"categories":["python","embedded"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]},{"type":"element","tag":"h1","props":{"id":"mocking"},"children":[{"type":"text","value":"Mocking"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed."}]},{"type":"element","tag":"h1","props":{"id":"a-micropython-mocking-example"},"children":[{"type":"text","value":"A MicroPython Mocking Example"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this example, we will be unit testing a module named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":", that\ndepends on the MicroPython library "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" to log the most recent Epoch time to\na file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# time_logger.py\n\nclass TimeLogger(object):\n\n def save_time(self):\n \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n \"\"\"\n with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n f.write(str(utime.time()))\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"w+\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f.write("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"str"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(utime.time()))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, because the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module is not installed on the machine that the unit\ntests on, we must mock "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module before importing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":" in our\nunit test file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# test_time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"sys.modules["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'utime'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"] "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" time_logger "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we can write a test that patches the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time"}]},{"type":"text","value":" functionality so that\nit returns a value of our choosing -- in this case, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"class TestTimeLogger(unittest.TestCase):\n\n def test_save_time(self):\n \"\"\" Verify that the Epoch time is written to file\n \"\"\"\n with unittest.mock.patch(\"utime.time\", return_value=1234):\n t = TimeLogger()\n t.save_time()\n with open(\"LAST_KNOWN_TIME\") as f:\n self.assertEqual(\"1234\", f.read())\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TestTimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"unittest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"TestCase"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" test_save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Verify that the Epoch time is written to file\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock.patch("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"utime.time\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"return_value"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t.save_time()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" self"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":".assertEqual("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"1234\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", f.read())\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now, when the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"save_time"}]},{"type":"text","value":" method gets the latest time from "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time()"}]},{"type":"text","value":", the\nvalue will be patched to return "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":". That value will be written to a file,\nand our unit test will pass!"}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/unittest.html","rel":["nofollow"]},"children":[{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"unittest"}]},{"type":"text","value":" — Unit testing framework"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:unit-testing-micropython-with-mocks.md","_source":"content","_file":"articles/unit-testing-micropython-with-mocks.md","_stem":"articles/unit-testing-micropython-with-mocks","_extension":"md"},{"_path":"/articles/vim-fugitive-gpg-pinentry","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Using pinentry-mac to sign commits from vim-fugitive","description":"In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","draft":false,"date":"2024-05-11","tags":["vim","tip"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The man, the myth, the legend, Timothy Popallopollis himself "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive/issues/846#issuecomment-253816577","rel":["nofollow"]},"children":[{"type":"text","value":"recommends"}]},{"type":"text","value":" configuring your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":". On macOS this can be done quite by simply installing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-mac"}]},{"type":"text","value":", and updating your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent.conf"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"configuration"},"children":[{"type":"text","value":"Configuration"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First things first, let's install the pinentry program."}]},{"type":"element","tag":"pre","props":{"code":"$ brew install pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, all we need to do is set the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":" option in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"~/.gnupg/gpg-agent.conf"}]},{"type":"text","value":" file."}]},{"type":"element","tag":"pre","props":{"code":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If your don't know the path to your pinentry program, you can throw down a quick "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"which"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"$ which pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" which"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or use your Homebrew prefix."}]},{"type":"element","tag":"pre","props":{"code":"$ echo $(brew --prefix)/bin/pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" $("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --prefix"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"configuration","depth":2,"text":"Configuration"}]}},"_type":"markdown","_id":"content:articles:vim-fugitive-gpg-pinentry.md","_source":"content","_file":"articles/vim-fugitive-gpg-pinentry.md","_stem":"articles/vim-fugitive-gpg-pinentry","_extension":"md"}],"navigation":[{"title":"Articles","_path":"/articles","children":[{"title":"Upgrading the Firmware on the PCEngines APU2","_path":"/articles/apu2-firmware-upgrade"},{"title":"Docker Volume Permissions with SELinux","_path":"/articles/docker-selinux-volumes"},{"title":"Exploring the Digital Ocean `doctl` Utility","_path":"/articles/doctl"},{"title":"Impressions of Fennel with Hammerspoon","_path":"/articles/fennel-initial-exploration"},{"title":"Migrate to TrueNAS Scale from TrueNAS Core","_path":"/articles/migrate-truenas-from-core-to-scale"},{"title":"How To Add an RSS Feed to a Nuxt Website","_path":"/articles/nuxt-content-rss-feed"},{"title":"This Website Has Been Migrated to Nuxt 3 🎉","_path":"/articles/nuxt-v3-migration"},{"title":"Create a Persistent Arch Linux Bootable USB with Vagrant","_path":"/articles/persistent-archlinux-usb"},{"title":"Easily Transcribe Podcasts with Whisper.cpp","_path":"/articles/podcast-transcription-whispercpp"},{"title":"Tip: Re-running Bash Commands","_path":"/articles/quick-tip-rerunning-bash-commands"},{"title":"Reset IPMI Credentials from the Host OS","_path":"/articles/reset-ipmi-password-from-host-os"},{"title":"Configuring a YubiKey for use with OpenSSH","_path":"/articles/ssh-ed25519-sk-yubikey"},{"title":"Unit Testing in MicroPython with Mocks","_path":"/articles/unit-testing-micropython-with-mocks"},{"title":"Using pinentry-mac to sign commits from vim-fugitive","_path":"/articles/vim-fugitive-gpg-pinentry"}]}]} \ No newline at end of file diff --git a/api/_content/query/1BkkvizQw8.1718891166808.json b/api/_content/query/6WfgQ5T9tH.1720229301475.json similarity index 99% rename from api/_content/query/1BkkvizQw8.1718891166808.json rename to api/_content/query/6WfgQ5T9tH.1720229301475.json index c2772ab5..16c4af21 100644 --- a/api/_content/query/1BkkvizQw8.1718891166808.json +++ b/api/_content/query/6WfgQ5T9tH.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/doctl","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Exploring the Digital Ocean `doctl` Utility","description":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","date":"2023-01-01","tags":["linux","digital-ocean"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To start things off, I had to install and setup authentication to Digital Ocean. Doing\nthis on my Mac machine, I opted to use "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"# install `doctl`\nbrew install doctl\n\n# setup authentication\ndoctl auth init\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# install `doctl`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" doctl\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# setup authentication\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" auth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" init\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the online "},{"type":"element","tag":"a","props":{"href":"https://docs.digitalocean.com/reference/doctl/reference/compute/droplet/create/","rel":["nofollow"]},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":" is fantastic, I instead found myself mostly referencing the outputs of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--help"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create --help\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --help\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I had to find the image name of the version of Ubuntu I wanted to install:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute image list --public | grep ubuntu-22\n\n# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --public"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" grep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And also the slug of the compute size:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute size list\n\n# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've also configured a few SSH keys with Digital Ocean, and I can have the key (specified by ID) provisioned to the machine using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--ssh-keys"}]},{"type":"text","value":" flag."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh-key list\n\n# ID Name FingerPrint\n# 1234 mini \n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# ID Name FingerPrint\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 1234 mini \n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Also, I wanted to install a few packages to the box upon creation, this can be done easily with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--user-data-file"}]},{"type":"text","value":" flag to run an initialization script."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"echo 'apt install -y imagemagick zip' > bootstrap.sh\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'apt install -y imagemagick zip'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" >"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bootstrap.sh\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Putting it all together, here is the simple command for creating a small compute instance!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create \\\n --image ubuntu-22-10-x64 \\\n --size s-1vcpu-512mb-10gb \\\n --region nyc1 \\\n --ssh-keys 1234 \\\n --user-data-file boostrap.sh \\\n ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22-10-x64"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" s-1vcpu-512mb-10gb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --region"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" nyc1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --ssh-keys"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --user-data-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" boostrap.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, I can connect, do my thing, and destroy the instance."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet delete --force ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" delete"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --force"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"All-in-all, I was up and running in about 20 minutes. What a handy utility!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:doctl.md","_source":"content","_file":"articles/doctl.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/doctl","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Exploring the Digital Ocean `doctl` Utility","description":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","date":"2023-01-01","tags":["linux","digital-ocean"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"doctl"}]},{"type":"text","value":" command line utility.\nThis proved to be an "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"extremely"}]},{"type":"text","value":" easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To start things off, I had to install and setup authentication to Digital Ocean. Doing\nthis on my Mac machine, I opted to use "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"# install `doctl`\nbrew install doctl\n\n# setup authentication\ndoctl auth init\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# install `doctl`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" doctl\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# setup authentication\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" auth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" init\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the online "},{"type":"element","tag":"a","props":{"href":"https://docs.digitalocean.com/reference/doctl/reference/compute/droplet/create/","rel":["nofollow"]},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":" is fantastic, I instead found myself mostly referencing the outputs of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--help"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create --help\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --help\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I had to find the image name of the version of Ubuntu I wanted to install:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute image list --public | grep ubuntu-22\n\n# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --public"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" grep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And also the slug of the compute size:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute size list\n\n# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've also configured a few SSH keys with Digital Ocean, and I can have the key (specified by ID) provisioned to the machine using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--ssh-keys"}]},{"type":"text","value":" flag."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh-key list\n\n# ID Name FingerPrint\n# 1234 mini \n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# ID Name FingerPrint\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# 1234 mini \n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Also, I wanted to install a few packages to the box upon creation, this can be done easily with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--user-data-file"}]},{"type":"text","value":" flag to run an initialization script."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"echo 'apt install -y imagemagick zip' > bootstrap.sh\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'apt install -y imagemagick zip'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" >"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bootstrap.sh\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Putting it all together, here is the simple command for creating a small compute instance!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet create \\\n --image ubuntu-22-10-x64 \\\n --size s-1vcpu-512mb-10gb \\\n --region nyc1 \\\n --ssh-keys 1234 \\\n --user-data-file boostrap.sh \\\n ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" create"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ubuntu-22-10-x64"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --size"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" s-1vcpu-512mb-10gb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --region"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" nyc1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --ssh-keys"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --user-data-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" boostrap.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, I can connect, do my thing, and destroy the instance."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute ssh ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"doctl compute droplet delete --force ephemeral\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"doctl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" compute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" droplet"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" delete"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --force"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ephemeral\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"All-in-all, I was up and running in about 20 minutes. What a handy utility!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:doctl.md","_source":"content","_file":"articles/doctl.md","_stem":"articles/doctl","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/TxpJ5sv0HY.1718891166808.json b/api/_content/query/7TfxHWYxZH.1720229301475.json similarity index 99% rename from api/_content/query/TxpJ5sv0HY.1718891166808.json rename to api/_content/query/7TfxHWYxZH.1720229301475.json index dc60ee79..e73ba574 100644 --- a/api/_content/query/TxpJ5sv0HY.1718891166808.json +++ b/api/_content/query/7TfxHWYxZH.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/fennel-initial-exploration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Impressions of Fennel with Hammerspoon","description":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","draft":false,"date":"2023-10-22","tags":["lisp","hammerspoon","fennel"],"categories":["lisp"],"cover_image":"/images/dall-e-fennel-hammer.jpeg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Fennel"}]},{"type":"text","value":" programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: "},{"type":"element","tag":"a","props":{"href":"https://www.hammerspoon.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Hammerspoon"}]},{"type":"text","value":", and "},{"type":"element","tag":"a","props":{"href":"https://neovim.io/","rel":["nofollow"]},"children":[{"type":"text","value":"Neovim"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"initial-observations"},"children":[{"type":"text","value":"Initial Observations"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/tree/795749fa17e1310bb001bb7deaa22be8689f0027/hammerspoon/.hammerspoon/modules","rel":["nofollow"]},"children":[{"type":"text","value":"modules"}]},{"type":"text","value":" that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project..."}]},{"type":"element","tag":"h2","props":{"id":"integrating-fennel-with-hammerspoon"},"children":[{"type":"text","value":"Integrating Fennel with Hammerspoon"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While official documentation exists describing how to "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/setup#embedding-fennel","rel":["nofollow"]},"children":[{"type":"text","value":"embed fennel"}]},{"type":"text","value":" into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.path"}]},{"type":"text","value":" and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.cpath"}]},{"type":"text","value":" properties in Lua, but I was unable to get this to\nwork."}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://blog.exupero.org/hammerspoon-with-fennel/","rel":["nofollow"]},"children":[{"type":"text","value":"https://blog.exupero.org/hammerspoon-with-fennel/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer/blob/master/init.lua","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/agzam/spacehammer/blob/master/init.lua"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Ultimately, I opted to include the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.lua"}]},{"type":"text","value":" file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.path"}]},{"type":"text","value":" to point to the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"*.fnl"}]},{"type":"text","value":" files in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":".hammerspoon/"}]},{"type":"text","value":" directory, and\nttranslating these modules can begin!"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"/.hammerspoon/?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"-- init.lua\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"local"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" fennel "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'fennel'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" .."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \";\" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.getenv"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"HOME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"/.hammerspoon/?.fnl\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"table.insert"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"package.loaders"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" or"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.searchers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"searcher"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'main'\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"translating-lua-to-fennel"},"children":[{"type":"text","value":"Translating Lua to Fennel"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/see","rel":["nofollow"]},"children":[{"type":"text","value":"anti-fennel"}]},{"type":"text","value":", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sleep"}]},{"type":"text","value":" function\nfrom the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"helpers"}]},{"type":"text","value":" module into the compiler:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"function sleep(ms)\n os.execute(\"sleep \" .. tonumber(ms) / 1000)\nend\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.execute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" tonumber"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(fn sleep [ms]\n (os.execute (.. \"sleep \" (/ (tonumber ms) 1000))))\n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(fn "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [ms]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (os.execute (.. "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (tonumber ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As another example, here is the output for my "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"caffeine"}]},{"type":"text","value":" toggle:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"hs.hotkey.bind(HYPER, \"0\", function()\n hs.caffeinate.toggle(\"displayIdle\")\n if hs.caffeinate.get(\"displayIdle\") then\n helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n else\n helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n end\nend)\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hotkey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"bind"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(HYPER, "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"0\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"toggle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"get"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"then\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"success"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"check"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" else\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ban"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(hs.hotkey.bind HYPER :0\n (fn [] (hs.caffeinate.toggle :displayIdle)\n (if (hs.caffeinate.get :displayIdle)\n (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban)))) \n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(hs.hotkey.bind HYPER "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":0\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (fn [] (hs.caffeinate.toggle "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (hs.caffeinate.get "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.success helpers.assets.check)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.error helpers.assets.ban))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This was especially helpful for more gnarly modules like the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"window"}]},{"type":"text","value":" module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!"}]},{"type":"element","tag":"h2","props":{"id":"next-steps"},"children":[{"type":"text","value":"Next Steps"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Additionally, before beginning this endeavor, I was already aware of projects like\n"},{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer","rel":["nofollow"]},"children":[{"type":"text","value":"spacehammer"}]},{"type":"text","value":"; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/pull/19/files","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/cmpadden/dotfiles/pull/19/files"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"initial-observations","depth":2,"text":"Initial Observations"},{"id":"integrating-fennel-with-hammerspoon","depth":2,"text":"Integrating Fennel with Hammerspoon"},{"id":"translating-lua-to-fennel","depth":2,"text":"Translating Lua to Fennel"},{"id":"next-steps","depth":2,"text":"Next Steps"}]}},"_type":"markdown","_id":"content:articles:fennel-initial-exploration.md","_source":"content","_file":"articles/fennel-initial-exploration.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/fennel-initial-exploration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Impressions of Fennel with Hammerspoon","description":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","draft":false,"date":"2023-10-22","tags":["lisp","hammerspoon","fennel"],"categories":["lisp"],"cover_image":"/images/dall-e-fennel-hammer.jpeg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Fennel"}]},{"type":"text","value":" programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: "},{"type":"element","tag":"a","props":{"href":"https://www.hammerspoon.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Hammerspoon"}]},{"type":"text","value":", and "},{"type":"element","tag":"a","props":{"href":"https://neovim.io/","rel":["nofollow"]},"children":[{"type":"text","value":"Neovim"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"initial-observations"},"children":[{"type":"text","value":"Initial Observations"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/tree/795749fa17e1310bb001bb7deaa22be8689f0027/hammerspoon/.hammerspoon/modules","rel":["nofollow"]},"children":[{"type":"text","value":"modules"}]},{"type":"text","value":" that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project..."}]},{"type":"element","tag":"h2","props":{"id":"integrating-fennel-with-hammerspoon"},"children":[{"type":"text","value":"Integrating Fennel with Hammerspoon"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While official documentation exists describing how to "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/setup#embedding-fennel","rel":["nofollow"]},"children":[{"type":"text","value":"embed fennel"}]},{"type":"text","value":" into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.path"}]},{"type":"text","value":" and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"package.cpath"}]},{"type":"text","value":" properties in Lua, but I was unable to get this to\nwork."}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://blog.exupero.org/hammerspoon-with-fennel/","rel":["nofollow"]},"children":[{"type":"text","value":"https://blog.exupero.org/hammerspoon-with-fennel/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer/blob/master/init.lua","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/agzam/spacehammer/blob/master/init.lua"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Ultimately, I opted to include the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.lua"}]},{"type":"text","value":" file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fennel.path"}]},{"type":"text","value":" to point to the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"*.fnl"}]},{"type":"text","value":" files in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":".hammerspoon/"}]},{"type":"text","value":" directory, and\nttranslating these modules can begin!"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"/.hammerspoon/?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"-- init.lua\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"local"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" fennel "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'fennel'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" .."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \";\" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.getenv"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"HOME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"/.hammerspoon/?.fnl\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"table.insert"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"package.loaders"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" or"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" package.searchers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", fennel."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"searcher"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"require"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'main'\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"translating-lua-to-fennel"},"children":[{"type":"text","value":"Translating Lua to Fennel"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called "},{"type":"element","tag":"a","props":{"href":"https://fennel-lang.org/see","rel":["nofollow"]},"children":[{"type":"text","value":"anti-fennel"}]},{"type":"text","value":", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sleep"}]},{"type":"text","value":" function\nfrom the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"helpers"}]},{"type":"text","value":" module into the compiler:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"function sleep(ms)\n os.execute(\"sleep \" .. tonumber(ms) / 1000)\nend\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" os.execute"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \" "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":".."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" tonumber"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(fn sleep [ms]\n (os.execute (.. \"sleep \" (/ (tonumber ms) 1000))))\n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(fn "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"sleep"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [ms]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (os.execute (.. "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"sleep \""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"/"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (tonumber ms) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As another example, here is the output for my "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"caffeine"}]},{"type":"text","value":" toggle:"}]},{"type":"element","tag":"pre","props":{"className":"language-lua shiki shiki-themes github-light","code":"hs.hotkey.bind(HYPER, \"0\", function()\n hs.caffeinate.toggle(\"displayIdle\")\n if hs.caffeinate.get(\"displayIdle\") then\n helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n else\n helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n end\nend)\n","language":"lua","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hotkey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"bind"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(HYPER, "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"0\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"toggle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" hs."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"caffeinate"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"get"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"displayIdle\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"then\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"success"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"check"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" else\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"show"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"styles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", helpers."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"assets"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ban"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"className":"language-lisp shiki shiki-themes github-light","code":"(hs.hotkey.bind HYPER :0\n (fn [] (hs.caffeinate.toggle :displayIdle)\n (if (hs.caffeinate.get :displayIdle)\n (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban)))) \n","language":"lisp","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(hs.hotkey.bind HYPER "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":0\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (fn [] (hs.caffeinate.toggle "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (hs.caffeinate.get "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":":displayIdle"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Enabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.success helpers.assets.check)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"helpers"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":":show "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Caffeine Disabled\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" nil"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" helpers.styles.error helpers.assets.ban))))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This was especially helpful for more gnarly modules like the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"window"}]},{"type":"text","value":" module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!"}]},{"type":"element","tag":"h2","props":{"id":"next-steps"},"children":[{"type":"text","value":"Next Steps"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Additionally, before beginning this endeavor, I was already aware of projects like\n"},{"type":"element","tag":"a","props":{"href":"https://github.com/agzam/spacehammer","rel":["nofollow"]},"children":[{"type":"text","value":"spacehammer"}]},{"type":"text","value":"; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/dotfiles/pull/19/files","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/cmpadden/dotfiles/pull/19/files"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"initial-observations","depth":2,"text":"Initial Observations"},{"id":"integrating-fennel-with-hammerspoon","depth":2,"text":"Integrating Fennel with Hammerspoon"},{"id":"translating-lua-to-fennel","depth":2,"text":"Translating Lua to Fennel"},{"id":"next-steps","depth":2,"text":"Next Steps"}]}},"_type":"markdown","_id":"content:articles:fennel-initial-exploration.md","_source":"content","_file":"articles/fennel-initial-exploration.md","_stem":"articles/fennel-initial-exploration","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/cOxeB6k0CX.1718891166808.json b/api/_content/query/98CVAb0zLR.1720229301475.json similarity index 98% rename from api/_content/query/cOxeB6k0CX.1718891166808.json rename to api/_content/query/98CVAb0zLR.1720229301475.json index 5e5eac55..05f77075 100644 --- a/api/_content/query/cOxeB6k0CX.1718891166808.json +++ b/api/_content/query/98CVAb0zLR.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/migrate-truenas-from-core-to-scale","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Migrate to TrueNAS Scale from TrueNAS Core","description":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","date":"2021-12-28","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":" in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Make a backup of your system’s configuration\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"System > General"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save Config"}]},{"type":"text","value":", check the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Export Secret Seed"}]},{"type":"text","value":" box, and click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Export dataset keys for the encrypted pools\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Storage > Pools"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click the cog icon, and select "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Export Dataset Keys"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Insert the TrueNAS Core bootable USB into the NAS"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the Supermicro IPMI interface select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Remote Control"}]},{"type":"text","value":" and "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"iKVM/HTML5"}]},{"type":"text","value":" and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Reboot"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Select the bootable USB as the boot device"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the TrueNAS installation wizard, select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":", select the drive that contains the TrueNAS installation, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Upgrade Install"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference "},{"type":"element","tag":"a","props":{"href":"https://www.truenas.com/help-me-choose/","rel":["nofollow"]},"children":[{"type":"text","value":"this table"}]},{"type":"text","value":"."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:migrate-truenas-from-core-to-scale.md","_source":"content","_file":"articles/migrate-truenas-from-core-to-scale.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/migrate-truenas-from-core-to-scale","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Migrate to TrueNAS Scale from TrueNAS Core","description":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","date":"2021-12-28","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":" in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Make a backup of your system’s configuration\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"System > General"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save Config"}]},{"type":"text","value":", check the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Export Secret Seed"}]},{"type":"text","value":" box, and click "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Save"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Export dataset keys for the encrypted pools\n"},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Navigate to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Storage > Pools"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Click the cog icon, and select "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Export Dataset Keys"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Insert the TrueNAS Core bootable USB into the NAS"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the Supermicro IPMI interface select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Remote Control"}]},{"type":"text","value":" and "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"iKVM/HTML5"}]},{"type":"text","value":" and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Reboot"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Select the bootable USB as the boot device"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"From the TrueNAS installation wizard, select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Install/Upgrade"}]},{"type":"text","value":", select the drive that contains the TrueNAS installation, and select "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Upgrade Install"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference "},{"type":"element","tag":"a","props":{"href":"https://www.truenas.com/help-me-choose/","rel":["nofollow"]},"children":[{"type":"text","value":"this table"}]},{"type":"text","value":"."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:migrate-truenas-from-core-to-scale.md","_source":"content","_file":"articles/migrate-truenas-from-core-to-scale.md","_stem":"articles/migrate-truenas-from-core-to-scale","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/DIau8q3IMV.1718891166808.json b/api/_content/query/DIau8q3IMV.1720229301475.json similarity index 100% rename from api/_content/query/DIau8q3IMV.1718891166808.json rename to api/_content/query/DIau8q3IMV.1720229301475.json diff --git a/api/_content/query/lIKyXFs9L8.1718891166808.json b/api/_content/query/LcWrOc5HNX.1720229301475.json similarity index 99% rename from api/_content/query/lIKyXFs9L8.1718891166808.json rename to api/_content/query/LcWrOc5HNX.1720229301475.json index aca9d3d2..a8b56dff 100644 --- a/api/_content/query/lIKyXFs9L8.1718891166808.json +++ b/api/_content/query/LcWrOc5HNX.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/quick-tip-rerunning-bash-commands","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Tip: Re-running Bash Commands","description":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","date":"2021-09-22","draft":false,"tags":["tip","bash"],"categories":["tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ pacman -Syu\nerror: you cannot perform this operation unless you are root.\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" cannot"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" perform"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" this"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" operation"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" unless"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" are"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" root.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Well, I have good news for you -- you can easily re-issue a command with the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" designator! Simply type "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" followed by "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" and you're good to go."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ sudo !!\nsudo pacman -Syu\n[sudo] password for colton:\n:: Synchronizing package databases...\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !!\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[sudo] password "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" colton:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"::"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" Synchronizing"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" package"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" databases...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Commands that are prefixed with a bang, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":", are considered "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event\nDesignators,"}]},{"type":"text","value":" and are references to your command-line history. You can take a\nlook at your history with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"history"}]},{"type":"text","value":" command."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ history\n 1021 touch hello_world.txt\n 1022 ls\n 1023 echo \"Here we go again!\"\n 1024 find . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" history\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1021"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" hello_world.txt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1022"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1023"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1024"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are many ways to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":" in your shell. For example, if you wanted to\nre-issue a specific command in your history, you could use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!n"}]},{"type":"text","value":" where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" is\nthe number next to the command in your history."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !1023\necho \"Here we go again!\"\nHere we go again!\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !1023\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Here"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" we"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" go"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" again!\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the command you issued 4-commands ago, you can use\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!-4"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !-4\nls\nhello_world.txt\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !-4\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hello_world.txt\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the last command that started with the string\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":", you can use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!find"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !find\nfind . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !find\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Be sure to check out the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event Designators"}]},{"type":"text","value":" section of the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"bash"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"man"}]},{"type":"text","value":" pages\nfor more information!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As an aside, for even faster command-line history navigation, be sure to check\nout the excellent "},{"type":"element","tag":"a","props":{"href":"https://github.com/junegunn/fzf","rel":["nofollow"]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" utility by "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"junegunn."}]},{"type":"text","value":"\nOne of the many features of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" is browsing and re-issuing commands from your\ncommand-line history with a fuzzy-finder!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:quick-tip-rerunning-bash-commands.md","_source":"content","_file":"articles/quick-tip-rerunning-bash-commands.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/quick-tip-rerunning-bash-commands","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Tip: Re-running Bash Commands","description":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","date":"2021-09-22","draft":false,"tags":["tip","bash"],"categories":["tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" for a command that requires\nroot privileges."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ pacman -Syu\nerror: you cannot perform this operation unless you are root.\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"error:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" cannot"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" perform"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" this"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" operation"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" unless"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" you"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" are"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" root.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Well, I have good news for you -- you can easily re-issue a command with the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" designator! Simply type "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sudo"}]},{"type":"text","value":" followed by "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!!"}]},{"type":"text","value":" and you're good to go."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ sudo !!\nsudo pacman -Syu\n[sudo] password for colton:\n:: Synchronizing package databases...\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !!\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pacman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -Syu\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[sudo] password "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"for"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" colton:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"::"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" Synchronizing"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" package"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" databases...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Commands that are prefixed with a bang, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":", are considered "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event\nDesignators,"}]},{"type":"text","value":" and are references to your command-line history. You can take a\nlook at your history with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"history"}]},{"type":"text","value":" command."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ history\n 1021 touch hello_world.txt\n 1022 ls\n 1023 echo \"Here we go again!\"\n 1024 find . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" history\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1021"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" hello_world.txt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1022"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1023"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" 1024"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are many ways to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":" in your shell. For example, if you wanted to\nre-issue a specific command in your history, you could use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!n"}]},{"type":"text","value":" where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" is\nthe number next to the command in your history."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !1023\necho \"Here we go again!\"\nHere we go again!\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !1023\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Here we go again!\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Here"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" we"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" go"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" again!\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the command you issued 4-commands ago, you can use\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!-4"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !-4\nls\nhello_world.txt\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !-4\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"ls\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"hello_world.txt\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or... if you wanted to run the last command that started with the string\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":", you can use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"!find"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-bash shiki shiki-themes github-light","code":"$ !find\nfind . -name *.py\n","language":"bash","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" !find\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -name"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":".py\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Be sure to check out the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Event Designators"}]},{"type":"text","value":" section of the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"bash"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"man"}]},{"type":"text","value":" pages\nfor more information!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"--"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As an aside, for even faster command-line history navigation, be sure to check\nout the excellent "},{"type":"element","tag":"a","props":{"href":"https://github.com/junegunn/fzf","rel":["nofollow"]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" utility by "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"junegunn."}]},{"type":"text","value":"\nOne of the many features of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fzf"}]},{"type":"text","value":" is browsing and re-issuing commands from your\ncommand-line history with a fuzzy-finder!"}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:quick-tip-rerunning-bash-commands.md","_source":"content","_file":"articles/quick-tip-rerunning-bash-commands.md","_stem":"articles/quick-tip-rerunning-bash-commands","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/C0SimRluqy.1718891166808.json b/api/_content/query/Nr5UObwduV.1720229301475.json similarity index 98% rename from api/_content/query/C0SimRluqy.1718891166808.json rename to api/_content/query/Nr5UObwduV.1720229301475.json index d88738ad..178e1f2b 100644 --- a/api/_content/query/C0SimRluqy.1718891166808.json +++ b/api/_content/query/Nr5UObwduV.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/nuxt-v3-migration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"This Website Has Been Migrated to Nuxt 3 🎉","description":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","date":"2022-12-31","tags":["nuxt"],"categories":["web"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you're curious what changes were required to make the migration, you can check out "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/cmpadden.github.io/pull/3","rel":["nofollow"]},"children":[{"type":"text","value":"pull request #3"}]},{"type":"text","value":" in the GitHub repository."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"img","props":{"alt":"Screenshot of Nuxt Migration Pull Request","src":"/images/nuxt-migration-pr.png"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious.\nFor this reason, I opted to generate a new project entirely, and port existing code to this clean slate.\nI believe that this resulted in a project with a bit less cruft."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The most valuable resources for making these changes include:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/migration/overview","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Migration Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/getting-started/introduction","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Framework Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://tailwindcss.nuxt.dev/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Tailwind Module Documentation"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content Module Documentation"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Part of the delay for doing this upgrade was in waiting for module developers to support this major release.\nI'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available!\nI just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:nuxt-v3-migration.md","_source":"content","_file":"articles/nuxt-v3-migration.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/nuxt-v3-migration","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"This Website Has Been Migrated to Nuxt 3 🎉","description":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","date":"2022-12-31","tags":["nuxt"],"categories":["web"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you're curious what changes were required to make the migration, you can check out "},{"type":"element","tag":"a","props":{"href":"https://github.com/cmpadden/cmpadden.github.io/pull/3","rel":["nofollow"]},"children":[{"type":"text","value":"pull request #3"}]},{"type":"text","value":" in the GitHub repository."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"img","props":{"alt":"Screenshot of Nuxt Migration Pull Request","src":"/images/nuxt-migration-pr.png"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious.\nFor this reason, I opted to generate a new project entirely, and port existing code to this clean slate.\nI believe that this resulted in a project with a bit less cruft."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The most valuable resources for making these changes include:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/migration/overview","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Migration Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://nuxt.com/docs/getting-started/introduction","rel":["nofollow"]},"children":[{"type":"text","value":"The Nuxt Framework Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://tailwindcss.nuxt.dev/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Tailwind Module Documentation"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content Module Documentation"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Part of the delay for doing this upgrade was in waiting for module developers to support this major release.\nI'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available!\nI just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:nuxt-v3-migration.md","_source":"content","_file":"articles/nuxt-v3-migration.md","_stem":"articles/nuxt-v3-migration","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/0ikQYfLQVZ.1718891166808.json b/api/_content/query/QmL7G3Pk7i.1720229301475.json similarity index 99% rename from api/_content/query/0ikQYfLQVZ.1718891166808.json rename to api/_content/query/QmL7G3Pk7i.1720229301475.json index 5eddad60..a742e40e 100644 --- a/api/_content/query/0ikQYfLQVZ.1718891166808.json +++ b/api/_content/query/QmL7G3Pk7i.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/unit-testing-micropython-with-mocks","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Unit Testing in MicroPython with Mocks","description":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","date":"2020-02-07","draft":false,"tags":["micropython","testing","mocks","tutorial"],"categories":["python","embedded"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]},{"type":"element","tag":"h1","props":{"id":"mocking"},"children":[{"type":"text","value":"Mocking"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed."}]},{"type":"element","tag":"h1","props":{"id":"a-micropython-mocking-example"},"children":[{"type":"text","value":"A MicroPython Mocking Example"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this example, we will be unit testing a module named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":", that\ndepends on the MicroPython library "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" to log the most recent Epoch time to\na file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# time_logger.py\n\nclass TimeLogger(object):\n\n def save_time(self):\n \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n \"\"\"\n with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n f.write(str(utime.time()))\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"w+\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f.write("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"str"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(utime.time()))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, because the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module is not installed on the machine that the unit\ntests on, we must mock "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module before importing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":" in our\nunit test file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# test_time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"sys.modules["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'utime'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"] "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" time_logger "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we can write a test that patches the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time"}]},{"type":"text","value":" functionality so that\nit returns a value of our choosing -- in this case, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"class TestTimeLogger(unittest.TestCase):\n\n def test_save_time(self):\n \"\"\" Verify that the Epoch time is written to file\n \"\"\"\n with unittest.mock.patch(\"utime.time\", return_value=1234):\n t = TimeLogger()\n t.save_time()\n with open(\"LAST_KNOWN_TIME\") as f:\n self.assertEqual(\"1234\", f.read())\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TestTimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"unittest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"TestCase"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" test_save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Verify that the Epoch time is written to file\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock.patch("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"utime.time\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"return_value"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t.save_time()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" self"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":".assertEqual("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"1234\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", f.read())\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now, when the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"save_time"}]},{"type":"text","value":" method gets the latest time from "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time()"}]},{"type":"text","value":", the\nvalue will be patched to return "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":". That value will be written to a file,\nand our unit test will pass!"}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/unittest.html","rel":["nofollow"]},"children":[{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"unittest"}]},{"type":"text","value":" — Unit testing framework"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:unit-testing-micropython-with-mocks.md","_source":"content","_file":"articles/unit-testing-micropython-with-mocks.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/unit-testing-micropython-with-mocks","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Unit Testing in MicroPython with Mocks","description":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","date":"2020-02-07","draft":false,"tags":["micropython","testing","mocks","tutorial"],"categories":["python","embedded"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality."}]},{"type":"element","tag":"h1","props":{"id":"mocking"},"children":[{"type":"text","value":"Mocking"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed."}]},{"type":"element","tag":"h1","props":{"id":"a-micropython-mocking-example"},"children":[{"type":"text","value":"A MicroPython Mocking Example"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this example, we will be unit testing a module named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":", that\ndepends on the MicroPython library "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" to log the most recent Epoch time to\na file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# time_logger.py\n\nclass TimeLogger(object):\n\n def save_time(self):\n \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n \"\"\"\n with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n f.write(str(utime.time()))\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"w+\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f.write("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"str"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(utime.time()))\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, because the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module is not installed on the machine that the unit\ntests on, we must mock "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime"}]},{"type":"text","value":" module before importing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"time_logger"}]},{"type":"text","value":" in our\nunit test file."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# test_time_logger.py\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"sys.modules["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'utime'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"] "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" MagicMock()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" time_logger "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we can write a test that patches the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time"}]},{"type":"text","value":" functionality so that\nit returns a value of our choosing -- in this case, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"className":"language-python shiki shiki-themes github-light","code":"class TestTimeLogger(unittest.TestCase):\n\n def test_save_time(self):\n \"\"\" Verify that the Epoch time is written to file\n \"\"\"\n with unittest.mock.patch(\"utime.time\", return_value=1234):\n t = TimeLogger()\n t.save_time()\n with open(\"LAST_KNOWN_TIME\") as f:\n self.assertEqual(\"1234\", f.read())\n","language":"python","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"class"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" TestTimeLogger"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"unittest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"TestCase"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" def"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" test_save_time"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(self):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\" Verify that the Epoch time is written to file\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"\"\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" unittest.mock.patch("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"utime.time\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"return_value"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"1234"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"):\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" TimeLogger()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" t.save_time()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" with"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" open"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"LAST_KNOWN_TIME\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"as"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" f:\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" self"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":".assertEqual("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"1234\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", f.read())\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now, when the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"save_time"}]},{"type":"text","value":" method gets the latest time from "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"utime.time()"}]},{"type":"text","value":", the\nvalue will be patched to return "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"1234"}]},{"type":"text","value":". That value will be written to a file,\nand our unit test will pass!"}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/unittest.html","rel":["nofollow"]},"children":[{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"unittest"}]},{"type":"text","value":" — Unit testing framework"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:unit-testing-micropython-with-mocks.md","_source":"content","_file":"articles/unit-testing-micropython-with-mocks.md","_stem":"articles/unit-testing-micropython-with-mocks","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/SFFy74pu72.1718891166808.json b/api/_content/query/TDaCLaQ73L.1720229301475.json similarity index 98% rename from api/_content/query/SFFy74pu72.1718891166808.json rename to api/_content/query/TDaCLaQ73L.1720229301475.json index a9d5401c..cf77636a 100644 --- a/api/_content/query/SFFy74pu72.1718891166808.json +++ b/api/_content/query/TDaCLaQ73L.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/reset-ipmi-password-from-host-os","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Reset IPMI Credentials from the Host OS","description":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","date":"2021-12-27","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from\nthe web interface. This is done by navigating to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Network > IPMI"}]},{"type":"text","value":", and simply entering a new value in the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"IPMI\nPassword Reset"}]},{"type":"text","value":" field."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using some other OS that doesn't have this feature, you can achieve similar results by using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ipmitool"}]},{"type":"text","value":"\ncommand-line utility."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, you'll want to determine the user ID associated with the user for whom you'd like to reset the password."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this case, we will be resetting the password for "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ADMIN"}]},{"type":"text","value":" who has a user ID of "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"2"}]},{"type":"text","value":". Then we'll assign the new\npassword like so:"}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user set password 2 \n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user set password 2 \n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And you should be good to go!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"..."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Alternatively, if you'd like to factory reset the baseboard management controller (BMC), which will reset the IPMI\ncredentials to their default value, you can issue the following command."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool raw 0x3c 0x40\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool raw 0x3c 0x40\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x3c"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":" argument, a.k.a. the network function code that defines the functional routing for\nmessages, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x40"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":". According to section 5.1 of the "},{"type":"element","tag":"a","props":{"href":"https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf","rel":["nofollow"]},"children":[{"type":"text","value":"IPMI interface\nspecification"}]},{"type":"text","value":",\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"netfn"}]},{"type":"text","value":" codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some\nSupermicro references on these vendor specific network functions without much luck other than various "},{"type":"element","tag":"a","props":{"href":"https://www.supermicro.com/support/faqs/faq.cfm?faq=15448","rel":["nofollow"]},"children":[{"type":"text","value":"support\nresponses"}]},{"type":"text","value":" on how to reset a device. Bummer!"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:reset-ipmi-password-from-host-os.md","_source":"content","_file":"articles/reset-ipmi-password-from-host-os.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/reset-ipmi-password-from-host-os","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Reset IPMI Credentials from the Host OS","description":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","date":"2021-12-27","tags":["homelab","supermicro","truenas"],"categories":["homelab"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from\nthe web interface. This is done by navigating to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Network > IPMI"}]},{"type":"text","value":", and simply entering a new value in the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"IPMI\nPassword Reset"}]},{"type":"text","value":" field."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are using some other OS that doesn't have this feature, you can achieve similar results by using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ipmitool"}]},{"type":"text","value":"\ncommand-line utility."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, you'll want to determine the user ID associated with the user for whom you'd like to reset the password."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this case, we will be resetting the password for "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ADMIN"}]},{"type":"text","value":" who has a user ID of "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"2"}]},{"type":"text","value":". Then we'll assign the new\npassword like so:"}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool user set password 2 \n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool user set password 2 \n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And you should be good to go!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"..."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Alternatively, if you'd like to factory reset the baseboard management controller (BMC), which will reset the IPMI\ncredentials to their default value, you can issue the following command."}]},{"type":"element","tag":"pre","props":{"code":"# ipmitool raw 0x3c 0x40\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# ipmitool raw 0x3c 0x40\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Where "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x3c"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":" argument, a.k.a. the network function code that defines the functional routing for\nmessages, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"0x40"}]},{"type":"text","value":" is the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":""}]},{"type":"text","value":". According to section 5.1 of the "},{"type":"element","tag":"a","props":{"href":"https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf","rel":["nofollow"]},"children":[{"type":"text","value":"IPMI interface\nspecification"}]},{"type":"text","value":",\n"},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"netfn"}]},{"type":"text","value":" codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some\nSupermicro references on these vendor specific network functions without much luck other than various "},{"type":"element","tag":"a","props":{"href":"https://www.supermicro.com/support/faqs/faq.cfm?faq=15448","rel":["nofollow"]},"children":[{"type":"text","value":"support\nresponses"}]},{"type":"text","value":" on how to reset a device. Bummer!"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:reset-ipmi-password-from-host-os.md","_source":"content","_file":"articles/reset-ipmi-password-from-host-os.md","_stem":"articles/reset-ipmi-password-from-host-os","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/0vuDGaHulu.1718891166808.json b/api/_content/query/XgcK3x9EBy.1720229301475.json similarity index 99% rename from api/_content/query/0vuDGaHulu.1718891166808.json rename to api/_content/query/XgcK3x9EBy.1720229301475.json index f9ccd20f..a5d0be1f 100644 --- a/api/_content/query/0vuDGaHulu.1718891166808.json +++ b/api/_content/query/XgcK3x9EBy.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/persistent-archlinux-usb","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Create a Persistent Arch Linux Bootable USB with Vagrant","description":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","date":"2020-01-09","draft":false,"tags":["vagrant","archlinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]},{"type":"element","tag":"h1","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The original intention was to use Docker for this process -- leveraging the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--device"}]},{"type":"text","value":" flag and mounting the target USB device in the Docker container,\nbut the underlying hypervisor in Docker Desktop for Mac does not support this.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"2"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"3"}]}]},{"type":"text","value":" While there are workarounds using Docker\nMachine, Vagrant felt like the path of least resistance."}]},{"type":"element","tag":"h1","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"h2","props":{"id":"create-an-arch-linux-virtual-machine-with-vagrant"},"children":[{"type":"text","value":"Create an Arch Linux Virtual Machine with Vagrant"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Get the latest Arch Linux image "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"4"}]}]},{"type":"text","value":" from the Vagrant Cloud Box\nCatalog."}]},{"type":"element","tag":"pre","props":{"code":"vagrant box add archlinux/archlinux\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" box"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" add"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" archlinux/archlinux\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Determine the USB vendor information for the thumb-drive that we will\npass-through to the virtual machine. Using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" utility that comes\nwith Virtual Box, list the devices, and make note of the Vendor and Product ID."}]},{"type":"element","tag":"pre","props":{"code":" VBoxManage list usbhost\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" VBoxManage"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" usbhost\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Vagrantfile"}]},{"type":"text","value":" with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"archlinx/archlinux"}]},{"type":"text","value":" as the target box, and the USB\ndevice information that is passed through. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"6"}]}]},{"type":"text","value":" Vagrant\noffers a handy customization parameter "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" that calls the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" command under-the-hood, allowing one to enable the guest machine\nto access the host machine's USB devices."}]},{"type":"element","tag":"pre","props":{"code":"# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\nVagrant.configure(\"2\") do |config|\n config.vm.box = \"archlinux/archlinux\"\n config.vm.provider \"virtualbox\" do |vb|\n vb.name = \"archlinux\"\n vb.customize ['modifyvm', :id, '--usb', 'on']\n vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n end\nend\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# -*- mode: ruby -*-\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# vi: set ft=ruby :\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Vagrant.configure(\"2\") do |config|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.box = \"archlinux/archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.provider \"virtualbox\" do |vb|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.name = \"archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['modifyvm', :id, '--usb', 'on']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When virtual machine is brought up, the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"usbfilter"}]},{"type":"text","value":" is applied, and the guest\nis able to access to the host machine's USB device that was specified in the\nfilter."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Start the machine, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" into the guest, and list the devices to confirm that\nthe USB device is available (see: "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"/dev/sdb"}]},{"type":"text","value":")."}]},{"type":"element","tag":"pre","props":{"code":"$ vagrant up\n$ vagrant ssh\n[vagrant@archlinux ~]$ lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 20G 0 disk\n├─sda1 8:1 0 1.9G 0 part [SWAP]\n└─sda2 8:2 0 18.1G 0 part /\nsdb 8:16 1 28.7G 0 disk\n└─sdb1 8:17 1 8G 0 part\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" up\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[vagrant@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]$ lsblk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MAJ:MIN"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RM"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" SIZE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RO"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" TYPE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MOUNTPOINT\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sda"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 20G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"├─sda1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 1.9G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [SWAP]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sda2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 18.1G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" /\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sdb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:16"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 28.7G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sdb1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:17"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"install-arch-linux-on-the-usb-drive"},"children":[{"type":"text","value":"Install Arch Linux on the USB Drive"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Installation Guide"}]},{"type":"text","value":" outlines the installation procedure in\ngreat detail -- the following steps follow this closely with a few alteration\ndue to installing onto removable media."}]},{"type":"element","tag":"h3","props":{"id":"partition-the-disk-uefi-with-gpt"},"children":[{"type":"text","value":"Partition the Disk (UEFI with GPT)"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# fdisk /dev/sdb\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# fdisk /dev/sdb\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command (m for help): p\nDisk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\nDisk model: Ultra Fit\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 1050623 1048576 512M EFI System\n/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n\nFilesystem/RAID signature on partition 1 will be wiped.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command (m for help): p\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk model: Ultra Fit\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Units: sectors of 1 * 512 = 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Sector size (logical/physical): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"I/O size (minimum/optimal): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disklabel type: gpt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Device Start End Sectors Size Type\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb1 2048 1050623 1048576 512M EFI System\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Filesystem/RAID signature on partition 1 will be wiped.\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"format-the-partitions"},"children":[{"type":"text","value":"Format the Partitions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The UEFI specification mandates support for FAT file-systems, and FAT32 is\nrecommended for removable media. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"7"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -Sy dosfstools\n[root@archlinux ~]# mkfs.fat -F32 /dev/sdb1\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -Sy dosfstools\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.fat -F32 /dev/sdb1\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for the root partition, it is recommended to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ext4"}]},{"type":"text","value":" without a journal to\nreduce the reads and writes to the file-system as this is detrimental to the\nflash-based USB drive. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"8"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mkfs.ext4 -O \"^has_journal\" /dev/sdb2\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.ext4 -O "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"^has_journal\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /dev/sdb2\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"mount-the-partitions-and-bootstrap-the-environment"},"children":[{"type":"text","value":"Mount the Partitions and Bootstrap the Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mount /dev/sdb2 /mnt\n[root@archlinux ~]# mkdir -p /mnt/boot/efi\n[root@archlinux ~]# mount /dev/sdb1 /mnt/boot/efi\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb2 /mnt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkdir -p /mnt/boot/efi\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb1 /mnt/boot/efi\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -S arch-install-scripts\n[root@archlinux ~]# pacstrap /mnt base linux linux-firmware\n[root@archlinux ~]# genfstab -U /mnt >> /mnt/etc/fstab\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -S arch-install-scripts\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacstrap /mnt base linux linux-firmware\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# genfstab -U /mnt "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":">>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /mnt/etc/fstab\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"configure-the-new-environment"},"children":[{"type":"text","value":"Configure the New Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# arch-chroot /mnt\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux ~]# arch-chroot /mnt\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Note, one difference here from a standard installation is that the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--removable"}]},{"type":"text","value":" flag is specified when installing the GRUB bootloader.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"10"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Shutdown the virtual machine, restart the host machine, and boot the newly\ncreated Arch Linux thumb-drive!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"🎉"}]},{"type":"element","tag":"h2","props":{"id":"side-note"},"children":[{"type":"text","value":"Side-note"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It was attempted to use the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"controlvm usbattach"}]},{"type":"text","value":" command to pass the USB\ndevice to the guest machine, but this did not work as it expects the virtual\nmachine to already be running, and the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" option runs prior to\nbooting the machine. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"11"}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n\nStderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Desktop on Mac vs. Docker Toolbox"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - HyperKit"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - Docker for Mac - Issue #900"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant Cloud - Arch Linux"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"Attaching USB Devices to VirtualBox Guests using VBoxManage"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub Gist - Vagrant USB Filter"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - EFI System Partition - Format Partitions"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Arch Linux on USB - Installation Tweaks"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Installation Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - GRUB - UEFI Systems"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant VBoxManage Customizations "}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"create-an-arch-linux-virtual-machine-with-vagrant","depth":2,"text":"Create an Arch Linux Virtual Machine with Vagrant"},{"id":"install-arch-linux-on-the-usb-drive","depth":2,"text":"Install Arch Linux on the USB Drive","children":[{"id":"partition-the-disk-uefi-with-gpt","depth":3,"text":"Partition the Disk (UEFI with GPT)"},{"id":"format-the-partitions","depth":3,"text":"Format the Partitions"},{"id":"mount-the-partitions-and-bootstrap-the-environment","depth":3,"text":"Mount the Partitions and Bootstrap the Environment"},{"id":"configure-the-new-environment","depth":3,"text":"Configure the New Environment"}]},{"id":"side-note","depth":2,"text":"Side-note"},{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:persistent-archlinux-usb.md","_source":"content","_file":"articles/persistent-archlinux-usb.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/persistent-archlinux-usb","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Create a Persistent Arch Linux Bootable USB with Vagrant","description":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","date":"2020-01-09","draft":false,"tags":["vagrant","archlinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium."}]},{"type":"element","tag":"h1","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The original intention was to use Docker for this process -- leveraging the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--device"}]},{"type":"text","value":" flag and mounting the target USB device in the Docker container,\nbut the underlying hypervisor in Docker Desktop for Mac does not support this.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"2"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"3"}]}]},{"type":"text","value":" While there are workarounds using Docker\nMachine, Vagrant felt like the path of least resistance."}]},{"type":"element","tag":"h1","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"h2","props":{"id":"create-an-arch-linux-virtual-machine-with-vagrant"},"children":[{"type":"text","value":"Create an Arch Linux Virtual Machine with Vagrant"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Get the latest Arch Linux image "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"4"}]}]},{"type":"text","value":" from the Vagrant Cloud Box\nCatalog."}]},{"type":"element","tag":"pre","props":{"code":"vagrant box add archlinux/archlinux\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" box"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" add"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" archlinux/archlinux\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Determine the USB vendor information for the thumb-drive that we will\npass-through to the virtual machine. Using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" utility that comes\nwith Virtual Box, list the devices, and make note of the Vendor and Product ID."}]},{"type":"element","tag":"pre","props":{"code":" VBoxManage list usbhost\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" VBoxManage"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" usbhost\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Vagrantfile"}]},{"type":"text","value":" with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"archlinx/archlinux"}]},{"type":"text","value":" as the target box, and the USB\ndevice information that is passed through. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"6"}]}]},{"type":"text","value":" Vagrant\noffers a handy customization parameter "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" that calls the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"VBoxManage"}]},{"type":"text","value":" command under-the-hood, allowing one to enable the guest machine\nto access the host machine's USB devices."}]},{"type":"element","tag":"pre","props":{"code":"# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\nVagrant.configure(\"2\") do |config|\n config.vm.box = \"archlinux/archlinux\"\n config.vm.provider \"virtualbox\" do |vb|\n vb.name = \"archlinux\"\n vb.customize ['modifyvm', :id, '--usb', 'on']\n vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n end\nend\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# -*- mode: ruby -*-\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"# vi: set ft=ruby :\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Vagrant.configure(\"2\") do |config|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.box = \"archlinux/archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" config.vm.provider \"virtualbox\" do |vb|\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.name = \"archlinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['modifyvm', :id, '--usb', 'on']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" end\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"end\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When virtual machine is brought up, the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"usbfilter"}]},{"type":"text","value":" is applied, and the guest\nis able to access to the host machine's USB device that was specified in the\nfilter."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Start the machine, "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" into the guest, and list the devices to confirm that\nthe USB device is available (see: "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"/dev/sdb"}]},{"type":"text","value":")."}]},{"type":"element","tag":"pre","props":{"code":"$ vagrant up\n$ vagrant ssh\n[vagrant@archlinux ~]$ lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 20G 0 disk\n├─sda1 8:1 0 1.9G 0 part [SWAP]\n└─sda2 8:2 0 18.1G 0 part /\nsdb 8:16 1 28.7G 0 disk\n└─sdb1 8:17 1 8G 0 part\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" up\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" vagrant"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[vagrant@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]$ lsblk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MAJ:MIN"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RM"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" SIZE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RO"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" TYPE"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" MOUNTPOINT\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sda"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 20G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"├─sda1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 1.9G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" [SWAP]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sda2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 18.1G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" /\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sdb"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:16"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 28.7G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" disk\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"└─sdb1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8:17"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 8G"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 0"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" part\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"install-arch-linux-on-the-usb-drive"},"children":[{"type":"text","value":"Install Arch Linux on the USB Drive"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Installation Guide"}]},{"type":"text","value":" outlines the installation procedure in\ngreat detail -- the following steps follow this closely with a few alteration\ndue to installing onto removable media."}]},{"type":"element","tag":"h3","props":{"id":"partition-the-disk-uefi-with-gpt"},"children":[{"type":"text","value":"Partition the Disk (UEFI with GPT)"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# fdisk /dev/sdb\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# fdisk /dev/sdb\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command (m for help): p\nDisk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\nDisk model: Ultra Fit\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 1050623 1048576 512M EFI System\n/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n\nFilesystem/RAID signature on partition 1 will be wiped.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command (m for help): p\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk model: Ultra Fit\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Units: sectors of 1 * 512 = 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Sector size (logical/physical): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"I/O size (minimum/optimal): 512 bytes / 512 bytes\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disklabel type: gpt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Disk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Device Start End Sectors Size Type\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb1 2048 1050623 1048576 512M EFI System\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Filesystem/RAID signature on partition 1 will be wiped.\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"format-the-partitions"},"children":[{"type":"text","value":"Format the Partitions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The UEFI specification mandates support for FAT file-systems, and FAT32 is\nrecommended for removable media. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"7"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -Sy dosfstools\n[root@archlinux ~]# mkfs.fat -F32 /dev/sdb1\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -Sy dosfstools\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.fat -F32 /dev/sdb1\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for the root partition, it is recommended to use "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ext4"}]},{"type":"text","value":" without a journal to\nreduce the reads and writes to the file-system as this is detrimental to the\nflash-based USB drive. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"8"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mkfs.ext4 -O \"^has_journal\" /dev/sdb2\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkfs.ext4 -O "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"^has_journal\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /dev/sdb2\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"mount-the-partitions-and-bootstrap-the-environment"},"children":[{"type":"text","value":"Mount the Partitions and Bootstrap the Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# mount /dev/sdb2 /mnt\n[root@archlinux ~]# mkdir -p /mnt/boot/efi\n[root@archlinux ~]# mount /dev/sdb1 /mnt/boot/efi\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb2 /mnt\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mkdir -p /mnt/boot/efi\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# mount /dev/sdb1 /mnt/boot/efi\n"}]}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# pacman -S arch-install-scripts\n[root@archlinux ~]# pacstrap /mnt base linux linux-firmware\n[root@archlinux ~]# genfstab -U /mnt >> /mnt/etc/fstab\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacman -S arch-install-scripts\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# pacstrap /mnt base linux linux-firmware\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[root@archlinux "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"~"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]# genfstab -U /mnt "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":">>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" /mnt/etc/fstab\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"configure-the-new-environment"},"children":[{"type":"text","value":"Configure the New Environment"}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux ~]# arch-chroot /mnt\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux ~]# arch-chroot /mnt\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n"}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Note, one difference here from a standard installation is that the\n"},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"--removable"}]},{"type":"text","value":" flag is specified when installing the GRUB bootloader.\n"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"10"}]}]}]},{"type":"element","tag":"pre","props":{"code":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Shutdown the virtual machine, restart the host machine, and boot the newly\ncreated Arch Linux thumb-drive!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"🎉"}]},{"type":"element","tag":"h2","props":{"id":"side-note"},"children":[{"type":"text","value":"Side-note"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It was attempted to use the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"controlvm usbattach"}]},{"type":"text","value":" command to pass the USB\ndevice to the guest machine, but this did not work as it expects the virtual\nmachine to already be running, and the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"vb.customize"}]},{"type":"text","value":" option runs prior to\nbooting the machine. "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"11"}]}]}]},{"type":"element","tag":"pre","props":{"code":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n\nStderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"references"},"children":[{"type":"text","value":"References"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/docker-for-mac/docker-toolbox/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Desktop on Mac vs. Docker Toolbox"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/moby/hyperkit","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - HyperKit"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/docker/for-mac/issues/900","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub - Docker for Mac - Issue #900"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://app.vagrantup.com/archlinux/boxes/archlinux","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant Cloud - Arch Linux"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/","rel":["nofollow"]},"children":[{"type":"text","value":"Attaching USB Devices to VirtualBox Guests using VBoxManage"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://gist.github.com/dscape/7d829c0c116ef419f963","rel":["nofollow"]},"children":[{"type":"text","value":"GitHub Gist - Vagrant USB Filter"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - EFI System Partition - Format Partitions"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Arch Linux on USB - Installation Tweaks"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/Installation_guide","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - Installation Guide"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems","rel":["nofollow"]},"children":[{"type":"text","value":"Arch Linux Wiki - GRUB - UEFI Systems"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations","rel":["nofollow"]},"children":[{"type":"text","value":"Vagrant VBoxManage Customizations "}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"create-an-arch-linux-virtual-machine-with-vagrant","depth":2,"text":"Create an Arch Linux Virtual Machine with Vagrant"},{"id":"install-arch-linux-on-the-usb-drive","depth":2,"text":"Install Arch Linux on the USB Drive","children":[{"id":"partition-the-disk-uefi-with-gpt","depth":3,"text":"Partition the Disk (UEFI with GPT)"},{"id":"format-the-partitions","depth":3,"text":"Format the Partitions"},{"id":"mount-the-partitions-and-bootstrap-the-environment","depth":3,"text":"Mount the Partitions and Bootstrap the Environment"},{"id":"configure-the-new-environment","depth":3,"text":"Configure the New Environment"}]},{"id":"side-note","depth":2,"text":"Side-note"},{"id":"references","depth":2,"text":"References"}]}},"_type":"markdown","_id":"content:articles:persistent-archlinux-usb.md","_source":"content","_file":"articles/persistent-archlinux-usb.md","_stem":"articles/persistent-archlinux-usb","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/AwYZnKuAHr.1718891166808.json b/api/_content/query/ZzD9WRl1Uk.1720229301475.json similarity index 99% rename from api/_content/query/AwYZnKuAHr.1718891166808.json rename to api/_content/query/ZzD9WRl1Uk.1720229301475.json index 461422c3..284f2adb 100644 --- a/api/_content/query/AwYZnKuAHr.1718891166808.json +++ b/api/_content/query/ZzD9WRl1Uk.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/vim-fugitive-gpg-pinentry","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Using pinentry-mac to sign commits from vim-fugitive","description":"In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","draft":false,"date":"2024-05-11","tags":["vim","tip"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The man, the myth, the legend, Timothy Popallopollis himself "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive/issues/846#issuecomment-253816577","rel":["nofollow"]},"children":[{"type":"text","value":"recommends"}]},{"type":"text","value":" configuring your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":". On macOS this can be done quite by simply installing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-mac"}]},{"type":"text","value":", and updating your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent.conf"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"configuration"},"children":[{"type":"text","value":"Configuration"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First things first, let's install the pinentry program."}]},{"type":"element","tag":"pre","props":{"code":"$ brew install pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, all we need to do is set the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":" option in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"~/.gnupg/gpg-agent.conf"}]},{"type":"text","value":" file."}]},{"type":"element","tag":"pre","props":{"code":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If your don't know the path to your pinentry program, you can throw down a quick "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"which"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"$ which pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" which"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or use your Homebrew prefix."}]},{"type":"element","tag":"pre","props":{"code":"$ echo $(brew --prefix)/bin/pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" $("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --prefix"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"configuration","depth":2,"text":"Configuration"}]}},"_type":"markdown","_id":"content:articles:vim-fugitive-gpg-pinentry.md","_source":"content","_file":"articles/vim-fugitive-gpg-pinentry.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/vim-fugitive-gpg-pinentry","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Using pinentry-mac to sign commits from vim-fugitive","description":"In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","draft":false,"date":"2024-05-11","tags":["vim","tip"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In order to sign git commits from within Vim using a plugin like "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive","rel":["nofollow"]},"children":[{"type":"text","value":"tpope/vim-fugitive"}]},{"type":"text","value":", it is necessary to configure the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The man, the myth, the legend, Timothy Popallopollis himself "},{"type":"element","tag":"a","props":{"href":"https://github.com/tpope/vim-fugitive/issues/846#issuecomment-253816577","rel":["nofollow"]},"children":[{"type":"text","value":"recommends"}]},{"type":"text","value":" configuring your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent"}]},{"type":"text","value":" to use a GUI based "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":". On macOS this can be done quite by simply installing "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-mac"}]},{"type":"text","value":", and updating your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"gpg-agent.conf"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"configuration"},"children":[{"type":"text","value":"Configuration"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First things first, let's install the pinentry program."}]},{"type":"element","tag":"pre","props":{"code":"$ brew install pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, all we need to do is set the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"pinentry-program"}]},{"type":"text","value":" option in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"~/.gnupg/gpg-agent.conf"}]},{"type":"text","value":" file."}]},{"type":"element","tag":"pre","props":{"code":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If your don't know the path to your pinentry program, you can throw down a quick "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"which"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"$ which pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" which"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Or use your Homebrew prefix."}]},{"type":"element","tag":"pre","props":{"code":"$ echo $(brew --prefix)/bin/pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" echo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" $("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --prefix"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":")"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"/bin/pinentry-mac\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"/opt/homebrew/bin/pinentry-mac\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"configuration","depth":2,"text":"Configuration"}]}},"_type":"markdown","_id":"content:articles:vim-fugitive-gpg-pinentry.md","_source":"content","_file":"articles/vim-fugitive-gpg-pinentry.md","_stem":"articles/vim-fugitive-gpg-pinentry","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/bXj5vj6Ts0.1718891166808.json b/api/_content/query/bXj5vj6Ts0.1720229301475.json similarity index 100% rename from api/_content/query/bXj5vj6Ts0.1718891166808.json rename to api/_content/query/bXj5vj6Ts0.1720229301475.json diff --git a/api/_content/query/ph6vNEpVOi.1718891166808.json b/api/_content/query/d7v45RMayO.1720229301475.json similarity index 99% rename from api/_content/query/ph6vNEpVOi.1718891166808.json rename to api/_content/query/d7v45RMayO.1720229301475.json index ca4ecbe7..4b52da8d 100644 --- a/api/_content/query/ph6vNEpVOi.1718891166808.json +++ b/api/_content/query/d7v45RMayO.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/podcast-transcription-whispercpp","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Easily Transcribe Podcasts with Whisper.cpp","description":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","draft":false,"date":"2024-01-08","tags":["whisper.cpp","ml"],"categories":["programming"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]},{"type":"element","tag":"h2","props":{"id":"obtain-audio-files"},"children":[{"type":"text","value":"Obtain Audio File(s)"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, let's get the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" file from YouTube using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"youtube-dl"}]},{"type":"text","value":" utility. It should be noted that "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" filetypes, and this utility defaults to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"mp3"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":" $ youtube-dl \\\n --extract-audio \\\n --audio-format wav \\\n --output podcast.wav \\\n \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" youtube-dl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --extract-audio"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --audio-format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This file has a 44.1 kHz sample rate, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects 16 kHz, so let's go ahead and convert that."}]},{"type":"element","tag":"pre","props":{"code":" $ file podcast.wav\npodcast.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n\n $ ffmpeg -i podcast.wav -ar 16000 podcast-16khz.wav\n\n $ file podcast-16khz.wav\npodcast-16khz.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n\n# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n# flag to the `youtube-dl` command -- I will explore this further next time...\n# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ffmpeg"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -ar"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 16000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast-16khz.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# flag to the `youtube-dl` command -- I will explore this further next time...\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"build-whispercpp-transcribe-audio"},"children":[{"type":"text","value":"Build "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" & Transcribe Audio"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's get the latest version of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":", download the English Whisper model, and build the example."}]},{"type":"element","tag":"pre","props":{"code":"# Clone the `whisper.cpp` repository\n $ git clone --depth 1 git@github.com:ggerganov/whisper.cpp && cd whisper.cpp\n\n# Download the English Whisper model in `ggml` format\n $ bash ./models/download-ggml-model.sh base.en\n\n# Build the main example\n $ make\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Clone the `whisper.cpp` repository\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" clone"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --depth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git@github.com:ggerganov/whisper.cpp"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" && "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"cd"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" whisper.cpp\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Download the English Whisper model in `ggml` format\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bash"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./models/download-ggml-model.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" base.en\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Build the main example\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" make\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, let's transcribe that podcast!"}]},{"type":"element","tag":"pre","props":{"code":" $ ./main \\\n -m ~/workspace/whisper.cpp/models/ggml-base.en.bin \\\n -f ~/Downloads/podcast-16khz.wav \\\n --output-vtt \\\n --output-file out\n\n# whisper_print_timings: load time = 114.71 ms\n# whisper_print_timings: fallbacks = 0 p / 0 h\n# whisper_print_timings: mel time = 692.20 ms\n# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n# whisper_print_timings: total time = 80709.54 ms\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./main"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -m"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/workspace/whisper.cpp/models/ggml-base.en.bin"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -f"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/Downloads/podcast-16khz.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-vtt"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" out\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: load time = 114.71 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: fallbacks = 0 p / 0 h\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: mel time = 692.20 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: total time = 80709.54 ms\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A full podcast transcribed in ~80 seconds on an M1 Mac Mini -- not too bad!"}]},{"type":"element","tag":"pre","props":{"code":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"obtain-audio-files","depth":2,"text":"Obtain Audio File(s)"},{"id":"build-whispercpp-transcribe-audio","depth":2,"text":"Build whisper.cpp & Transcribe Audio"}]}},"_type":"markdown","_id":"content:articles:podcast-transcription-whispercpp.md","_source":"content","_file":"articles/podcast-transcription-whispercpp.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/podcast-transcription-whispercpp","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Easily Transcribe Podcasts with Whisper.cpp","description":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","draft":false,"date":"2024-01-08","tags":["whisper.cpp","ml"],"categories":["programming"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive "},{"type":"element","tag":"a","props":{"href":"https://github.com/ggerganov/whisper.cpp","rel":["nofollow"]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" project. This high-performance fork of "},{"type":"element","tag":"a","props":{"href":"https://github.com/openai/whisper","rel":["nofollow"]},"children":[{"type":"text","value":"OpenAI's Whisper"}]},{"type":"text","value":" can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the "},{"type":"element","tag":"a","props":{"href":"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854","rel":["nofollow"]},"children":[{"type":"text","value":"Alter Everything"}]},{"type":"text","value":" podcast."}]},{"type":"element","tag":"h2","props":{"id":"obtain-audio-files"},"children":[{"type":"text","value":"Obtain Audio File(s)"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, let's get the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" file from YouTube using the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"youtube-dl"}]},{"type":"text","value":" utility. It should be noted that "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"wav"}]},{"type":"text","value":" filetypes, and this utility defaults to "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"mp3"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":" $ youtube-dl \\\n --extract-audio \\\n --audio-format wav \\\n --output podcast.wav \\\n \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" youtube-dl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --extract-audio"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --audio-format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This file has a 44.1 kHz sample rate, and "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" expects 16 kHz, so let's go ahead and convert that."}]},{"type":"element","tag":"pre","props":{"code":" $ file podcast.wav\npodcast.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n\n $ ffmpeg -i podcast.wav -ar 16000 podcast-16khz.wav\n\n $ file podcast-16khz.wav\npodcast-16khz.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n\n# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n# flag to the `youtube-dl` command -- I will explore this further next time...\n# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ffmpeg"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -ar"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 16000"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" podcast-16khz.wav\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"podcast-16khz.wav:"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" RIFF"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# flag to the `youtube-dl` command -- I will explore this further next time...\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"build-whispercpp-transcribe-audio"},"children":[{"type":"text","value":"Build "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":" & Transcribe Audio"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's get the latest version of "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"whisper.cpp"}]},{"type":"text","value":", download the English Whisper model, and build the example."}]},{"type":"element","tag":"pre","props":{"code":"# Clone the `whisper.cpp` repository\n $ git clone --depth 1 git@github.com:ggerganov/whisper.cpp && cd whisper.cpp\n\n# Download the English Whisper model in `ggml` format\n $ bash ./models/download-ggml-model.sh base.en\n\n# Build the main example\n $ make\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Clone the `whisper.cpp` repository\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" clone"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --depth"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" 1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" git@github.com:ggerganov/whisper.cpp"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" && "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"cd"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" whisper.cpp\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Download the English Whisper model in `ggml` format\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" bash"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./models/download-ggml-model.sh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" base.en\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# Build the main example\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" make\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, let's transcribe that podcast!"}]},{"type":"element","tag":"pre","props":{"code":" $ ./main \\\n -m ~/workspace/whisper.cpp/models/ggml-base.en.bin \\\n -f ~/Downloads/podcast-16khz.wav \\\n --output-vtt \\\n --output-file out\n\n# whisper_print_timings: load time = 114.71 ms\n# whisper_print_timings: fallbacks = 0 p / 0 h\n# whisper_print_timings: mel time = 692.20 ms\n# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n# whisper_print_timings: total time = 80709.54 ms\n","language":"sh","meta":"","className":"language-sh shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" $"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ./main"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -m"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/workspace/whisper.cpp/models/ggml-base.en.bin"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -f"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ~/Downloads/podcast-16khz.wav"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-vtt"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" \\\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --output-file"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" out\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: load time = 114.71 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: fallbacks = 0 p / 0 h\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: mel time = 692.20 ms\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":"# whisper_print_timings: total time = 80709.54 ms\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"A full podcast transcribed in ~80 seconds on an M1 Mac Mini -- not too bad!"}]},{"type":"element","tag":"pre","props":{"code":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"obtain-audio-files","depth":2,"text":"Obtain Audio File(s)"},{"id":"build-whispercpp-transcribe-audio","depth":2,"text":"Build whisper.cpp & Transcribe Audio"}]}},"_type":"markdown","_id":"content:articles:podcast-transcription-whispercpp.md","_source":"content","_file":"articles/podcast-transcription-whispercpp.md","_stem":"articles/podcast-transcription-whispercpp","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/QB64GpMlA8.1718891166808.json b/api/_content/query/pfbAdBSC9a.1720229301475.json similarity index 99% rename from api/_content/query/QB64GpMlA8.1718891166808.json rename to api/_content/query/pfbAdBSC9a.1720229301475.json index 74ee3769..6934c084 100644 --- a/api/_content/query/QB64GpMlA8.1718891166808.json +++ b/api/_content/query/pfbAdBSC9a.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/ssh-ed25519-sk-yubikey","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Configuring a YubiKey for use with OpenSSH","description":"YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","draft":false,"date":"2024-06-09","tags":["unix","configurations"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In "},{"type":"element","tag":"a","props":{"href":"https://www.openssh.com/txt/release-8.2","rel":["nofollow"]},"children":[{"type":"text","value":"release 8.2 of OpenSSH"}]},{"type":"text","value":" support for FIDO devices was added with public key types \"ecdsa-sk\" and \"ed25519-sk\" (-sk standing for \"security key\"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types \"ecdsa-sk\" and \"ed25519-sk\", along with corresponding certificate types."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's get started by installing the latest version of OpenSSH via "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":", along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ brew install openssh ykman\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" openssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman list\nYubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"YubiKey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 5Ci"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (5.4.3) [OTP+FIDO+CCID]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we'll go ahead and enable a pin on our device via the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"change-pin"}]},{"type":"text","value":" command, as this a requirement for our use."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman fido access change-pin\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" fido"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" access"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" change-pin\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And last, we'll generate the key on our device!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ssh-keygen -t ed25519-sk -O resident\nGenerating public/private ed25519-sk key pair.\nYou may need to touch your authenticator to authorize key generation.\n...\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-keygen"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -t"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Generating"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" public/private"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pair.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"You"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" may"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" need"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" your"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authenticator"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authorize"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" generation.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We specify "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"resident"}]},{"type":"text","value":" to indicate that the key handle is to be stored on the YubiKey itself, since we will be using this device with multiple computers."}]},{"type":"element","tag":"pre","props":{"className":"language-txt shiki shiki-themes github-light","code":"resident\n Indicate that the key handle should be stored on the FIDO\n authenticator itself. This makes it easier to use the\n authenticator on multiple computers. Resident keys may be\n supported on FIDO2 authenticators and typically require that a PIN\n be set on the authenticator prior to generation. Resident keys\n may be loaded off the authenticator using ssh-add(1). Storing\n both parts of a key on a FIDO authenticator increases the\n likelihood of an attacker being able to use a stolen authenticator\n device.\n","language":"txt","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" Indicate that the key handle should be stored on the FIDO\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator itself. This makes it easier to use the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator on multiple computers. Resident keys may be\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" supported on FIDO2 authenticators and typically require that a PIN\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" be set on the authenticator prior to generation. Resident keys\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" may be loaded off the authenticator using ssh-add(1). Storing\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" both parts of a key on a FIDO authenticator increases the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" likelihood of an attacker being able to use a stolen authenticator\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" device.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's all it takes -- simple enough. Now, when interacting with "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" or "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"git"}]},{"type":"text","value":" you will be prompted to touch the YubiKey to bring that little bit of physical 2FA."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:ssh-ed25519-sk-yubikey.md","_source":"content","_file":"articles/ssh-ed25519-sk-yubikey.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/ssh-ed25519-sk-yubikey","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Configuring a YubiKey for use with OpenSSH","description":"YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","draft":false,"date":"2024-06-09","tags":["unix","configurations"],"categories":["tooling","tips"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://www.yubico.com/","rel":["nofollow"]},"children":[{"type":"text","value":"YubiKey's"}]},{"type":"text","value":" are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"ed25519-sk"}]},{"type":"text","value":" key type that supports FIDO compliant hardware keys."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In "},{"type":"element","tag":"a","props":{"href":"https://www.openssh.com/txt/release-8.2","rel":["nofollow"]},"children":[{"type":"text","value":"release 8.2 of OpenSSH"}]},{"type":"text","value":" support for FIDO devices was added with public key types \"ecdsa-sk\" and \"ed25519-sk\" (-sk standing for \"security key\"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types \"ecdsa-sk\" and \"ed25519-sk\", along with corresponding certificate types."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's get started by installing the latest version of OpenSSH via "},{"type":"element","tag":"a","props":{"href":"https://brew.sh/","rel":["nofollow"]},"children":[{"type":"text","value":"Homebrew"}]},{"type":"text","value":", along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ brew install openssh ykman\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" brew"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" openssh"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman list\nYubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" list\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"YubiKey"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 5Ci"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" (5.4.3) [OTP+FIDO+CCID]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we'll go ahead and enable a pin on our device via the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"change-pin"}]},{"type":"text","value":" command, as this a requirement for our use."}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ykman fido access change-pin\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ykman"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" fido"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" access"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" change-pin\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And last, we'll generate the key on our device!"}]},{"type":"element","tag":"pre","props":{"className":"language-sh shiki shiki-themes github-light","code":"$ ssh-keygen -t ed25519-sk -O resident\nGenerating public/private ed25519-sk key pair.\nYou may need to touch your authenticator to authorize key generation.\n...\n","language":"sh","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ssh-keygen"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -t"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"Generating"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" public/private"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" ed25519-sk"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" pair.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"You"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" may"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" need"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" touch"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" your"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authenticator"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" to"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" authorize"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" key"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" generation.\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"...\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We specify "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"resident"}]},{"type":"text","value":" to indicate that the key handle is to be stored on the YubiKey itself, since we will be using this device with multiple computers."}]},{"type":"element","tag":"pre","props":{"className":"language-txt shiki shiki-themes github-light","code":"resident\n Indicate that the key handle should be stored on the FIDO\n authenticator itself. This makes it easier to use the\n authenticator on multiple computers. Resident keys may be\n supported on FIDO2 authenticators and typically require that a PIN\n be set on the authenticator prior to generation. Resident keys\n may be loaded off the authenticator using ssh-add(1). Storing\n both parts of a key on a FIDO authenticator increases the\n likelihood of an attacker being able to use a stolen authenticator\n device.\n","language":"txt","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"resident\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" Indicate that the key handle should be stored on the FIDO\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator itself. This makes it easier to use the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" authenticator on multiple computers. Resident keys may be\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" supported on FIDO2 authenticators and typically require that a PIN\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" be set on the authenticator prior to generation. Resident keys\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" may be loaded off the authenticator using ssh-add(1). Storing\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" both parts of a key on a FIDO authenticator increases the\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" likelihood of an attacker being able to use a stolen authenticator\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":" device.\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's all it takes -- simple enough. Now, when interacting with "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"ssh"}]},{"type":"text","value":" or "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"git"}]},{"type":"text","value":" you will be prompted to touch the YubiKey to bring that little bit of physical 2FA."}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:ssh-ed25519-sk-yubikey.md","_source":"content","_file":"articles/ssh-ed25519-sk-yubikey.md","_stem":"articles/ssh-ed25519-sk-yubikey","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/PYi9meWOqm.1718891166808.json b/api/_content/query/tGrf8kFZOz.1720229301475.json similarity index 98% rename from api/_content/query/PYi9meWOqm.1718891166808.json rename to api/_content/query/tGrf8kFZOz.1720229301475.json index 73087874..0c365c45 100644 --- a/api/_content/query/PYi9meWOqm.1718891166808.json +++ b/api/_content/query/tGrf8kFZOz.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/apu2-firmware-upgrade","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Upgrading the Firmware on the PCEngines APU2","description":"I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","date":"2019-12-21","draft":false,"tags":["pcengine","apu"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, we will connect to the device over the serial port"}]},{"type":"element","tag":"pre","props":{"code":"screen /dev/tty.usbserial 115200\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"screen /dev/tty.usbserial 115200\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we will install the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"flashrom"}]},{"type":"text","value":" utility that is needed to update the\nfirmware. Because it is not available in the default "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"yum"}]},{"type":"text","value":" repositories, we\nwill enable the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Extra Packages for Enterprise Linux"}]},{"type":"text","value":" (EPEL) repository before\ninstallation."}]},{"type":"element","tag":"pre","props":{"code":"sudo yum install epel-release\nsudo yum install flashrom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" epel-release\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we will download the latest version of the firmware that is compatible\nwith the APU2 device from the PC Engines release website:\n"},{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"curl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, we will flash the firmware..."}]},{"type":"element","tag":"pre","props":{"code":"sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -w"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" apu2_v4.11.0.1.rom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -p"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" internal:boardmismatch=force\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References:"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.ch/apu2.htm"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/elad/openbsd-apu2","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/elad/openbsd-apu2"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:apu2-firmware-upgrade.md","_source":"content","_file":"articles/apu2-firmware-upgrade.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/apu2-firmware-upgrade","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Upgrading the Firmware on the PCEngines APU2","description":"I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","date":"2019-12-21","draft":false,"tags":["pcengine","apu"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I've had a "},{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"PCEngines APU2"}]},{"type":"text","value":" gathering dust for a\nfew years, and have recently decided to dust it off."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, we will connect to the device over the serial port"}]},{"type":"element","tag":"pre","props":{"code":"screen /dev/tty.usbserial 115200\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"screen /dev/tty.usbserial 115200\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, we will install the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"flashrom"}]},{"type":"text","value":" utility that is needed to update the\nfirmware. Because it is not available in the default "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"yum"}]},{"type":"text","value":" repositories, we\nwill enable the "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"Extra Packages for Enterprise Linux"}]},{"type":"text","value":" (EPEL) repository before\ninstallation."}]},{"type":"element","tag":"pre","props":{"code":"sudo yum install epel-release\nsudo yum install flashrom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" epel-release\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" yum"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" install"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next, we will download the latest version of the firmware that is compatible\nwith the APU2 device from the PC Engines release website:\n"},{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]},{"type":"text","value":"."}]},{"type":"element","tag":"pre","props":{"code":"curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"curl"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -O"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And finally, we will flash the firmware..."}]},{"type":"element","tag":"pre","props":{"code":"sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"sudo"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" flashrom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -w"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" apu2_v4.11.0.1.rom"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -p"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" internal:boardmismatch=force\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References:"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.ch/apu2.htm","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.ch/apu2.htm"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://pcengines.github.io/","rel":["nofollow"]},"children":[{"type":"text","value":"https://pcengines.github.io/"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://github.com/elad/openbsd-apu2","rel":["nofollow"]},"children":[{"type":"text","value":"https://github.com/elad/openbsd-apu2"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:apu2-firmware-upgrade.md","_source":"content","_file":"articles/apu2-firmware-upgrade.md","_stem":"articles/apu2-firmware-upgrade","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/wVY7dvWXwt.1718891166808.json b/api/_content/query/ucEXmLbw2Z.1720229301475.json similarity index 98% rename from api/_content/query/wVY7dvWXwt.1718891166808.json rename to api/_content/query/ucEXmLbw2Z.1720229301475.json index f8e98189..b76fd19c 100644 --- a/api/_content/query/wVY7dvWXwt.1718891166808.json +++ b/api/_content/query/ucEXmLbw2Z.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/docker-selinux-volumes","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Docker Volume Permissions with SELinux","description":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","date":"2019-12-26","draft":false,"tags":["docker","selinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]},{"type":"element","tag":"pre","props":{"code":"mkdir: can't create directory '/data': Permission denied\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"mkdir: can't create directory '/data': Permission denied\n"}]}]}]}]},{"type":"element","tag":"hr","props":{},"children":[]},{"type":"element","tag":"pre","props":{"code":"$ docker info --format '{{json .SecurityOptions}}'\n[\n \"name=seccomp,profile=/etc/docker/seccomp.json\",\n \"name=selinux\"\n]\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" docker"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" info"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '{{json .SecurityOptions}}'\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=seccomp,profile=/etc/docker/seccomp.json\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=selinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It turns out that this can be resolved by appending the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":":z"}]},{"type":"text","value":" flag to the volume\nmappings in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"docker-compose.yml"}]},{"type":"text","value":" file, indicating that the volume content\nis shared."}]},{"type":"element","tag":"pre","props":{"code":"services:\n server:\n volumes:\n - ./data:/data:z\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"services:\n server:\n volumes:\n - ./data:/data:z\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From the Docker documentation:"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"z"}]},{"type":"text","value":" option tells Docker that two containers share the volume content. As\na result, Docker labels the content with a shared content label. Shared\nvolume labels allow all containers to read/write content."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/info/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Docker Info"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Mounting Volumes"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:docker-selinux-volumes.md","_source":"content","_file":"articles/docker-selinux-volumes.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/docker-selinux-volumes","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"Docker Volume Permissions with SELinux","description":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","date":"2019-12-26","draft":false,"tags":["docker","selinux"],"categories":["linux"],"excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes."}]},{"type":"element","tag":"pre","props":{"code":"mkdir: can't create directory '/data': Permission denied\n","language":"txt","meta":"","className":"language-txt shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"mkdir: can't create directory '/data': Permission denied\n"}]}]}]}]},{"type":"element","tag":"hr","props":{},"children":[]},{"type":"element","tag":"pre","props":{"code":"$ docker info --format '{{json .SecurityOptions}}'\n[\n \"name=seccomp,profile=/etc/docker/seccomp.json\",\n \"name=selinux\"\n]\n","language":"bash","meta":"","className":"language-bash shiki shiki-themes github-light","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"$"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" docker"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" info"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" --format"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '{{json .SecurityOptions}}'\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"[\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=seccomp,profile=/etc/docker/seccomp.json\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"name=selinux\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It turns out that this can be resolved by appending the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":":z"}]},{"type":"text","value":" flag to the volume\nmappings in the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"docker-compose.yml"}]},{"type":"text","value":" file, indicating that the volume content\nis shared."}]},{"type":"element","tag":"pre","props":{"code":"services:\n server:\n volumes:\n - ./data:/data:z\n"},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"services:\n server:\n volumes:\n - ./data:/data:z\n"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From the Docker documentation:"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"z"}]},{"type":"text","value":" option tells Docker that two containers share the volume content. As\na result, Docker labels the content with a shared content label. Shared\nvolume labels allow all containers to read/write content."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"References"}]}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/info/","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Docker Info"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from","rel":["nofollow"]},"children":[{"type":"text","value":"Docker Docs: Mounting Volumes"}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:articles:docker-selinux-volumes.md","_source":"content","_file":"articles/docker-selinux-volumes.md","_stem":"articles/docker-selinux-volumes","_extension":"md"} \ No newline at end of file diff --git a/api/_content/query/x8mzqct7Ta.1718891166808.json b/api/_content/query/v3HQ7aAWkW.1720229301475.json similarity index 99% rename from api/_content/query/x8mzqct7Ta.1718891166808.json rename to api/_content/query/v3HQ7aAWkW.1720229301475.json index a4c5f2e5..ea26152b 100644 --- a/api/_content/query/x8mzqct7Ta.1718891166808.json +++ b/api/_content/query/v3HQ7aAWkW.1720229301475.json @@ -1 +1 @@ -{"_path":"/articles/nuxt-content-rss-feed","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"How To Add an RSS Feed to a Nuxt Website","description":"If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","draft":false,"date":"2024-01-06","tags":["nuxt","rss"],"categories":["programming"],"cover_image":"/images/nuxt-content-rss-feed.jpg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In version 2 of Nuxt, the community module, "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module","rel":["nofollow"]},"children":[{"type":"text","value":"nuxt-community/feed-module"}]},{"type":"text","value":" was a popular choice for adding an RSS feed to your website. However, there has been an unresolved "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module/issues/106","rel":["nofollow"]},"children":[{"type":"text","value":"open issue"}]},{"type":"text","value":" since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward."}]},{"type":"element","tag":"h2","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, install the "},{"type":"element","tag":"a","props":{"href":"https://www.npmjs.com/package/feed","rel":["nofollow"]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library into your project:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D feed\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" feed\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/"}]},{"type":"text","value":" folder in your project if it does not already exist, and create a file named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/atom.ts"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Here, we will leverage the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library and construct an XML representation of our Nuxt content. As you can see, we first define our "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"serverQueryContent"}]},{"type":"text","value":" and append a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed.addItem"}]},{"type":"text","value":" for each article."}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { Feed } from 'feed';\n\nconst BASE_URL = \"https://mywebsite.com\"\nconst AUTHOR_NAME = \"Firstname Lastname\"\n\nexport default defineEventHandler(async (event) => {\n\n const feed = new Feed({\n title: \"My Title\",\n description: \"My Description\",\n id: BASE_URL,\n link: BASE_URL,\n language: \"en\",\n image: `${BASE_URL}/images/placeholder.png`,\n favicon: `${BASE_URL}/favicon.ico`,\n copyright: `All rights reserved ${new Date().getFullYear()}, ${AUTHOR_NAME}`,\n updated: new Date(),\n generator: \"Nuxt static site generation + Feed for Node.js\",\n feedLinks: {\n atom: `${BASE_URL}/atom`\n },\n author: {\n name: AUTHOR_NAME,\n }\n });\n\n const articles = await serverQueryContent(event).find();\n\n articles.forEach((article) => {\n feed.addItem({\n title: article.title ? article.title : \"Missing Title\",\n id: article._path,\n link: `${BASE_URL}${article._path}`,\n description: article.description,\n author: [\n {\n name: AUTHOR_NAME,\n },\n ],\n date: new Date(article.date),\n image: article.cover_image ? `${BASE_URL}/${article.cover_image}` : undefined\n });\n });\n\n return feed.atom1();\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { Feed } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'feed'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://mywebsite.com\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Firstname Lastname\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Description\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" language: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"en\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/images/placeholder.png`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" favicon: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/favicon.ico`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" copyright: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`All rights reserved ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"getFullYear"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}, ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" updated: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":19},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" generator: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Nuxt static site generation + Feed for Node.js\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":20},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feedLinks: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":21},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" atom: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/atom`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":22},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":23},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":24},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":25},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":26},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":27},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":28},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":29},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":30},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":31},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"addItem"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":32},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Missing Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":33},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: article._path,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":34},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"_path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":35},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: article.description,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":36},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: [\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":37},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":38},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":39},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":40},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ],\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":41},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" date: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(article.date),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":42},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: article.cover_image "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" `${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"cover_image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" :"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" undefined\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":43},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":44},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":45},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":46},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"atom1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":47},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's just about it! Except, if you are statically generating your website with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt generate"}]},{"type":"text","value":" command, you will need to configure this server-side route to be pre-rendered on site generation. This is as simple as adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nitro"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" definition in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":" file, like so:"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"bonus"},"children":[{"type":"text","value":"Bonus"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may also be interested in adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sitemap.xml"}]},{"type":"text","value":" to your website. This can be done in almost an identical fashion!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Install the dependency:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D sitemap\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sitemap\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a route at "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/sitemap.xml.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { SitemapStream, streamToPromise } from 'sitemap';\n\nexport default defineEventHandler(async (event) => {\n const articles = await serverQueryContent(event).find();\n\n const sitemap = new SitemapStream({ hostname: 'https://my-website.com/' });\n\n // Add non nuxt content endpoints here\n sitemap.write({ url: '/' });\n sitemap.write({ url: '/articles' });\n\n // Dynamically generate routes for Nuxt markdown content\n articles.forEach((article) => sitemap.write({ url: article._path, changefreq: 'monthly' }));\n sitemap.end();\n\n return (await streamToPromise(sitemap));\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { SitemapStream, streamToPromise } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'sitemap'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" sitemap"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" SitemapStream"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ hostname: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'https://my-website.com/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Add non nuxt content endpoints here\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/articles'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Dynamically generate routes for Nuxt markdown content\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: article._path, changefreq: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'monthly'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" streamToPromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(sitemap));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And add the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" entry in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/sitemap.xml', '/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/sitemap.xml'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"instructions","depth":2,"text":"Instructions"},{"id":"bonus","depth":2,"text":"Bonus"}]}},"_type":"markdown","_id":"content:articles:nuxt-content-rss-feed.md","_source":"content","_file":"articles/nuxt-content-rss-feed.md","_extension":"md"} \ No newline at end of file +{"_path":"/articles/nuxt-content-rss-feed","_dir":"articles","_draft":false,"_partial":false,"_locale":"","title":"How To Add an RSS Feed to a Nuxt Website","description":"If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","draft":false,"date":"2024-01-06","tags":["nuxt","rss"],"categories":["programming"],"cover_image":"/images/nuxt-content-rss-feed.jpg","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]}]},"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If you are a user of "},{"type":"element","tag":"a","props":{"href":"https://content.nuxt.com/","rel":["nofollow"]},"children":[{"type":"text","value":"Nuxt Content"}]},{"type":"text","value":" and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application."}]},{"type":"element","tag":"h2","props":{"id":"preface"},"children":[{"type":"text","value":"Preface"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In version 2 of Nuxt, the community module, "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module","rel":["nofollow"]},"children":[{"type":"text","value":"nuxt-community/feed-module"}]},{"type":"text","value":" was a popular choice for adding an RSS feed to your website. However, there has been an unresolved "},{"type":"element","tag":"a","props":{"href":"https://github.com/nuxt-community/feed-module/issues/106","rel":["nofollow"]},"children":[{"type":"text","value":"open issue"}]},{"type":"text","value":" since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward."}]},{"type":"element","tag":"h2","props":{"id":"instructions"},"children":[{"type":"text","value":"Instructions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"First, install the "},{"type":"element","tag":"a","props":{"href":"https://www.npmjs.com/package/feed","rel":["nofollow"]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library into your project:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D feed\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" feed\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then, create a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/"}]},{"type":"text","value":" folder in your project if it does not already exist, and create a file named "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/atom.ts"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Here, we will leverage the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" library and construct an XML representation of our Nuxt content. As you can see, we first define our "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed"}]},{"type":"text","value":" with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"serverQueryContent"}]},{"type":"text","value":" and append a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"feed.addItem"}]},{"type":"text","value":" for each article."}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { Feed } from 'feed';\n\nconst BASE_URL = \"https://mywebsite.com\"\nconst AUTHOR_NAME = \"Firstname Lastname\"\n\nexport default defineEventHandler(async (event) => {\n\n const feed = new Feed({\n title: \"My Title\",\n description: \"My Description\",\n id: BASE_URL,\n link: BASE_URL,\n language: \"en\",\n image: `${BASE_URL}/images/placeholder.png`,\n favicon: `${BASE_URL}/favicon.ico`,\n copyright: `All rights reserved ${new Date().getFullYear()}, ${AUTHOR_NAME}`,\n updated: new Date(),\n generator: \"Nuxt static site generation + Feed for Node.js\",\n feedLinks: {\n atom: `${BASE_URL}/atom`\n },\n author: {\n name: AUTHOR_NAME,\n }\n });\n\n const articles = await serverQueryContent(event).find();\n\n articles.forEach((article) => {\n feed.addItem({\n title: article.title ? article.title : \"Missing Title\",\n id: article._path,\n link: `${BASE_URL}${article._path}`,\n description: article.description,\n author: [\n {\n name: AUTHOR_NAME,\n },\n ],\n date: new Date(article.date),\n image: article.cover_image ? `${BASE_URL}/${article.cover_image}` : undefined\n });\n });\n\n return feed.atom1();\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { Feed } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'feed'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"https://mywebsite.com\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Firstname Lastname\"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Feed"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"My Description\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" language: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"en\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/images/placeholder.png`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" favicon: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/favicon.ico`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" copyright: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`All rights reserved ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"getFullYear"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}, ${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" updated: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":19},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" generator: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"\"Nuxt static site generation + Feed for Node.js\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":20},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feedLinks: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":21},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" atom: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/atom`\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":22},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":23},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":24},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":25},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":26},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":27},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":28},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":29},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":30},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":31},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"addItem"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":32},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" title: article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" article.title "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" \"Missing Title\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":33},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" id: article._path,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":34},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" link: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"`${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"_path"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":35},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" description: article.description,\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":36},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" author: [\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":37},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":38},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" name: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"AUTHOR_NAME"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":",\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":39},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" },\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":40},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ],\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":41},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" date: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" Date"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(article.date),\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":42},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" image: article.cover_image "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"?"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" `${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":"BASE_URL"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}/${"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"cover_image"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" :"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" undefined\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":43},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":44},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":45},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":46},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" feed."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"atom1"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":47},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And that's just about it! Except, if you are statically generating your website with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt generate"}]},{"type":"text","value":" command, you will need to configure this server-side route to be pre-rendered on site generation. This is as simple as adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nitro"}]},{"type":"text","value":" "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" definition in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":" file, like so:"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"bonus"},"children":[{"type":"text","value":"Bonus"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may also be interested in adding a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"sitemap.xml"}]},{"type":"text","value":" to your website. This can be done in almost an identical fashion!"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Install the dependency:"}]},{"type":"element","tag":"pre","props":{"className":"language-shell shiki shiki-themes github-light","code":"npm i -D sitemap\n","language":"shell","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"npm"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" i"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" -D"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" sitemap\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Create a route at "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"server/routes/sitemap.xml.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"import { serverQueryContent } from '#content/server';\nimport { SitemapStream, streamToPromise } from 'sitemap';\n\nexport default defineEventHandler(async (event) => {\n const articles = await serverQueryContent(event).find();\n\n const sitemap = new SitemapStream({ hostname: 'https://my-website.com/' });\n\n // Add non nuxt content endpoints here\n sitemap.write({ url: '/' });\n sitemap.write({ url: '/articles' });\n\n // Dynamically generate routes for Nuxt markdown content\n articles.forEach((article) => sitemap.write({ url: article._path, changefreq: 'monthly' }));\n sitemap.end();\n\n return (await streamToPromise(sitemap));\n});\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { serverQueryContent } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" '#content/server'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" { SitemapStream, streamToPromise } "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":" 'sitemap'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" default"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" defineEventHandler"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"event"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" articles"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" serverQueryContent"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(event)."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"find"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#005CC5"},"children":[{"type":"text","value":" sitemap"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" new"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" SitemapStream"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ hostname: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'https://my-website.com/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":8},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":9},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Add non nuxt content endpoints here\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":10},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":11},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/articles'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":12},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":13},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6A737D"},"children":[{"type":"text","value":" // Dynamically generate routes for Nuxt markdown content\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":14},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" articles."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#E36209"},"children":[{"type":"text","value":"article"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"write"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"({ url: article._path, changefreq: "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'monthly'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":15},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" sitemap."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"end"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":16},"children":[{"type":"element","tag":"span","props":{"emptyLinePlaceholder":true},"children":[{"type":"text","value":"\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":17},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#D73A49"},"children":[{"type":"text","value":"await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" streamToPromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"(sitemap));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":18},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"});\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And add the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"prerender"}]},{"type":"text","value":" entry in your "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":":"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes github-light","code":"nitro: {\n prerender: {\n routes: ['/sitemap.xml', '/atom']\n }\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":"nitro"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" prerender"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#6F42C1"},"children":[{"type":"text","value":" routes"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":": ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/sitemap.xml'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#032F62"},"children":[{"type":"text","value":"'/atom'"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"]\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":" }\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#24292E"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"preface","depth":2,"text":"Preface"},{"id":"instructions","depth":2,"text":"Instructions"},{"id":"bonus","depth":2,"text":"Bonus"}]}},"_type":"markdown","_id":"content:articles:nuxt-content-rss-feed.md","_source":"content","_file":"articles/nuxt-content-rss-feed.md","_stem":"articles/nuxt-content-rss-feed","_extension":"md"} \ No newline at end of file diff --git a/articles/_payload.json b/articles/_payload.json index ba94d79d..31c82a27 100644 --- a/articles/_payload.json +++ b/articles/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180652] \ No newline at end of file +[{"data":1,"prerenderedAt":360},["Reactive",2],{"articles":3},[4,45,87,131,157,174,207,222,239,253,277,297,313,329],{"_path":5,"title":6,"description":7,"date":8,"tags":9,"categories":12,"excerpt":15,"_id":44},"/articles/ssh-ed25519-sk-yubikey","Configuring a YubiKey for use with OpenSSH","YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","2024-06-09",[10,11],"unix","configurations",[13,14],"tooling","tips",{"type":16,"children":17},"root",[18],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23,33,35,42],{"type":19,"tag":24,"props":25,"children":29},"a",{"href":26,"rel":27},"https://www.yubico.com/",[28],"nofollow",[30],{"type":31,"value":32},"text","YubiKey's",{"type":31,"value":34}," are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ",{"type":19,"tag":36,"props":37,"children":39},"code",{"className":38},[],[40],{"type":31,"value":41},"ed25519-sk",{"type":31,"value":43}," key type that supports FIDO compliant hardware keys.","content:articles:ssh-ed25519-sk-yubikey.md",{"_path":46,"title":47,"description":48,"date":49,"tags":50,"categories":53,"excerpt":54,"_id":86},"/articles/vim-fugitive-gpg-pinentry","Using pinentry-mac to sign commits from vim-fugitive","In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","2024-05-11",[51,52],"vim","tip",[13,14],{"type":16,"children":55},[56],{"type":19,"tag":20,"props":57,"children":58},{},[59,61,68,70,76,78,84],{"type":31,"value":60},"In order to sign git commits from within Vim using a plugin like ",{"type":19,"tag":24,"props":62,"children":65},{"href":63,"rel":64},"https://github.com/tpope/vim-fugitive",[28],[66],{"type":31,"value":67},"tpope/vim-fugitive",{"type":31,"value":69},", it is necessary to configure the ",{"type":19,"tag":36,"props":71,"children":73},{"className":72},[],[74],{"type":31,"value":75},"gpg-agent",{"type":31,"value":77}," to use a GUI based ",{"type":19,"tag":36,"props":79,"children":81},{"className":80},[],[82],{"type":31,"value":83},"pinentry-program",{"type":31,"value":85},".","content:articles:vim-fugitive-gpg-pinentry.md",{"_path":88,"title":89,"description":90,"date":91,"tags":92,"categories":95,"excerpt":97,"_id":130},"/articles/podcast-transcription-whispercpp","Easily Transcribe Podcasts with Whisper.cpp","If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","2024-01-08",[93,94],"whisper.cpp","ml",[96],"programming",{"type":16,"children":98},[99],{"type":19,"tag":20,"props":100,"children":101},{},[102,104,110,112,119,121,128],{"type":31,"value":103},"If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive ",{"type":19,"tag":24,"props":105,"children":108},{"href":106,"rel":107},"https://github.com/ggerganov/whisper.cpp",[28],[109],{"type":31,"value":93},{"type":31,"value":111}," project. This high-performance fork of ",{"type":19,"tag":24,"props":113,"children":116},{"href":114,"rel":115},"https://github.com/openai/whisper",[28],[117],{"type":31,"value":118},"OpenAI's Whisper",{"type":31,"value":120}," can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the ",{"type":19,"tag":24,"props":122,"children":125},{"href":123,"rel":124},"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854",[28],[126],{"type":31,"value":127},"Alter Everything",{"type":31,"value":129}," podcast.","content:articles:podcast-transcription-whispercpp.md",{"_path":132,"title":133,"description":134,"date":135,"tags":136,"categories":139,"excerpt":140,"_id":156},"/articles/nuxt-content-rss-feed","How To Add an RSS Feed to a Nuxt Website","If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","2024-01-06",[137,138],"nuxt","rss",[96],{"type":16,"children":141},[142],{"type":19,"tag":20,"props":143,"children":144},{},[145,147,154],{"type":31,"value":146},"If you are a user of ",{"type":19,"tag":24,"props":148,"children":151},{"href":149,"rel":150},"https://content.nuxt.com/",[28],[152],{"type":31,"value":153},"Nuxt Content",{"type":31,"value":155}," and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","content:articles:nuxt-content-rss-feed.md",{"_path":158,"title":159,"description":160,"date":161,"tags":162,"categories":166,"excerpt":167,"_id":173},"/articles/fennel-initial-exploration","Impressions of Fennel with Hammerspoon","A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","2023-10-22",[163,164,165],"lisp","hammerspoon","fennel",[163],{"type":16,"children":168},[169],{"type":19,"tag":20,"props":170,"children":171},{},[172],{"type":31,"value":160},"content:articles:fennel-initial-exploration.md",{"_path":175,"title":176,"description":177,"date":178,"tags":179,"categories":182,"excerpt":183,"_id":206},"/articles/doctl","Exploring the Digital Ocean `doctl` Utility","I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","2023-01-01",[180,181],"linux","digital-ocean",[180],{"type":16,"children":184},[185],{"type":19,"tag":20,"props":186,"children":187},{},[188,190,196,198,204],{"type":31,"value":189},"I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean ",{"type":19,"tag":36,"props":191,"children":193},{"className":192},[],[194],{"type":31,"value":195},"doctl",{"type":31,"value":197}," command line utility.\nThis proved to be an ",{"type":19,"tag":199,"props":200,"children":201},"em",{},[202],{"type":31,"value":203},"extremely",{"type":31,"value":205}," easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","content:articles:doctl.md",{"_path":208,"title":209,"description":210,"date":211,"tags":212,"categories":213,"excerpt":215,"_id":221},"/articles/nuxt-v3-migration","This Website Has Been Migrated to Nuxt 3 🎉","This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","2022-12-31",[137],[214],"web",{"type":16,"children":216},[217],{"type":19,"tag":20,"props":218,"children":219},{},[220],{"type":31,"value":210},"content:articles:nuxt-v3-migration.md",{"_path":223,"title":224,"description":225,"date":226,"tags":227,"categories":231,"excerpt":232,"_id":238},"/articles/migrate-truenas-from-core-to-scale","Migrate to TrueNAS Scale from TrueNAS Core","TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","2021-12-28",[228,229,230],"homelab","supermicro","truenas",[228],{"type":16,"children":233},[234],{"type":19,"tag":20,"props":235,"children":236},{},[237],{"type":31,"value":225},"content:articles:migrate-truenas-from-core-to-scale.md",{"_path":240,"title":241,"description":242,"date":243,"tags":244,"categories":245,"excerpt":246,"_id":252},"/articles/reset-ipmi-password-from-host-os","Reset IPMI Credentials from the Host OS","If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","2021-12-27",[228,229,230],[228],{"type":16,"children":247},[248],{"type":19,"tag":20,"props":249,"children":250},{},[251],{"type":31,"value":242},"content:articles:reset-ipmi-password-from-host-os.md",{"_path":254,"title":255,"description":256,"date":257,"tags":258,"categories":260,"excerpt":261,"_id":276},"/articles/quick-tip-rerunning-bash-commands","Tip: Re-running Bash Commands","Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","2021-09-22",[52,259],"bash",[14],{"type":16,"children":262},[263],{"type":19,"tag":20,"props":264,"children":265},{},[266,268,274],{"type":31,"value":267},"Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use ",{"type":19,"tag":36,"props":269,"children":271},{"className":270},[],[272],{"type":31,"value":273},"sudo",{"type":31,"value":275}," for a command that requires\nroot privileges.","content:articles:quick-tip-rerunning-bash-commands.md",{"_path":278,"title":279,"description":280,"date":281,"tags":282,"categories":287,"excerpt":290,"_id":296},"/articles/unit-testing-micropython-with-mocks","Unit Testing in MicroPython with Mocks","Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","2020-02-07",[283,284,285,286],"micropython","testing","mocks","tutorial",[288,289],"python","embedded",{"type":16,"children":291},[292],{"type":19,"tag":20,"props":293,"children":294},{},[295],{"type":31,"value":280},"content:articles:unit-testing-micropython-with-mocks.md",{"_path":298,"title":299,"description":300,"date":301,"tags":302,"categories":305,"excerpt":306,"_id":312},"/articles/persistent-archlinux-usb","Create a Persistent Arch Linux Bootable USB with Vagrant","When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","2020-01-09",[303,304],"vagrant","archlinux",[180],{"type":16,"children":307},[308],{"type":19,"tag":20,"props":309,"children":310},{},[311],{"type":31,"value":300},"content:articles:persistent-archlinux-usb.md",{"_path":314,"title":315,"description":316,"date":317,"tags":318,"categories":321,"excerpt":322,"_id":328},"/articles/docker-selinux-volumes","Docker Volume Permissions with SELinux","Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","2019-12-26",[319,320],"docker","selinux",[180],{"type":16,"children":323},[324],{"type":19,"tag":20,"props":325,"children":326},{},[327],{"type":31,"value":316},"content:articles:docker-selinux-volumes.md",{"_path":330,"title":331,"description":332,"date":333,"tags":334,"categories":337,"excerpt":338,"_id":359},"/articles/apu2-firmware-upgrade","Upgrading the Firmware on the PCEngines APU2","I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","2019-12-21",[335,336],"pcengine","apu",[180],{"type":16,"children":339},[340,354],{"type":19,"tag":20,"props":341,"children":342},{},[343,345,352],{"type":31,"value":344},"I've had a ",{"type":19,"tag":24,"props":346,"children":349},{"href":347,"rel":348},"https://pcengines.ch/apu2.htm",[28],[350],{"type":31,"value":351},"PCEngines APU2",{"type":31,"value":353}," gathering dust for a\nfew years, and have recently decided to dust it off.",{"type":19,"tag":20,"props":355,"children":356},{},[357],{"type":31,"value":358},"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS.","content:articles:apu2-firmware-upgrade.md",1720229314468] \ No newline at end of file diff --git a/articles/apu2-firmware-upgrade/_payload.json b/articles/apu2-firmware-upgrade/_payload.json index 5cb3890b..ba24d05d 100644 --- a/articles/apu2-firmware-upgrade/_payload.json +++ b/articles/apu2-firmware-upgrade/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":314},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":43,"_type":309,"_id":310,"_source":311,"_file":312,"_extension":313},"/articles/apu2-firmware-upgrade","articles",false,"","Upgrading the Firmware on the PCEngines APU2","I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","2019-12-21",[12,13],"pcengine","apu",[15],"linux",{"type":17,"children":18},"root",[19,38],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,36],{"type":25,"value":26},"text","I've had a ",{"type":20,"tag":28,"props":29,"children":33},"a",{"href":30,"rel":31},"https://pcengines.ch/apu2.htm",[32],"nofollow",[34],{"type":25,"value":35},"PCEngines APU2",{"type":25,"value":37}," gathering dust for a\nfew years, and have recently decided to dust it off.",{"type":20,"tag":21,"props":39,"children":40},{},[41],{"type":25,"value":42},"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS.",{"type":17,"children":44,"toc":307},[45,55,59,64,74,103,161,174,200,205,244,253,301],{"type":20,"tag":21,"props":46,"children":47},{},[48,49,54],{"type":25,"value":26},{"type":20,"tag":28,"props":50,"children":52},{"href":30,"rel":51},[32],[53],{"type":25,"value":35},{"type":25,"value":37},{"type":20,"tag":21,"props":56,"children":57},{},[58],{"type":25,"value":42},{"type":20,"tag":21,"props":60,"children":61},{},[62],{"type":25,"value":63},"First, we will connect to the device over the serial port",{"type":20,"tag":65,"props":66,"children":68},"pre",{"code":67},"screen /dev/tty.usbserial 115200\n",[69],{"type":20,"tag":70,"props":71,"children":72},"code",{"__ignoreMap":7},[73],{"type":25,"value":67},{"type":20,"tag":21,"props":75,"children":76},{},[77,79,85,87,93,95,101],{"type":25,"value":78},"Then, we will install the ",{"type":20,"tag":70,"props":80,"children":82},{"className":81},[],[83],{"type":25,"value":84},"flashrom",{"type":25,"value":86}," utility that is needed to update the\nfirmware. Because it is not available in the default ",{"type":20,"tag":70,"props":88,"children":90},{"className":89},[],[91],{"type":25,"value":92},"yum",{"type":25,"value":94}," repositories, we\nwill enable the ",{"type":20,"tag":96,"props":97,"children":98},"em",{},[99],{"type":25,"value":100},"Extra Packages for Enterprise Linux",{"type":25,"value":102}," (EPEL) repository before\ninstallation.",{"type":20,"tag":65,"props":104,"children":108},{"code":105,"language":106,"meta":7,"className":107,"style":7},"sudo yum install epel-release\nsudo yum install flashrom\n","bash","language-bash shiki shiki-themes github-light",[109],{"type":20,"tag":70,"props":110,"children":111},{"__ignoreMap":7},[112,140],{"type":20,"tag":113,"props":114,"children":117},"span",{"class":115,"line":116},"line",1,[118,124,130,135],{"type":20,"tag":113,"props":119,"children":121},{"style":120},"--shiki-default:#6F42C1",[122],{"type":25,"value":123},"sudo",{"type":20,"tag":113,"props":125,"children":127},{"style":126},"--shiki-default:#032F62",[128],{"type":25,"value":129}," yum",{"type":20,"tag":113,"props":131,"children":132},{"style":126},[133],{"type":25,"value":134}," install",{"type":20,"tag":113,"props":136,"children":137},{"style":126},[138],{"type":25,"value":139}," epel-release\n",{"type":20,"tag":113,"props":141,"children":143},{"class":115,"line":142},2,[144,148,152,156],{"type":20,"tag":113,"props":145,"children":146},{"style":120},[147],{"type":25,"value":123},{"type":20,"tag":113,"props":149,"children":150},{"style":126},[151],{"type":25,"value":129},{"type":20,"tag":113,"props":153,"children":154},{"style":126},[155],{"type":25,"value":134},{"type":20,"tag":113,"props":157,"children":158},{"style":126},[159],{"type":25,"value":160}," flashrom\n",{"type":20,"tag":21,"props":162,"children":163},{},[164,166,172],{"type":25,"value":165},"Next, we will download the latest version of the firmware that is compatible\nwith the APU2 device from the PC Engines release website:\n",{"type":20,"tag":28,"props":167,"children":170},{"href":168,"rel":169},"https://pcengines.github.io/",[32],[171],{"type":25,"value":168},{"type":25,"value":173},".",{"type":20,"tag":65,"props":175,"children":177},{"code":176,"language":106,"meta":7,"className":107,"style":7},"curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n",[178],{"type":20,"tag":70,"props":179,"children":180},{"__ignoreMap":7},[181],{"type":20,"tag":113,"props":182,"children":183},{"class":115,"line":116},[184,189,195],{"type":20,"tag":113,"props":185,"children":186},{"style":120},[187],{"type":25,"value":188},"curl",{"type":20,"tag":113,"props":190,"children":192},{"style":191},"--shiki-default:#005CC5",[193],{"type":25,"value":194}," -O",{"type":20,"tag":113,"props":196,"children":197},{"style":126},[198],{"type":25,"value":199}," https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n",{"type":20,"tag":21,"props":201,"children":202},{},[203],{"type":25,"value":204},"And finally, we will flash the firmware...",{"type":20,"tag":65,"props":206,"children":208},{"code":207,"language":106,"meta":7,"className":107,"style":7},"sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force\n",[209],{"type":20,"tag":70,"props":210,"children":211},{"__ignoreMap":7},[212],{"type":20,"tag":113,"props":213,"children":214},{"class":115,"line":116},[215,219,224,229,234,239],{"type":20,"tag":113,"props":216,"children":217},{"style":120},[218],{"type":25,"value":123},{"type":20,"tag":113,"props":220,"children":221},{"style":126},[222],{"type":25,"value":223}," flashrom",{"type":20,"tag":113,"props":225,"children":226},{"style":191},[227],{"type":25,"value":228}," -w",{"type":20,"tag":113,"props":230,"children":231},{"style":126},[232],{"type":25,"value":233}," apu2_v4.11.0.1.rom",{"type":20,"tag":113,"props":235,"children":236},{"style":191},[237],{"type":25,"value":238}," -p",{"type":20,"tag":113,"props":240,"children":241},{"style":126},[242],{"type":25,"value":243}," internal:boardmismatch=force\n",{"type":20,"tag":21,"props":245,"children":246},{},[247],{"type":20,"tag":248,"props":249,"children":250},"strong",{},[251],{"type":25,"value":252},"References:",{"type":20,"tag":254,"props":255,"children":256},"ul",{},[257,266,274,283,292],{"type":20,"tag":258,"props":259,"children":260},"li",{},[261],{"type":20,"tag":28,"props":262,"children":264},{"href":30,"rel":263},[32],[265],{"type":25,"value":30},{"type":20,"tag":258,"props":267,"children":268},{},[269],{"type":20,"tag":28,"props":270,"children":272},{"href":168,"rel":271},[32],[273],{"type":25,"value":168},{"type":20,"tag":258,"props":275,"children":276},{},[277],{"type":20,"tag":28,"props":278,"children":281},{"href":279,"rel":280},"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md",[32],[282],{"type":25,"value":279},{"type":20,"tag":258,"props":284,"children":285},{},[286],{"type":20,"tag":28,"props":287,"children":290},{"href":288,"rel":289},"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md",[32],[291],{"type":25,"value":288},{"type":20,"tag":258,"props":293,"children":294},{},[295],{"type":20,"tag":28,"props":296,"children":299},{"href":297,"rel":298},"https://github.com/elad/openbsd-apu2",[32],[300],{"type":25,"value":297},{"type":20,"tag":302,"props":303,"children":304},"style",{},[305],{"type":25,"value":306},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":142,"depth":142,"links":308},[],"markdown","content:articles:apu2-firmware-upgrade.md","content","articles/apu2-firmware-upgrade.md","md",1718891181803] \ No newline at end of file +[{"data":1,"prerenderedAt":315},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":43,"_type":309,"_id":310,"_source":311,"_file":312,"_stem":313,"_extension":314},"/articles/apu2-firmware-upgrade","articles",false,"","Upgrading the Firmware on the PCEngines APU2","I've had a PCEngines APU2 gathering dust for a\nfew years, and have recently decided to dust it off.","2019-12-21",[12,13],"pcengine","apu",[15],"linux",{"type":17,"children":18},"root",[19,38],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,36],{"type":25,"value":26},"text","I've had a ",{"type":20,"tag":28,"props":29,"children":33},"a",{"href":30,"rel":31},"https://pcengines.ch/apu2.htm",[32],"nofollow",[34],{"type":25,"value":35},"PCEngines APU2",{"type":25,"value":37}," gathering dust for a\nfew years, and have recently decided to dust it off.",{"type":20,"tag":21,"props":39,"children":40},{},[41],{"type":25,"value":42},"Since the last time the device has been powered on, there have been many great\nimprovements to the firmware, and it was very-much due for an upgrade. The\nfollowing steps outline how the firmware was upgraded on the APU from the\nalready-installed operating system -- CentOS.",{"type":17,"children":44,"toc":307},[45,55,59,64,74,103,161,174,200,205,244,253,301],{"type":20,"tag":21,"props":46,"children":47},{},[48,49,54],{"type":25,"value":26},{"type":20,"tag":28,"props":50,"children":52},{"href":30,"rel":51},[32],[53],{"type":25,"value":35},{"type":25,"value":37},{"type":20,"tag":21,"props":56,"children":57},{},[58],{"type":25,"value":42},{"type":20,"tag":21,"props":60,"children":61},{},[62],{"type":25,"value":63},"First, we will connect to the device over the serial port",{"type":20,"tag":65,"props":66,"children":68},"pre",{"code":67},"screen /dev/tty.usbserial 115200\n",[69],{"type":20,"tag":70,"props":71,"children":72},"code",{"__ignoreMap":7},[73],{"type":25,"value":67},{"type":20,"tag":21,"props":75,"children":76},{},[77,79,85,87,93,95,101],{"type":25,"value":78},"Then, we will install the ",{"type":20,"tag":70,"props":80,"children":82},{"className":81},[],[83],{"type":25,"value":84},"flashrom",{"type":25,"value":86}," utility that is needed to update the\nfirmware. Because it is not available in the default ",{"type":20,"tag":70,"props":88,"children":90},{"className":89},[],[91],{"type":25,"value":92},"yum",{"type":25,"value":94}," repositories, we\nwill enable the ",{"type":20,"tag":96,"props":97,"children":98},"em",{},[99],{"type":25,"value":100},"Extra Packages for Enterprise Linux",{"type":25,"value":102}," (EPEL) repository before\ninstallation.",{"type":20,"tag":65,"props":104,"children":108},{"code":105,"language":106,"meta":7,"className":107,"style":7},"sudo yum install epel-release\nsudo yum install flashrom\n","bash","language-bash shiki shiki-themes github-light",[109],{"type":20,"tag":70,"props":110,"children":111},{"__ignoreMap":7},[112,140],{"type":20,"tag":113,"props":114,"children":117},"span",{"class":115,"line":116},"line",1,[118,124,130,135],{"type":20,"tag":113,"props":119,"children":121},{"style":120},"--shiki-default:#6F42C1",[122],{"type":25,"value":123},"sudo",{"type":20,"tag":113,"props":125,"children":127},{"style":126},"--shiki-default:#032F62",[128],{"type":25,"value":129}," yum",{"type":20,"tag":113,"props":131,"children":132},{"style":126},[133],{"type":25,"value":134}," install",{"type":20,"tag":113,"props":136,"children":137},{"style":126},[138],{"type":25,"value":139}," epel-release\n",{"type":20,"tag":113,"props":141,"children":143},{"class":115,"line":142},2,[144,148,152,156],{"type":20,"tag":113,"props":145,"children":146},{"style":120},[147],{"type":25,"value":123},{"type":20,"tag":113,"props":149,"children":150},{"style":126},[151],{"type":25,"value":129},{"type":20,"tag":113,"props":153,"children":154},{"style":126},[155],{"type":25,"value":134},{"type":20,"tag":113,"props":157,"children":158},{"style":126},[159],{"type":25,"value":160}," flashrom\n",{"type":20,"tag":21,"props":162,"children":163},{},[164,166,172],{"type":25,"value":165},"Next, we will download the latest version of the firmware that is compatible\nwith the APU2 device from the PC Engines release website:\n",{"type":20,"tag":28,"props":167,"children":170},{"href":168,"rel":169},"https://pcengines.github.io/",[32],[171],{"type":25,"value":168},{"type":25,"value":173},".",{"type":20,"tag":65,"props":175,"children":177},{"code":176,"language":106,"meta":7,"className":107,"style":7},"curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n",[178],{"type":20,"tag":70,"props":179,"children":180},{"__ignoreMap":7},[181],{"type":20,"tag":113,"props":182,"children":183},{"class":115,"line":116},[184,189,195],{"type":20,"tag":113,"props":185,"children":186},{"style":120},[187],{"type":25,"value":188},"curl",{"type":20,"tag":113,"props":190,"children":192},{"style":191},"--shiki-default:#005CC5",[193],{"type":25,"value":194}," -O",{"type":20,"tag":113,"props":196,"children":197},{"style":126},[198],{"type":25,"value":199}," https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom\n",{"type":20,"tag":21,"props":201,"children":202},{},[203],{"type":25,"value":204},"And finally, we will flash the firmware...",{"type":20,"tag":65,"props":206,"children":208},{"code":207,"language":106,"meta":7,"className":107,"style":7},"sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force\n",[209],{"type":20,"tag":70,"props":210,"children":211},{"__ignoreMap":7},[212],{"type":20,"tag":113,"props":213,"children":214},{"class":115,"line":116},[215,219,224,229,234,239],{"type":20,"tag":113,"props":216,"children":217},{"style":120},[218],{"type":25,"value":123},{"type":20,"tag":113,"props":220,"children":221},{"style":126},[222],{"type":25,"value":223}," flashrom",{"type":20,"tag":113,"props":225,"children":226},{"style":191},[227],{"type":25,"value":228}," -w",{"type":20,"tag":113,"props":230,"children":231},{"style":126},[232],{"type":25,"value":233}," apu2_v4.11.0.1.rom",{"type":20,"tag":113,"props":235,"children":236},{"style":191},[237],{"type":25,"value":238}," -p",{"type":20,"tag":113,"props":240,"children":241},{"style":126},[242],{"type":25,"value":243}," internal:boardmismatch=force\n",{"type":20,"tag":21,"props":245,"children":246},{},[247],{"type":20,"tag":248,"props":249,"children":250},"strong",{},[251],{"type":25,"value":252},"References:",{"type":20,"tag":254,"props":255,"children":256},"ul",{},[257,266,274,283,292],{"type":20,"tag":258,"props":259,"children":260},"li",{},[261],{"type":20,"tag":28,"props":262,"children":264},{"href":30,"rel":263},[32],[265],{"type":25,"value":30},{"type":20,"tag":258,"props":267,"children":268},{},[269],{"type":20,"tag":28,"props":270,"children":272},{"href":168,"rel":271},[32],[273],{"type":25,"value":168},{"type":20,"tag":258,"props":275,"children":276},{},[277],{"type":20,"tag":28,"props":278,"children":281},{"href":279,"rel":280},"https://github.com/pcengines/apu2-documentation/blob/master/docs/firmware_flashing.md",[32],[282],{"type":25,"value":279},{"type":20,"tag":258,"props":284,"children":285},{},[286],{"type":20,"tag":28,"props":287,"children":290},{"href":288,"rel":289},"https://github.com/pcengines/apu2-documentation/blob/master/docs/cold_reset.md",[32],[291],{"type":25,"value":288},{"type":20,"tag":258,"props":293,"children":294},{},[295],{"type":20,"tag":28,"props":296,"children":299},{"href":297,"rel":298},"https://github.com/elad/openbsd-apu2",[32],[300],{"type":25,"value":297},{"type":20,"tag":302,"props":303,"children":304},"style",{},[305],{"type":25,"value":306},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":142,"depth":142,"links":308},[],"markdown","content:articles:apu2-firmware-upgrade.md","content","articles/apu2-firmware-upgrade.md","articles/apu2-firmware-upgrade","md",1720229315593] \ No newline at end of file diff --git a/articles/apu2-firmware-upgrade/index.html b/articles/apu2-firmware-upgrade/index.html index e2d849dc..fc13575d 100644 --- a/articles/apu2-firmware-upgrade/index.html +++ b/articles/apu2-firmware-upgrade/index.html @@ -4,35 +4,36 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - - - - -

            Upgrading the Firmware on the PCEngines APU2

            2019-12-21

            I've had a PCEngines APU2 gathering dust for a + + + + + + + + + + + + + + + + +

            Upgrading the Firmware on the PCEngines APU2

            I've had a PCEngines APU2 gathering dust for a few years, and have recently decided to dust it off.

            Since the last time the device has been powered on, there have been many great improvements to the firmware, and it was very-much due for an upgrade. The following steps outline how the firmware was upgraded on the APU from the @@ -46,5 +47,5 @@ with the APU2 device from the PC Engines release website: https://pcengines.github.io/.

            curl -O https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.11.0.1.rom
             

            And finally, we will flash the firmware...

            sudo flashrom -w apu2_v4.11.0.1.rom -p internal:boardmismatch=force
            -

            References:

            - \ No newline at end of file +

            References:

            + \ No newline at end of file diff --git a/articles/docker-selinux-volumes/_payload.json b/articles/docker-selinux-volumes/_payload.json index 82c903ba..32bb18e9 100644 --- a/articles/docker-selinux-volumes/_payload.json +++ b/articles/docker-selinux-volumes/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":239},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":26,"_type":234,"_id":235,"_source":236,"_file":237,"_extension":238},"/articles/docker-selinux-volumes","articles",false,"","Docker Volume Permissions with SELinux","Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","2019-12-26",[12,13],"docker","selinux",[15],"linux",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":232},[28,32,53,57,139,160,168,173,190,199,226],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":33,"props":34,"children":38},"pre",{"code":35,"language":36,"meta":7,"className":37,"style":7},"mkdir: can't create directory '/data': Permission denied\n","txt","language-txt shiki shiki-themes github-light",[39],{"type":20,"tag":40,"props":41,"children":42},"code",{"__ignoreMap":7},[43],{"type":20,"tag":44,"props":45,"children":48},"span",{"class":46,"line":47},"line",1,[49],{"type":20,"tag":44,"props":50,"children":51},{},[52],{"type":25,"value":35},{"type":20,"tag":54,"props":55,"children":56},"hr",{},[],{"type":20,"tag":33,"props":58,"children":62},{"code":59,"language":60,"meta":7,"className":61,"style":7},"$ docker info --format '{{json .SecurityOptions}}'\n[\n \"name=seccomp,profile=/etc/docker/seccomp.json\",\n \"name=selinux\"\n]\n","bash","language-bash shiki shiki-themes github-light",[63],{"type":20,"tag":40,"props":64,"children":65},{"__ignoreMap":7},[66,97,107,121,130],{"type":20,"tag":44,"props":67,"children":68},{"class":46,"line":47},[69,75,81,86,92],{"type":20,"tag":44,"props":70,"children":72},{"style":71},"--shiki-default:#6F42C1",[73],{"type":25,"value":74},"$",{"type":20,"tag":44,"props":76,"children":78},{"style":77},"--shiki-default:#032F62",[79],{"type":25,"value":80}," docker",{"type":20,"tag":44,"props":82,"children":83},{"style":77},[84],{"type":25,"value":85}," info",{"type":20,"tag":44,"props":87,"children":89},{"style":88},"--shiki-default:#005CC5",[90],{"type":25,"value":91}," --format",{"type":20,"tag":44,"props":93,"children":94},{"style":77},[95],{"type":25,"value":96}," '{{json .SecurityOptions}}'\n",{"type":20,"tag":44,"props":98,"children":100},{"class":46,"line":99},2,[101],{"type":20,"tag":44,"props":102,"children":104},{"style":103},"--shiki-default:#24292E",[105],{"type":25,"value":106},"[\n",{"type":20,"tag":44,"props":108,"children":110},{"class":46,"line":109},3,[111,116],{"type":20,"tag":44,"props":112,"children":113},{"style":77},[114],{"type":25,"value":115}," \"name=seccomp,profile=/etc/docker/seccomp.json\"",{"type":20,"tag":44,"props":117,"children":118},{"style":103},[119],{"type":25,"value":120},",\n",{"type":20,"tag":44,"props":122,"children":124},{"class":46,"line":123},4,[125],{"type":20,"tag":44,"props":126,"children":127},{"style":77},[128],{"type":25,"value":129}," \"name=selinux\"\n",{"type":20,"tag":44,"props":131,"children":133},{"class":46,"line":132},5,[134],{"type":20,"tag":44,"props":135,"children":136},{"style":103},[137],{"type":25,"value":138},"]\n",{"type":20,"tag":21,"props":140,"children":141},{},[142,144,150,152,158],{"type":25,"value":143},"It turns out that this can be resolved by appending the ",{"type":20,"tag":40,"props":145,"children":147},{"className":146},[],[148],{"type":25,"value":149},":z",{"type":25,"value":151}," flag to the volume\nmappings in the ",{"type":20,"tag":40,"props":153,"children":155},{"className":154},[],[156],{"type":25,"value":157},"docker-compose.yml",{"type":25,"value":159}," file, indicating that the volume content\nis shared.",{"type":20,"tag":33,"props":161,"children":163},{"code":162},"services:\n server:\n volumes:\n - ./data:/data:z\n",[164],{"type":20,"tag":40,"props":165,"children":166},{"__ignoreMap":7},[167],{"type":25,"value":162},{"type":20,"tag":21,"props":169,"children":170},{},[171],{"type":25,"value":172},"From the Docker documentation:",{"type":20,"tag":174,"props":175,"children":176},"blockquote",{},[177],{"type":20,"tag":21,"props":178,"children":179},{},[180,182,188],{"type":25,"value":181},"The ",{"type":20,"tag":40,"props":183,"children":185},{"className":184},[],[186],{"type":25,"value":187},"z",{"type":25,"value":189}," option tells Docker that two containers share the volume content. As\na result, Docker labels the content with a shared content label. Shared\nvolume labels allow all containers to read/write content.",{"type":20,"tag":21,"props":191,"children":192},{},[193],{"type":20,"tag":194,"props":195,"children":196},"strong",{},[197],{"type":25,"value":198},"References",{"type":20,"tag":200,"props":201,"children":202},"ul",{},[203,216],{"type":20,"tag":204,"props":205,"children":206},"li",{},[207],{"type":20,"tag":208,"props":209,"children":213},"a",{"href":210,"rel":211},"https://docs.docker.com/engine/reference/commandline/info/",[212],"nofollow",[214],{"type":25,"value":215},"Docker Docs: Docker Info",{"type":20,"tag":204,"props":217,"children":218},{},[219],{"type":20,"tag":208,"props":220,"children":223},{"href":221,"rel":222},"https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from",[212],[224],{"type":25,"value":225},"Docker Docs: Mounting Volumes",{"type":20,"tag":227,"props":228,"children":229},"style",{},[230],{"type":25,"value":231},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":99,"depth":99,"links":233},[],"markdown","content:articles:docker-selinux-volumes.md","content","articles/docker-selinux-volumes.md","md",1718891181794] \ No newline at end of file +[{"data":1,"prerenderedAt":240},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":26,"_type":234,"_id":235,"_source":236,"_file":237,"_stem":238,"_extension":239},"/articles/docker-selinux-volumes","articles",false,"","Docker Volume Permissions with SELinux","Unfamiliar with running Docker on a SELinux enabled system, I found myself\nrunning into a bunch of file permission errors while creating volumes.","2019-12-26",[12,13],"docker","selinux",[15],"linux",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":232},[28,32,53,57,139,160,168,173,190,199,226],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":33,"props":34,"children":38},"pre",{"code":35,"language":36,"meta":7,"className":37,"style":7},"mkdir: can't create directory '/data': Permission denied\n","txt","language-txt shiki shiki-themes github-light",[39],{"type":20,"tag":40,"props":41,"children":42},"code",{"__ignoreMap":7},[43],{"type":20,"tag":44,"props":45,"children":48},"span",{"class":46,"line":47},"line",1,[49],{"type":20,"tag":44,"props":50,"children":51},{},[52],{"type":25,"value":35},{"type":20,"tag":54,"props":55,"children":56},"hr",{},[],{"type":20,"tag":33,"props":58,"children":62},{"code":59,"language":60,"meta":7,"className":61,"style":7},"$ docker info --format '{{json .SecurityOptions}}'\n[\n \"name=seccomp,profile=/etc/docker/seccomp.json\",\n \"name=selinux\"\n]\n","bash","language-bash shiki shiki-themes github-light",[63],{"type":20,"tag":40,"props":64,"children":65},{"__ignoreMap":7},[66,97,107,121,130],{"type":20,"tag":44,"props":67,"children":68},{"class":46,"line":47},[69,75,81,86,92],{"type":20,"tag":44,"props":70,"children":72},{"style":71},"--shiki-default:#6F42C1",[73],{"type":25,"value":74},"$",{"type":20,"tag":44,"props":76,"children":78},{"style":77},"--shiki-default:#032F62",[79],{"type":25,"value":80}," docker",{"type":20,"tag":44,"props":82,"children":83},{"style":77},[84],{"type":25,"value":85}," info",{"type":20,"tag":44,"props":87,"children":89},{"style":88},"--shiki-default:#005CC5",[90],{"type":25,"value":91}," --format",{"type":20,"tag":44,"props":93,"children":94},{"style":77},[95],{"type":25,"value":96}," '{{json .SecurityOptions}}'\n",{"type":20,"tag":44,"props":98,"children":100},{"class":46,"line":99},2,[101],{"type":20,"tag":44,"props":102,"children":104},{"style":103},"--shiki-default:#24292E",[105],{"type":25,"value":106},"[\n",{"type":20,"tag":44,"props":108,"children":110},{"class":46,"line":109},3,[111,116],{"type":20,"tag":44,"props":112,"children":113},{"style":77},[114],{"type":25,"value":115}," \"name=seccomp,profile=/etc/docker/seccomp.json\"",{"type":20,"tag":44,"props":117,"children":118},{"style":103},[119],{"type":25,"value":120},",\n",{"type":20,"tag":44,"props":122,"children":124},{"class":46,"line":123},4,[125],{"type":20,"tag":44,"props":126,"children":127},{"style":77},[128],{"type":25,"value":129}," \"name=selinux\"\n",{"type":20,"tag":44,"props":131,"children":133},{"class":46,"line":132},5,[134],{"type":20,"tag":44,"props":135,"children":136},{"style":103},[137],{"type":25,"value":138},"]\n",{"type":20,"tag":21,"props":140,"children":141},{},[142,144,150,152,158],{"type":25,"value":143},"It turns out that this can be resolved by appending the ",{"type":20,"tag":40,"props":145,"children":147},{"className":146},[],[148],{"type":25,"value":149},":z",{"type":25,"value":151}," flag to the volume\nmappings in the ",{"type":20,"tag":40,"props":153,"children":155},{"className":154},[],[156],{"type":25,"value":157},"docker-compose.yml",{"type":25,"value":159}," file, indicating that the volume content\nis shared.",{"type":20,"tag":33,"props":161,"children":163},{"code":162},"services:\n server:\n volumes:\n - ./data:/data:z\n",[164],{"type":20,"tag":40,"props":165,"children":166},{"__ignoreMap":7},[167],{"type":25,"value":162},{"type":20,"tag":21,"props":169,"children":170},{},[171],{"type":25,"value":172},"From the Docker documentation:",{"type":20,"tag":174,"props":175,"children":176},"blockquote",{},[177],{"type":20,"tag":21,"props":178,"children":179},{},[180,182,188],{"type":25,"value":181},"The ",{"type":20,"tag":40,"props":183,"children":185},{"className":184},[],[186],{"type":25,"value":187},"z",{"type":25,"value":189}," option tells Docker that two containers share the volume content. As\na result, Docker labels the content with a shared content label. Shared\nvolume labels allow all containers to read/write content.",{"type":20,"tag":21,"props":191,"children":192},{},[193],{"type":20,"tag":194,"props":195,"children":196},"strong",{},[197],{"type":25,"value":198},"References",{"type":20,"tag":200,"props":201,"children":202},"ul",{},[203,216],{"type":20,"tag":204,"props":205,"children":206},"li",{},[207],{"type":20,"tag":208,"props":209,"children":213},"a",{"href":210,"rel":211},"https://docs.docker.com/engine/reference/commandline/info/",[212],"nofollow",[214],{"type":25,"value":215},"Docker Docs: Docker Info",{"type":20,"tag":204,"props":217,"children":218},{},[219],{"type":20,"tag":208,"props":220,"children":223},{"href":221,"rel":222},"https://docs.docker.com/engine/reference/commandline/run/#mount-volumes-from-container---volumes-from",[212],[224],{"type":25,"value":225},"Docker Docs: Mounting Volumes",{"type":20,"tag":227,"props":228,"children":229},"style",{},[230],{"type":25,"value":231},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":99,"depth":99,"links":233},[],"markdown","content:articles:docker-selinux-volumes.md","content","articles/docker-selinux-volumes.md","articles/docker-selinux-volumes","md",1720229315504] \ No newline at end of file diff --git a/articles/docker-selinux-volumes/index.html b/articles/docker-selinux-volumes/index.html index 8cb0c353..0ebde66c 100644 --- a/articles/docker-selinux-volumes/index.html +++ b/articles/docker-selinux-volumes/index.html @@ -4,36 +4,37 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - - - - - -

            Docker Volume Permissions with SELinux

            2019-12-26

            Unfamiliar with running Docker on a SELinux enabled system, I found myself + + + + + + + + + + + + + + + + + +

            Docker Volume Permissions with SELinux

            Unfamiliar with running Docker on a SELinux enabled system, I found myself running into a bunch of file permission errors while creating volumes.

            mkdir: can't create directory '/data': Permission denied
             

            $ docker info --format '{{json .SecurityOptions}}'
             [
            @@ -48,5 +49,5 @@
                   - ./data:/data:z
             

            From the Docker documentation:

            The z option tells Docker that two containers share the volume content. As a result, Docker labels the content with a shared content label. Shared -volume labels allow all containers to read/write content.

            References

            - \ No newline at end of file +volume labels allow all containers to read/write content.

            References

            + \ No newline at end of file diff --git a/articles/doctl/_payload.json b/articles/doctl/_payload.json index b02c8424..c8abbe04 100644 --- a/articles/doctl/_payload.json +++ b/articles/doctl/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":711},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":14,"excerpt":15,"body":43,"_type":706,"_id":707,"_source":708,"_file":709,"_extension":710},"/articles/doctl","articles",false,"","Exploring the Digital Ocean `doctl` Utility","I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","2023-01-01",[12,13],"linux","digital-ocean",[12],{"type":16,"children":17},"root",[18],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23,26,33,35,41],{"type":24,"value":25},"text","I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean ",{"type":19,"tag":27,"props":28,"children":30},"code",{"className":29},[],[31],{"type":24,"value":32},"doctl",{"type":24,"value":34}," command line utility.\nThis proved to be an ",{"type":19,"tag":36,"props":37,"children":38},"em",{},[39],{"type":24,"value":40},"extremely",{"type":24,"value":42}," easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.",{"type":16,"children":44,"toc":704},[45,60,76,156,177,212,217,289,294,389,402,452,465,495,500,624,629,657,693,698],{"type":19,"tag":20,"props":46,"children":47},{},[48,49,54,55,59],{"type":24,"value":25},{"type":19,"tag":27,"props":50,"children":52},{"className":51},[],[53],{"type":24,"value":32},{"type":24,"value":34},{"type":19,"tag":36,"props":56,"children":57},{},[58],{"type":24,"value":40},{"type":24,"value":42},{"type":19,"tag":20,"props":61,"children":62},{},[63,65,74],{"type":24,"value":64},"To start things off, I had to install and setup authentication to Digital Ocean. Doing\nthis on my Mac machine, I opted to use ",{"type":19,"tag":66,"props":67,"children":71},"a",{"href":68,"rel":69},"https://brew.sh/",[70],"nofollow",[72],{"type":24,"value":73},"Homebrew",{"type":24,"value":75},".",{"type":19,"tag":77,"props":78,"children":82},"pre",{"className":79,"code":80,"language":81,"meta":7,"style":7},"language-sh shiki shiki-themes github-light","# install `doctl`\nbrew install doctl\n\n# setup authentication\ndoctl auth init\n","sh",[83],{"type":19,"tag":27,"props":84,"children":85},{"__ignoreMap":7},[86,98,119,129,138],{"type":19,"tag":87,"props":88,"children":91},"span",{"class":89,"line":90},"line",1,[92],{"type":19,"tag":87,"props":93,"children":95},{"style":94},"--shiki-default:#6A737D",[96],{"type":24,"value":97},"# install `doctl`\n",{"type":19,"tag":87,"props":99,"children":101},{"class":89,"line":100},2,[102,108,114],{"type":19,"tag":87,"props":103,"children":105},{"style":104},"--shiki-default:#6F42C1",[106],{"type":24,"value":107},"brew",{"type":19,"tag":87,"props":109,"children":111},{"style":110},"--shiki-default:#032F62",[112],{"type":24,"value":113}," install",{"type":19,"tag":87,"props":115,"children":116},{"style":110},[117],{"type":24,"value":118}," doctl\n",{"type":19,"tag":87,"props":120,"children":122},{"class":89,"line":121},3,[123],{"type":19,"tag":87,"props":124,"children":126},{"emptyLinePlaceholder":125},true,[127],{"type":24,"value":128},"\n",{"type":19,"tag":87,"props":130,"children":132},{"class":89,"line":131},4,[133],{"type":19,"tag":87,"props":134,"children":135},{"style":94},[136],{"type":24,"value":137},"# setup authentication\n",{"type":19,"tag":87,"props":139,"children":141},{"class":89,"line":140},5,[142,146,151],{"type":19,"tag":87,"props":143,"children":144},{"style":104},[145],{"type":24,"value":32},{"type":19,"tag":87,"props":147,"children":148},{"style":110},[149],{"type":24,"value":150}," auth",{"type":19,"tag":87,"props":152,"children":153},{"style":110},[154],{"type":24,"value":155}," init\n",{"type":19,"tag":20,"props":157,"children":158},{},[159,161,168,170,176],{"type":24,"value":160},"While the online ",{"type":19,"tag":66,"props":162,"children":165},{"href":163,"rel":164},"https://docs.digitalocean.com/reference/doctl/reference/compute/droplet/create/",[70],[166],{"type":24,"value":167},"documentation",{"type":24,"value":169}," is fantastic, I instead found myself mostly referencing the outputs of ",{"type":19,"tag":27,"props":171,"children":173},{"className":172},[],[174],{"type":24,"value":175},"--help",{"type":24,"value":75},{"type":19,"tag":77,"props":178,"children":180},{"className":79,"code":179,"language":81,"meta":7,"style":7},"doctl compute droplet create --help\n",[181],{"type":19,"tag":27,"props":182,"children":183},{"__ignoreMap":7},[184],{"type":19,"tag":87,"props":185,"children":186},{"class":89,"line":90},[187,191,196,201,206],{"type":19,"tag":87,"props":188,"children":189},{"style":104},[190],{"type":24,"value":32},{"type":19,"tag":87,"props":192,"children":193},{"style":110},[194],{"type":24,"value":195}," compute",{"type":19,"tag":87,"props":197,"children":198},{"style":110},[199],{"type":24,"value":200}," droplet",{"type":19,"tag":87,"props":202,"children":203},{"style":110},[204],{"type":24,"value":205}," create",{"type":19,"tag":87,"props":207,"children":209},{"style":208},"--shiki-default:#005CC5",[210],{"type":24,"value":211}," --help\n",{"type":19,"tag":20,"props":213,"children":214},{},[215],{"type":24,"value":216},"I had to find the image name of the version of Ubuntu I wanted to install:",{"type":19,"tag":77,"props":218,"children":220},{"className":79,"code":219,"language":81,"meta":7,"style":7},"doctl compute image list --public | grep ubuntu-22\n\n# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n",[221],{"type":19,"tag":27,"props":222,"children":223},{"__ignoreMap":7},[224,266,273,281],{"type":19,"tag":87,"props":225,"children":226},{"class":89,"line":90},[227,231,235,240,245,250,256,261],{"type":19,"tag":87,"props":228,"children":229},{"style":104},[230],{"type":24,"value":32},{"type":19,"tag":87,"props":232,"children":233},{"style":110},[234],{"type":24,"value":195},{"type":19,"tag":87,"props":236,"children":237},{"style":110},[238],{"type":24,"value":239}," image",{"type":19,"tag":87,"props":241,"children":242},{"style":110},[243],{"type":24,"value":244}," list",{"type":19,"tag":87,"props":246,"children":247},{"style":208},[248],{"type":24,"value":249}," --public",{"type":19,"tag":87,"props":251,"children":253},{"style":252},"--shiki-default:#D73A49",[254],{"type":24,"value":255}," |",{"type":19,"tag":87,"props":257,"children":258},{"style":104},[259],{"type":24,"value":260}," grep",{"type":19,"tag":87,"props":262,"children":263},{"style":110},[264],{"type":24,"value":265}," ubuntu-22\n",{"type":19,"tag":87,"props":267,"children":268},{"class":89,"line":100},[269],{"type":19,"tag":87,"props":270,"children":271},{"emptyLinePlaceholder":125},[272],{"type":24,"value":128},{"type":19,"tag":87,"props":274,"children":275},{"class":89,"line":121},[276],{"type":19,"tag":87,"props":277,"children":278},{"style":94},[279],{"type":24,"value":280},"# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n",{"type":19,"tag":87,"props":282,"children":283},{"class":89,"line":131},[284],{"type":19,"tag":87,"props":285,"children":286},{"style":94},[287],{"type":24,"value":288},"# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n",{"type":19,"tag":20,"props":290,"children":291},{},[292],{"type":24,"value":293},"And also the slug of the compute size:",{"type":19,"tag":77,"props":295,"children":297},{"className":79,"code":296,"language":81,"meta":7,"style":7},"doctl compute size list\n\n# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n",[298],{"type":19,"tag":27,"props":299,"children":300},{"__ignoreMap":7},[301,322,329,337,345,353,362,371,380],{"type":19,"tag":87,"props":302,"children":303},{"class":89,"line":90},[304,308,312,317],{"type":19,"tag":87,"props":305,"children":306},{"style":104},[307],{"type":24,"value":32},{"type":19,"tag":87,"props":309,"children":310},{"style":110},[311],{"type":24,"value":195},{"type":19,"tag":87,"props":313,"children":314},{"style":110},[315],{"type":24,"value":316}," size",{"type":19,"tag":87,"props":318,"children":319},{"style":110},[320],{"type":24,"value":321}," list\n",{"type":19,"tag":87,"props":323,"children":324},{"class":89,"line":100},[325],{"type":19,"tag":87,"props":326,"children":327},{"emptyLinePlaceholder":125},[328],{"type":24,"value":128},{"type":19,"tag":87,"props":330,"children":331},{"class":89,"line":121},[332],{"type":19,"tag":87,"props":333,"children":334},{"style":94},[335],{"type":24,"value":336},"# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n",{"type":19,"tag":87,"props":338,"children":339},{"class":89,"line":131},[340],{"type":19,"tag":87,"props":341,"children":342},{"style":94},[343],{"type":24,"value":344},"# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n",{"type":19,"tag":87,"props":346,"children":347},{"class":89,"line":140},[348],{"type":19,"tag":87,"props":349,"children":350},{"style":94},[351],{"type":24,"value":352},"# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n",{"type":19,"tag":87,"props":354,"children":356},{"class":89,"line":355},6,[357],{"type":19,"tag":87,"props":358,"children":359},{"style":94},[360],{"type":24,"value":361},"# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n",{"type":19,"tag":87,"props":363,"children":365},{"class":89,"line":364},7,[366],{"type":19,"tag":87,"props":367,"children":368},{"style":94},[369],{"type":24,"value":370},"# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n",{"type":19,"tag":87,"props":372,"children":374},{"class":89,"line":373},8,[375],{"type":19,"tag":87,"props":376,"children":377},{"style":94},[378],{"type":24,"value":379},"# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n",{"type":19,"tag":87,"props":381,"children":383},{"class":89,"line":382},9,[384],{"type":19,"tag":87,"props":385,"children":386},{"style":94},[387],{"type":24,"value":388},"# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n",{"type":19,"tag":20,"props":390,"children":391},{},[392,394,400],{"type":24,"value":393},"I've also configured a few SSH keys with Digital Ocean, and I can have the key (specified by ID) provisioned to the machine using the ",{"type":19,"tag":27,"props":395,"children":397},{"className":396},[],[398],{"type":24,"value":399},"--ssh-keys",{"type":24,"value":401}," flag.",{"type":19,"tag":77,"props":403,"children":405},{"className":79,"code":404,"language":81,"meta":7,"style":7},"doctl compute ssh-key list\n\n# ID Name FingerPrint\n# 1234 mini \u003Credacted>\n",[406],{"type":19,"tag":27,"props":407,"children":408},{"__ignoreMap":7},[409,429,436,444],{"type":19,"tag":87,"props":410,"children":411},{"class":89,"line":90},[412,416,420,425],{"type":19,"tag":87,"props":413,"children":414},{"style":104},[415],{"type":24,"value":32},{"type":19,"tag":87,"props":417,"children":418},{"style":110},[419],{"type":24,"value":195},{"type":19,"tag":87,"props":421,"children":422},{"style":110},[423],{"type":24,"value":424}," ssh-key",{"type":19,"tag":87,"props":426,"children":427},{"style":110},[428],{"type":24,"value":321},{"type":19,"tag":87,"props":430,"children":431},{"class":89,"line":100},[432],{"type":19,"tag":87,"props":433,"children":434},{"emptyLinePlaceholder":125},[435],{"type":24,"value":128},{"type":19,"tag":87,"props":437,"children":438},{"class":89,"line":121},[439],{"type":19,"tag":87,"props":440,"children":441},{"style":94},[442],{"type":24,"value":443},"# ID Name FingerPrint\n",{"type":19,"tag":87,"props":445,"children":446},{"class":89,"line":131},[447],{"type":19,"tag":87,"props":448,"children":449},{"style":94},[450],{"type":24,"value":451},"# 1234 mini \u003Credacted>\n",{"type":19,"tag":20,"props":453,"children":454},{},[455,457,463],{"type":24,"value":456},"Also, I wanted to install a few packages to the box upon creation, this can be done easily with the ",{"type":19,"tag":27,"props":458,"children":460},{"className":459},[],[461],{"type":24,"value":462},"--user-data-file",{"type":24,"value":464}," flag to run an initialization script.",{"type":19,"tag":77,"props":466,"children":468},{"className":79,"code":467,"language":81,"meta":7,"style":7},"echo 'apt install -y imagemagick zip' > bootstrap.sh\n",[469],{"type":19,"tag":27,"props":470,"children":471},{"__ignoreMap":7},[472],{"type":19,"tag":87,"props":473,"children":474},{"class":89,"line":90},[475,480,485,490],{"type":19,"tag":87,"props":476,"children":477},{"style":208},[478],{"type":24,"value":479},"echo",{"type":19,"tag":87,"props":481,"children":482},{"style":110},[483],{"type":24,"value":484}," 'apt install -y imagemagick zip'",{"type":19,"tag":87,"props":486,"children":487},{"style":252},[488],{"type":24,"value":489}," >",{"type":19,"tag":87,"props":491,"children":492},{"style":110},[493],{"type":24,"value":494}," bootstrap.sh\n",{"type":19,"tag":20,"props":496,"children":497},{},[498],{"type":24,"value":499},"Putting it all together, here is the simple command for creating a small compute instance!",{"type":19,"tag":77,"props":501,"children":503},{"className":79,"code":502,"language":81,"meta":7,"style":7},"doctl compute droplet create \\\n --image ubuntu-22-10-x64 \\\n --size s-1vcpu-512mb-10gb \\\n --region nyc1 \\\n --ssh-keys 1234 \\\n --user-data-file boostrap.sh \\\n ephemeral\n",[504],{"type":19,"tag":27,"props":505,"children":506},{"__ignoreMap":7},[507,531,548,565,582,599,616],{"type":19,"tag":87,"props":508,"children":509},{"class":89,"line":90},[510,514,518,522,526],{"type":19,"tag":87,"props":511,"children":512},{"style":104},[513],{"type":24,"value":32},{"type":19,"tag":87,"props":515,"children":516},{"style":110},[517],{"type":24,"value":195},{"type":19,"tag":87,"props":519,"children":520},{"style":110},[521],{"type":24,"value":200},{"type":19,"tag":87,"props":523,"children":524},{"style":110},[525],{"type":24,"value":205},{"type":19,"tag":87,"props":527,"children":528},{"style":208},[529],{"type":24,"value":530}," \\\n",{"type":19,"tag":87,"props":532,"children":533},{"class":89,"line":100},[534,539,544],{"type":19,"tag":87,"props":535,"children":536},{"style":208},[537],{"type":24,"value":538}," --image",{"type":19,"tag":87,"props":540,"children":541},{"style":110},[542],{"type":24,"value":543}," ubuntu-22-10-x64",{"type":19,"tag":87,"props":545,"children":546},{"style":208},[547],{"type":24,"value":530},{"type":19,"tag":87,"props":549,"children":550},{"class":89,"line":121},[551,556,561],{"type":19,"tag":87,"props":552,"children":553},{"style":208},[554],{"type":24,"value":555}," --size",{"type":19,"tag":87,"props":557,"children":558},{"style":110},[559],{"type":24,"value":560}," s-1vcpu-512mb-10gb",{"type":19,"tag":87,"props":562,"children":563},{"style":208},[564],{"type":24,"value":530},{"type":19,"tag":87,"props":566,"children":567},{"class":89,"line":131},[568,573,578],{"type":19,"tag":87,"props":569,"children":570},{"style":208},[571],{"type":24,"value":572}," --region",{"type":19,"tag":87,"props":574,"children":575},{"style":110},[576],{"type":24,"value":577}," nyc1",{"type":19,"tag":87,"props":579,"children":580},{"style":208},[581],{"type":24,"value":530},{"type":19,"tag":87,"props":583,"children":584},{"class":89,"line":140},[585,590,595],{"type":19,"tag":87,"props":586,"children":587},{"style":208},[588],{"type":24,"value":589}," --ssh-keys",{"type":19,"tag":87,"props":591,"children":592},{"style":208},[593],{"type":24,"value":594}," 1234",{"type":19,"tag":87,"props":596,"children":597},{"style":208},[598],{"type":24,"value":530},{"type":19,"tag":87,"props":600,"children":601},{"class":89,"line":355},[602,607,612],{"type":19,"tag":87,"props":603,"children":604},{"style":208},[605],{"type":24,"value":606}," --user-data-file",{"type":19,"tag":87,"props":608,"children":609},{"style":110},[610],{"type":24,"value":611}," boostrap.sh",{"type":19,"tag":87,"props":613,"children":614},{"style":208},[615],{"type":24,"value":530},{"type":19,"tag":87,"props":617,"children":618},{"class":89,"line":364},[619],{"type":19,"tag":87,"props":620,"children":621},{"style":110},[622],{"type":24,"value":623}," ephemeral\n",{"type":19,"tag":20,"props":625,"children":626},{},[627],{"type":24,"value":628},"Finally, I can connect, do my thing, and destroy the instance.",{"type":19,"tag":77,"props":630,"children":632},{"className":79,"code":631,"language":81,"meta":7,"style":7},"doctl compute ssh ephemeral\n",[633],{"type":19,"tag":27,"props":634,"children":635},{"__ignoreMap":7},[636],{"type":19,"tag":87,"props":637,"children":638},{"class":89,"line":90},[639,643,647,652],{"type":19,"tag":87,"props":640,"children":641},{"style":104},[642],{"type":24,"value":32},{"type":19,"tag":87,"props":644,"children":645},{"style":110},[646],{"type":24,"value":195},{"type":19,"tag":87,"props":648,"children":649},{"style":110},[650],{"type":24,"value":651}," ssh",{"type":19,"tag":87,"props":653,"children":654},{"style":110},[655],{"type":24,"value":656}," ephemeral\n",{"type":19,"tag":77,"props":658,"children":660},{"className":79,"code":659,"language":81,"meta":7,"style":7},"doctl compute droplet delete --force ephemeral\n",[661],{"type":19,"tag":27,"props":662,"children":663},{"__ignoreMap":7},[664],{"type":19,"tag":87,"props":665,"children":666},{"class":89,"line":90},[667,671,675,679,684,689],{"type":19,"tag":87,"props":668,"children":669},{"style":104},[670],{"type":24,"value":32},{"type":19,"tag":87,"props":672,"children":673},{"style":110},[674],{"type":24,"value":195},{"type":19,"tag":87,"props":676,"children":677},{"style":110},[678],{"type":24,"value":200},{"type":19,"tag":87,"props":680,"children":681},{"style":110},[682],{"type":24,"value":683}," delete",{"type":19,"tag":87,"props":685,"children":686},{"style":208},[687],{"type":24,"value":688}," --force",{"type":19,"tag":87,"props":690,"children":691},{"style":110},[692],{"type":24,"value":656},{"type":19,"tag":20,"props":694,"children":695},{},[696],{"type":24,"value":697},"All-in-all, I was up and running in about 20 minutes. What a handy utility!",{"type":19,"tag":699,"props":700,"children":701},"style",{},[702],{"type":24,"value":703},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":100,"depth":100,"links":705},[],"markdown","content:articles:doctl.md","content","articles/doctl.md","md",1718891181750] \ No newline at end of file +[{"data":1,"prerenderedAt":712},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":14,"excerpt":15,"body":43,"_type":706,"_id":707,"_source":708,"_file":709,"_stem":710,"_extension":711},"/articles/doctl","articles",false,"","Exploring the Digital Ocean `doctl` Utility","I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility.\nThis proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.","2023-01-01",[12,13],"linux","digital-ocean",[12],{"type":16,"children":17},"root",[18],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23,26,33,35,41],{"type":24,"value":25},"text","I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean ",{"type":19,"tag":27,"props":28,"children":30},"code",{"className":29},[],[31],{"type":24,"value":32},"doctl",{"type":24,"value":34}," command line utility.\nThis proved to be an ",{"type":19,"tag":36,"props":37,"children":38},"em",{},[39],{"type":24,"value":40},"extremely",{"type":24,"value":42}," easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.",{"type":16,"children":44,"toc":704},[45,60,76,156,177,212,217,289,294,389,402,452,465,495,500,624,629,657,693,698],{"type":19,"tag":20,"props":46,"children":47},{},[48,49,54,55,59],{"type":24,"value":25},{"type":19,"tag":27,"props":50,"children":52},{"className":51},[],[53],{"type":24,"value":32},{"type":24,"value":34},{"type":19,"tag":36,"props":56,"children":57},{},[58],{"type":24,"value":40},{"type":24,"value":42},{"type":19,"tag":20,"props":61,"children":62},{},[63,65,74],{"type":24,"value":64},"To start things off, I had to install and setup authentication to Digital Ocean. Doing\nthis on my Mac machine, I opted to use ",{"type":19,"tag":66,"props":67,"children":71},"a",{"href":68,"rel":69},"https://brew.sh/",[70],"nofollow",[72],{"type":24,"value":73},"Homebrew",{"type":24,"value":75},".",{"type":19,"tag":77,"props":78,"children":82},"pre",{"className":79,"code":80,"language":81,"meta":7,"style":7},"language-sh shiki shiki-themes github-light","# install `doctl`\nbrew install doctl\n\n# setup authentication\ndoctl auth init\n","sh",[83],{"type":19,"tag":27,"props":84,"children":85},{"__ignoreMap":7},[86,98,119,129,138],{"type":19,"tag":87,"props":88,"children":91},"span",{"class":89,"line":90},"line",1,[92],{"type":19,"tag":87,"props":93,"children":95},{"style":94},"--shiki-default:#6A737D",[96],{"type":24,"value":97},"# install `doctl`\n",{"type":19,"tag":87,"props":99,"children":101},{"class":89,"line":100},2,[102,108,114],{"type":19,"tag":87,"props":103,"children":105},{"style":104},"--shiki-default:#6F42C1",[106],{"type":24,"value":107},"brew",{"type":19,"tag":87,"props":109,"children":111},{"style":110},"--shiki-default:#032F62",[112],{"type":24,"value":113}," install",{"type":19,"tag":87,"props":115,"children":116},{"style":110},[117],{"type":24,"value":118}," doctl\n",{"type":19,"tag":87,"props":120,"children":122},{"class":89,"line":121},3,[123],{"type":19,"tag":87,"props":124,"children":126},{"emptyLinePlaceholder":125},true,[127],{"type":24,"value":128},"\n",{"type":19,"tag":87,"props":130,"children":132},{"class":89,"line":131},4,[133],{"type":19,"tag":87,"props":134,"children":135},{"style":94},[136],{"type":24,"value":137},"# setup authentication\n",{"type":19,"tag":87,"props":139,"children":141},{"class":89,"line":140},5,[142,146,151],{"type":19,"tag":87,"props":143,"children":144},{"style":104},[145],{"type":24,"value":32},{"type":19,"tag":87,"props":147,"children":148},{"style":110},[149],{"type":24,"value":150}," auth",{"type":19,"tag":87,"props":152,"children":153},{"style":110},[154],{"type":24,"value":155}," init\n",{"type":19,"tag":20,"props":157,"children":158},{},[159,161,168,170,176],{"type":24,"value":160},"While the online ",{"type":19,"tag":66,"props":162,"children":165},{"href":163,"rel":164},"https://docs.digitalocean.com/reference/doctl/reference/compute/droplet/create/",[70],[166],{"type":24,"value":167},"documentation",{"type":24,"value":169}," is fantastic, I instead found myself mostly referencing the outputs of ",{"type":19,"tag":27,"props":171,"children":173},{"className":172},[],[174],{"type":24,"value":175},"--help",{"type":24,"value":75},{"type":19,"tag":77,"props":178,"children":180},{"className":79,"code":179,"language":81,"meta":7,"style":7},"doctl compute droplet create --help\n",[181],{"type":19,"tag":27,"props":182,"children":183},{"__ignoreMap":7},[184],{"type":19,"tag":87,"props":185,"children":186},{"class":89,"line":90},[187,191,196,201,206],{"type":19,"tag":87,"props":188,"children":189},{"style":104},[190],{"type":24,"value":32},{"type":19,"tag":87,"props":192,"children":193},{"style":110},[194],{"type":24,"value":195}," compute",{"type":19,"tag":87,"props":197,"children":198},{"style":110},[199],{"type":24,"value":200}," droplet",{"type":19,"tag":87,"props":202,"children":203},{"style":110},[204],{"type":24,"value":205}," create",{"type":19,"tag":87,"props":207,"children":209},{"style":208},"--shiki-default:#005CC5",[210],{"type":24,"value":211}," --help\n",{"type":19,"tag":20,"props":213,"children":214},{},[215],{"type":24,"value":216},"I had to find the image name of the version of Ubuntu I wanted to install:",{"type":19,"tag":77,"props":218,"children":220},{"className":79,"code":219,"language":81,"meta":7,"style":7},"doctl compute image list --public | grep ubuntu-22\n\n# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n",[221],{"type":19,"tag":27,"props":222,"children":223},{"__ignoreMap":7},[224,266,273,281],{"type":19,"tag":87,"props":225,"children":226},{"class":89,"line":90},[227,231,235,240,245,250,256,261],{"type":19,"tag":87,"props":228,"children":229},{"style":104},[230],{"type":24,"value":32},{"type":19,"tag":87,"props":232,"children":233},{"style":110},[234],{"type":24,"value":195},{"type":19,"tag":87,"props":236,"children":237},{"style":110},[238],{"type":24,"value":239}," image",{"type":19,"tag":87,"props":241,"children":242},{"style":110},[243],{"type":24,"value":244}," list",{"type":19,"tag":87,"props":246,"children":247},{"style":208},[248],{"type":24,"value":249}," --public",{"type":19,"tag":87,"props":251,"children":253},{"style":252},"--shiki-default:#D73A49",[254],{"type":24,"value":255}," |",{"type":19,"tag":87,"props":257,"children":258},{"style":104},[259],{"type":24,"value":260}," grep",{"type":19,"tag":87,"props":262,"children":263},{"style":110},[264],{"type":24,"value":265}," ubuntu-22\n",{"type":19,"tag":87,"props":267,"children":268},{"class":89,"line":100},[269],{"type":19,"tag":87,"props":270,"children":271},{"emptyLinePlaceholder":125},[272],{"type":24,"value":128},{"type":19,"tag":87,"props":274,"children":275},{"class":89,"line":121},[276],{"type":19,"tag":87,"props":277,"children":278},{"style":94},[279],{"type":24,"value":280},"# 118857366 22.04 (LTS) x64 snapshot Ubuntu ubuntu-22-04-x64 true 7\n",{"type":19,"tag":87,"props":282,"children":283},{"class":89,"line":131},[284],{"type":19,"tag":87,"props":285,"children":286},{"style":94},[287],{"type":24,"value":288},"# 119383150 22.10 x64 snapshot Ubuntu ubuntu-22-10-x64 true 7\n",{"type":19,"tag":20,"props":290,"children":291},{},[292],{"type":24,"value":293},"And also the slug of the compute size:",{"type":19,"tag":77,"props":295,"children":297},{"className":79,"code":296,"language":81,"meta":7,"style":7},"doctl compute size list\n\n# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n",[298],{"type":19,"tag":27,"props":299,"children":300},{"__ignoreMap":7},[301,322,329,337,345,353,362,371,380],{"type":19,"tag":87,"props":302,"children":303},{"class":89,"line":90},[304,308,312,317],{"type":19,"tag":87,"props":305,"children":306},{"style":104},[307],{"type":24,"value":32},{"type":19,"tag":87,"props":309,"children":310},{"style":110},[311],{"type":24,"value":195},{"type":19,"tag":87,"props":313,"children":314},{"style":110},[315],{"type":24,"value":316}," size",{"type":19,"tag":87,"props":318,"children":319},{"style":110},[320],{"type":24,"value":321}," list\n",{"type":19,"tag":87,"props":323,"children":324},{"class":89,"line":100},[325],{"type":19,"tag":87,"props":326,"children":327},{"emptyLinePlaceholder":125},[328],{"type":24,"value":128},{"type":19,"tag":87,"props":330,"children":331},{"class":89,"line":121},[332],{"type":19,"tag":87,"props":333,"children":334},{"style":94},[335],{"type":24,"value":336},"# Slug Description Memory VCPUs Disk Price Monthly Price Hourly\n",{"type":19,"tag":87,"props":338,"children":339},{"class":89,"line":131},[340],{"type":19,"tag":87,"props":341,"children":342},{"style":94},[343],{"type":24,"value":344},"# s-1vcpu-512mb-10gb Basic 512 1 10 4.00 0.005950\n",{"type":19,"tag":87,"props":346,"children":347},{"class":89,"line":140},[348],{"type":19,"tag":87,"props":349,"children":350},{"style":94},[351],{"type":24,"value":352},"# s-1vcpu-1gb Basic 1024 1 25 6.00 0.008930\n",{"type":19,"tag":87,"props":354,"children":356},{"class":89,"line":355},6,[357],{"type":19,"tag":87,"props":358,"children":359},{"style":94},[360],{"type":24,"value":361},"# s-1vcpu-1gb-amd Basic AMD 1024 1 25 7.00 0.010420\n",{"type":19,"tag":87,"props":363,"children":365},{"class":89,"line":364},7,[366],{"type":19,"tag":87,"props":367,"children":368},{"style":94},[369],{"type":24,"value":370},"# s-1vcpu-1gb-intel Basic Intel 1024 1 25 7.00 0.010420\n",{"type":19,"tag":87,"props":372,"children":374},{"class":89,"line":373},8,[375],{"type":19,"tag":87,"props":376,"children":377},{"style":94},[378],{"type":24,"value":379},"# s-1vcpu-2gb Basic 2048 1 50 12.00 0.017860\n",{"type":19,"tag":87,"props":381,"children":383},{"class":89,"line":382},9,[384],{"type":19,"tag":87,"props":385,"children":386},{"style":94},[387],{"type":24,"value":388},"# s-1vcpu-2gb-amd Basic AMD 2048 1 50 14.00 0.020830\n",{"type":19,"tag":20,"props":390,"children":391},{},[392,394,400],{"type":24,"value":393},"I've also configured a few SSH keys with Digital Ocean, and I can have the key (specified by ID) provisioned to the machine using the ",{"type":19,"tag":27,"props":395,"children":397},{"className":396},[],[398],{"type":24,"value":399},"--ssh-keys",{"type":24,"value":401}," flag.",{"type":19,"tag":77,"props":403,"children":405},{"className":79,"code":404,"language":81,"meta":7,"style":7},"doctl compute ssh-key list\n\n# ID Name FingerPrint\n# 1234 mini \u003Credacted>\n",[406],{"type":19,"tag":27,"props":407,"children":408},{"__ignoreMap":7},[409,429,436,444],{"type":19,"tag":87,"props":410,"children":411},{"class":89,"line":90},[412,416,420,425],{"type":19,"tag":87,"props":413,"children":414},{"style":104},[415],{"type":24,"value":32},{"type":19,"tag":87,"props":417,"children":418},{"style":110},[419],{"type":24,"value":195},{"type":19,"tag":87,"props":421,"children":422},{"style":110},[423],{"type":24,"value":424}," ssh-key",{"type":19,"tag":87,"props":426,"children":427},{"style":110},[428],{"type":24,"value":321},{"type":19,"tag":87,"props":430,"children":431},{"class":89,"line":100},[432],{"type":19,"tag":87,"props":433,"children":434},{"emptyLinePlaceholder":125},[435],{"type":24,"value":128},{"type":19,"tag":87,"props":437,"children":438},{"class":89,"line":121},[439],{"type":19,"tag":87,"props":440,"children":441},{"style":94},[442],{"type":24,"value":443},"# ID Name FingerPrint\n",{"type":19,"tag":87,"props":445,"children":446},{"class":89,"line":131},[447],{"type":19,"tag":87,"props":448,"children":449},{"style":94},[450],{"type":24,"value":451},"# 1234 mini \u003Credacted>\n",{"type":19,"tag":20,"props":453,"children":454},{},[455,457,463],{"type":24,"value":456},"Also, I wanted to install a few packages to the box upon creation, this can be done easily with the ",{"type":19,"tag":27,"props":458,"children":460},{"className":459},[],[461],{"type":24,"value":462},"--user-data-file",{"type":24,"value":464}," flag to run an initialization script.",{"type":19,"tag":77,"props":466,"children":468},{"className":79,"code":467,"language":81,"meta":7,"style":7},"echo 'apt install -y imagemagick zip' > bootstrap.sh\n",[469],{"type":19,"tag":27,"props":470,"children":471},{"__ignoreMap":7},[472],{"type":19,"tag":87,"props":473,"children":474},{"class":89,"line":90},[475,480,485,490],{"type":19,"tag":87,"props":476,"children":477},{"style":208},[478],{"type":24,"value":479},"echo",{"type":19,"tag":87,"props":481,"children":482},{"style":110},[483],{"type":24,"value":484}," 'apt install -y imagemagick zip'",{"type":19,"tag":87,"props":486,"children":487},{"style":252},[488],{"type":24,"value":489}," >",{"type":19,"tag":87,"props":491,"children":492},{"style":110},[493],{"type":24,"value":494}," bootstrap.sh\n",{"type":19,"tag":20,"props":496,"children":497},{},[498],{"type":24,"value":499},"Putting it all together, here is the simple command for creating a small compute instance!",{"type":19,"tag":77,"props":501,"children":503},{"className":79,"code":502,"language":81,"meta":7,"style":7},"doctl compute droplet create \\\n --image ubuntu-22-10-x64 \\\n --size s-1vcpu-512mb-10gb \\\n --region nyc1 \\\n --ssh-keys 1234 \\\n --user-data-file boostrap.sh \\\n ephemeral\n",[504],{"type":19,"tag":27,"props":505,"children":506},{"__ignoreMap":7},[507,531,548,565,582,599,616],{"type":19,"tag":87,"props":508,"children":509},{"class":89,"line":90},[510,514,518,522,526],{"type":19,"tag":87,"props":511,"children":512},{"style":104},[513],{"type":24,"value":32},{"type":19,"tag":87,"props":515,"children":516},{"style":110},[517],{"type":24,"value":195},{"type":19,"tag":87,"props":519,"children":520},{"style":110},[521],{"type":24,"value":200},{"type":19,"tag":87,"props":523,"children":524},{"style":110},[525],{"type":24,"value":205},{"type":19,"tag":87,"props":527,"children":528},{"style":208},[529],{"type":24,"value":530}," \\\n",{"type":19,"tag":87,"props":532,"children":533},{"class":89,"line":100},[534,539,544],{"type":19,"tag":87,"props":535,"children":536},{"style":208},[537],{"type":24,"value":538}," --image",{"type":19,"tag":87,"props":540,"children":541},{"style":110},[542],{"type":24,"value":543}," ubuntu-22-10-x64",{"type":19,"tag":87,"props":545,"children":546},{"style":208},[547],{"type":24,"value":530},{"type":19,"tag":87,"props":549,"children":550},{"class":89,"line":121},[551,556,561],{"type":19,"tag":87,"props":552,"children":553},{"style":208},[554],{"type":24,"value":555}," --size",{"type":19,"tag":87,"props":557,"children":558},{"style":110},[559],{"type":24,"value":560}," s-1vcpu-512mb-10gb",{"type":19,"tag":87,"props":562,"children":563},{"style":208},[564],{"type":24,"value":530},{"type":19,"tag":87,"props":566,"children":567},{"class":89,"line":131},[568,573,578],{"type":19,"tag":87,"props":569,"children":570},{"style":208},[571],{"type":24,"value":572}," --region",{"type":19,"tag":87,"props":574,"children":575},{"style":110},[576],{"type":24,"value":577}," nyc1",{"type":19,"tag":87,"props":579,"children":580},{"style":208},[581],{"type":24,"value":530},{"type":19,"tag":87,"props":583,"children":584},{"class":89,"line":140},[585,590,595],{"type":19,"tag":87,"props":586,"children":587},{"style":208},[588],{"type":24,"value":589}," --ssh-keys",{"type":19,"tag":87,"props":591,"children":592},{"style":208},[593],{"type":24,"value":594}," 1234",{"type":19,"tag":87,"props":596,"children":597},{"style":208},[598],{"type":24,"value":530},{"type":19,"tag":87,"props":600,"children":601},{"class":89,"line":355},[602,607,612],{"type":19,"tag":87,"props":603,"children":604},{"style":208},[605],{"type":24,"value":606}," --user-data-file",{"type":19,"tag":87,"props":608,"children":609},{"style":110},[610],{"type":24,"value":611}," boostrap.sh",{"type":19,"tag":87,"props":613,"children":614},{"style":208},[615],{"type":24,"value":530},{"type":19,"tag":87,"props":617,"children":618},{"class":89,"line":364},[619],{"type":19,"tag":87,"props":620,"children":621},{"style":110},[622],{"type":24,"value":623}," ephemeral\n",{"type":19,"tag":20,"props":625,"children":626},{},[627],{"type":24,"value":628},"Finally, I can connect, do my thing, and destroy the instance.",{"type":19,"tag":77,"props":630,"children":632},{"className":79,"code":631,"language":81,"meta":7,"style":7},"doctl compute ssh ephemeral\n",[633],{"type":19,"tag":27,"props":634,"children":635},{"__ignoreMap":7},[636],{"type":19,"tag":87,"props":637,"children":638},{"class":89,"line":90},[639,643,647,652],{"type":19,"tag":87,"props":640,"children":641},{"style":104},[642],{"type":24,"value":32},{"type":19,"tag":87,"props":644,"children":645},{"style":110},[646],{"type":24,"value":195},{"type":19,"tag":87,"props":648,"children":649},{"style":110},[650],{"type":24,"value":651}," ssh",{"type":19,"tag":87,"props":653,"children":654},{"style":110},[655],{"type":24,"value":656}," ephemeral\n",{"type":19,"tag":77,"props":658,"children":660},{"className":79,"code":659,"language":81,"meta":7,"style":7},"doctl compute droplet delete --force ephemeral\n",[661],{"type":19,"tag":27,"props":662,"children":663},{"__ignoreMap":7},[664],{"type":19,"tag":87,"props":665,"children":666},{"class":89,"line":90},[667,671,675,679,684,689],{"type":19,"tag":87,"props":668,"children":669},{"style":104},[670],{"type":24,"value":32},{"type":19,"tag":87,"props":672,"children":673},{"style":110},[674],{"type":24,"value":195},{"type":19,"tag":87,"props":676,"children":677},{"style":110},[678],{"type":24,"value":200},{"type":19,"tag":87,"props":680,"children":681},{"style":110},[682],{"type":24,"value":683}," delete",{"type":19,"tag":87,"props":685,"children":686},{"style":208},[687],{"type":24,"value":688}," --force",{"type":19,"tag":87,"props":690,"children":691},{"style":110},[692],{"type":24,"value":656},{"type":19,"tag":20,"props":694,"children":695},{},[696],{"type":24,"value":697},"All-in-all, I was up and running in about 20 minutes. What a handy utility!",{"type":19,"tag":699,"props":700,"children":701},"style",{},[702],{"type":24,"value":703},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":100,"depth":100,"links":705},[],"markdown","content:articles:doctl.md","content","articles/doctl.md","articles/doctl","md",1720229315493] \ No newline at end of file diff --git a/articles/doctl/index.html b/articles/doctl/index.html index 9b793577..0e450799 100644 --- a/articles/doctl/index.html +++ b/articles/doctl/index.html @@ -4,32 +4,33 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - -

            Exploring the Digital Ocean `doctl` Utility

            2023-01-01

            I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility. + + + + + + + + + + + + + +

            Exploring the Digital Ocean `doctl` Utility

            I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility. This proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.

            To start things off, I had to install and setup authentication to Digital Ocean. Doing this on my Mac machine, I opted to use Homebrew.

            # install `doctl`
             brew install doctl
            @@ -64,5 +65,5 @@
                 ephemeral
             

            Finally, I can connect, do my thing, and destroy the instance.

            doctl compute ssh ephemeral
             
            doctl compute droplet delete --force ephemeral
            -

            All-in-all, I was up and running in about 20 minutes. What a handy utility!

            - \ No newline at end of file +

            All-in-all, I was up and running in about 20 minutes. What a handy utility!

            + \ No newline at end of file diff --git a/articles/fennel-initial-exploration/_payload.json b/articles/fennel-initial-exploration/_payload.json index 32809426..ca41b693 100644 --- a/articles/fennel-initial-exploration/_payload.json +++ b/articles/fennel-initial-exploration/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":1105},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":15,"cover_image":16,"excerpt":17,"body":27,"_type":1100,"_id":1101,"_source":1102,"_file":1103,"_extension":1104},"/articles/fennel-initial-exploration","articles",false,"","Impressions of Fennel with Hammerspoon","A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","2023-10-22",[12,13,14],"lisp","hammerspoon","fennel",[12],"/images/dall-e-fennel-hammer.jpeg",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25],{"type":26,"value":9},"text",{"type":18,"children":28,"toc":1094},[29,33,67,74,88,94,125,157,170,199,422,428,458,536,598,611,917,1039,1052,1058,1063,1077,1088],{"type":21,"tag":22,"props":30,"children":31},{},[32],{"type":26,"value":9},{"type":21,"tag":22,"props":34,"children":35},{},[36,38,47,49,56,58,65],{"type":26,"value":37},"The ",{"type":21,"tag":39,"props":40,"children":44},"a",{"href":41,"rel":42},"https://fennel-lang.org/",[43],"nofollow",[45],{"type":26,"value":46},"Fennel",{"type":26,"value":48}," programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: ",{"type":21,"tag":39,"props":50,"children":53},{"href":51,"rel":52},"https://www.hammerspoon.org/",[43],[54],{"type":26,"value":55},"Hammerspoon",{"type":26,"value":57},", and ",{"type":21,"tag":39,"props":59,"children":62},{"href":60,"rel":61},"https://neovim.io/",[43],[63],{"type":26,"value":64},"Neovim",{"type":26,"value":66},".",{"type":21,"tag":68,"props":69,"children":71},"h2",{"id":70},"initial-observations",[72],{"type":26,"value":73},"Initial Observations",{"type":21,"tag":22,"props":75,"children":76},{},[77,79,86],{"type":26,"value":78},"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 ",{"type":21,"tag":39,"props":80,"children":83},{"href":81,"rel":82},"https://github.com/cmpadden/dotfiles/tree/795749fa17e1310bb001bb7deaa22be8689f0027/hammerspoon/.hammerspoon/modules",[43],[84],{"type":26,"value":85},"modules",{"type":26,"value":87}," that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project...",{"type":21,"tag":68,"props":89,"children":91},{"id":90},"integrating-fennel-with-hammerspoon",[92],{"type":26,"value":93},"Integrating Fennel with Hammerspoon",{"type":21,"tag":22,"props":95,"children":96},{},[97,99,106,108,115,117,123],{"type":26,"value":98},"While official documentation exists describing how to ",{"type":21,"tag":39,"props":100,"children":103},{"href":101,"rel":102},"https://fennel-lang.org/setup#embedding-fennel",[43],[104],{"type":26,"value":105},"embed fennel",{"type":26,"value":107}," into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n",{"type":21,"tag":109,"props":110,"children":112},"code",{"className":111},[],[113],{"type":26,"value":114},"package.path",{"type":26,"value":116}," and ",{"type":21,"tag":109,"props":118,"children":120},{"className":119},[],[121],{"type":26,"value":122},"package.cpath",{"type":26,"value":124}," properties in Lua, but I was unable to get this to\nwork.",{"type":21,"tag":126,"props":127,"children":128},"ul",{},[129,139,148],{"type":21,"tag":130,"props":131,"children":132},"li",{},[133],{"type":21,"tag":39,"props":134,"children":137},{"href":135,"rel":136},"https://blog.exupero.org/hammerspoon-with-fennel/",[43],[138],{"type":26,"value":135},{"type":21,"tag":130,"props":140,"children":141},{},[142],{"type":21,"tag":39,"props":143,"children":146},{"href":144,"rel":145},"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435",[43],[147],{"type":26,"value":144},{"type":21,"tag":130,"props":149,"children":150},{},[151],{"type":21,"tag":39,"props":152,"children":155},{"href":153,"rel":154},"https://github.com/agzam/spacehammer/blob/master/init.lua",[43],[156],{"type":26,"value":153},{"type":21,"tag":22,"props":158,"children":159},{},[160,162,168],{"type":26,"value":161},"Ultimately, I opted to include the ",{"type":21,"tag":109,"props":163,"children":165},{"className":164},[],[166],{"type":26,"value":167},"fennel.lua",{"type":26,"value":169}," file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks.",{"type":21,"tag":22,"props":171,"children":172},{},[173,175,181,183,189,191,197],{"type":26,"value":174},"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe ",{"type":21,"tag":109,"props":176,"children":178},{"className":177},[],[179],{"type":26,"value":180},"fennel.path",{"type":26,"value":182}," to point to the ",{"type":21,"tag":109,"props":184,"children":186},{"className":185},[],[187],{"type":26,"value":188},"*.fnl",{"type":26,"value":190}," files in the ",{"type":21,"tag":109,"props":192,"children":194},{"className":193},[],[195],{"type":26,"value":196},".hammerspoon/",{"type":26,"value":198}," directory, and\nttranslating these modules can begin!",{"type":21,"tag":200,"props":201,"children":205},"pre",{"className":202,"code":203,"language":204,"meta":7,"style":7},"language-lua shiki shiki-themes github-light","-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"/.hammerspoon/?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'\n","lua",[206],{"type":21,"tag":109,"props":207,"children":208},{"__ignoreMap":7},[209,221,231,274,282,350,358,400,408],{"type":21,"tag":210,"props":211,"children":214},"span",{"class":212,"line":213},"line",1,[215],{"type":21,"tag":210,"props":216,"children":218},{"style":217},"--shiki-default:#6A737D",[219],{"type":26,"value":220},"-- init.lua\n",{"type":21,"tag":210,"props":222,"children":224},{"class":212,"line":223},2,[225],{"type":21,"tag":210,"props":226,"children":228},{"emptyLinePlaceholder":227},true,[229],{"type":26,"value":230},"\n",{"type":21,"tag":210,"props":232,"children":234},{"class":212,"line":233},3,[235,241,247,252,258,263,269],{"type":21,"tag":210,"props":236,"children":238},{"style":237},"--shiki-default:#D73A49",[239],{"type":26,"value":240},"local",{"type":21,"tag":210,"props":242,"children":244},{"style":243},"--shiki-default:#24292E",[245],{"type":26,"value":246}," fennel ",{"type":21,"tag":210,"props":248,"children":249},{"style":237},[250],{"type":26,"value":251},"=",{"type":21,"tag":210,"props":253,"children":255},{"style":254},"--shiki-default:#005CC5",[256],{"type":26,"value":257}," require",{"type":21,"tag":210,"props":259,"children":260},{"style":243},[261],{"type":26,"value":262},"(",{"type":21,"tag":210,"props":264,"children":266},{"style":265},"--shiki-default:#032F62",[267],{"type":26,"value":268},"'fennel'",{"type":21,"tag":210,"props":270,"children":271},{"style":243},[272],{"type":26,"value":273},")\n",{"type":21,"tag":210,"props":275,"children":277},{"class":212,"line":276},4,[278],{"type":21,"tag":210,"props":279,"children":280},{"emptyLinePlaceholder":227},[281],{"type":26,"value":230},{"type":21,"tag":210,"props":283,"children":285},{"class":212,"line":284},5,[286,291,297,302,307,312,317,322,327,331,336,341,345],{"type":21,"tag":210,"props":287,"children":288},{"style":243},[289],{"type":26,"value":290},"fennel.",{"type":21,"tag":210,"props":292,"children":294},{"style":293},"--shiki-default:#6F42C1",[295],{"type":26,"value":296},"path",{"type":21,"tag":210,"props":298,"children":299},{"style":237},[300],{"type":26,"value":301}," =",{"type":21,"tag":210,"props":303,"children":304},{"style":254},[305],{"type":26,"value":306}," package.path",{"type":21,"tag":210,"props":308,"children":309},{"style":237},[310],{"type":26,"value":311}," ..",{"type":21,"tag":210,"props":313,"children":314},{"style":265},[315],{"type":26,"value":316}," \";\" ",{"type":21,"tag":210,"props":318,"children":319},{"style":237},[320],{"type":26,"value":321},"..",{"type":21,"tag":210,"props":323,"children":324},{"style":254},[325],{"type":26,"value":326}," os.getenv",{"type":21,"tag":210,"props":328,"children":329},{"style":243},[330],{"type":26,"value":262},{"type":21,"tag":210,"props":332,"children":333},{"style":265},[334],{"type":26,"value":335},"\"HOME\"",{"type":21,"tag":210,"props":337,"children":338},{"style":243},[339],{"type":26,"value":340},") ",{"type":21,"tag":210,"props":342,"children":343},{"style":237},[344],{"type":26,"value":321},{"type":21,"tag":210,"props":346,"children":347},{"style":265},[348],{"type":26,"value":349}," \"/.hammerspoon/?.fnl\"\n",{"type":21,"tag":210,"props":351,"children":353},{"class":212,"line":352},6,[354],{"type":21,"tag":210,"props":355,"children":356},{"emptyLinePlaceholder":227},[357],{"type":26,"value":230},{"type":21,"tag":210,"props":359,"children":361},{"class":212,"line":360},7,[362,367,371,376,381,386,391,396],{"type":21,"tag":210,"props":363,"children":364},{"style":254},[365],{"type":26,"value":366},"table.insert",{"type":21,"tag":210,"props":368,"children":369},{"style":243},[370],{"type":26,"value":262},{"type":21,"tag":210,"props":372,"children":373},{"style":254},[374],{"type":26,"value":375},"package.loaders",{"type":21,"tag":210,"props":377,"children":378},{"style":237},[379],{"type":26,"value":380}," or",{"type":21,"tag":210,"props":382,"children":383},{"style":254},[384],{"type":26,"value":385}," package.searchers",{"type":21,"tag":210,"props":387,"children":388},{"style":243},[389],{"type":26,"value":390},", fennel.",{"type":21,"tag":210,"props":392,"children":393},{"style":293},[394],{"type":26,"value":395},"searcher",{"type":21,"tag":210,"props":397,"children":398},{"style":243},[399],{"type":26,"value":273},{"type":21,"tag":210,"props":401,"children":403},{"class":212,"line":402},8,[404],{"type":21,"tag":210,"props":405,"children":406},{"emptyLinePlaceholder":227},[407],{"type":26,"value":230},{"type":21,"tag":210,"props":409,"children":411},{"class":212,"line":410},9,[412,417],{"type":21,"tag":210,"props":413,"children":414},{"style":254},[415],{"type":26,"value":416},"require",{"type":21,"tag":210,"props":418,"children":419},{"style":265},[420],{"type":26,"value":421}," 'main'\n",{"type":21,"tag":68,"props":423,"children":425},{"id":424},"translating-lua-to-fennel",[426],{"type":26,"value":427},"Translating Lua to Fennel",{"type":21,"tag":22,"props":429,"children":430},{},[431,433,440,442,448,450,456],{"type":26,"value":432},"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called ",{"type":21,"tag":39,"props":434,"children":437},{"href":435,"rel":436},"https://fennel-lang.org/see",[43],[438],{"type":26,"value":439},"anti-fennel",{"type":26,"value":441},", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple ",{"type":21,"tag":109,"props":443,"children":445},{"className":444},[],[446],{"type":26,"value":447},"sleep",{"type":26,"value":449}," function\nfrom the ",{"type":21,"tag":109,"props":451,"children":453},{"className":452},[],[454],{"type":26,"value":455},"helpers",{"type":26,"value":457}," module into the compiler:",{"type":21,"tag":200,"props":459,"children":461},{"className":202,"code":460,"language":204,"meta":7,"style":7},"function sleep(ms)\n os.execute(\"sleep \" .. tonumber(ms) / 1000)\nend\n",[462],{"type":21,"tag":109,"props":463,"children":464},{"__ignoreMap":7},[465,483,528],{"type":21,"tag":210,"props":466,"children":467},{"class":212,"line":213},[468,473,478],{"type":21,"tag":210,"props":469,"children":470},{"style":237},[471],{"type":26,"value":472},"function",{"type":21,"tag":210,"props":474,"children":475},{"style":293},[476],{"type":26,"value":477}," sleep",{"type":21,"tag":210,"props":479,"children":480},{"style":243},[481],{"type":26,"value":482},"(ms)\n",{"type":21,"tag":210,"props":484,"children":485},{"class":212,"line":223},[486,491,495,500,504,509,514,519,524],{"type":21,"tag":210,"props":487,"children":488},{"style":254},[489],{"type":26,"value":490}," os.execute",{"type":21,"tag":210,"props":492,"children":493},{"style":243},[494],{"type":26,"value":262},{"type":21,"tag":210,"props":496,"children":497},{"style":265},[498],{"type":26,"value":499},"\"sleep \" ",{"type":21,"tag":210,"props":501,"children":502},{"style":237},[503],{"type":26,"value":321},{"type":21,"tag":210,"props":505,"children":506},{"style":254},[507],{"type":26,"value":508}," tonumber",{"type":21,"tag":210,"props":510,"children":511},{"style":243},[512],{"type":26,"value":513},"(ms) ",{"type":21,"tag":210,"props":515,"children":516},{"style":237},[517],{"type":26,"value":518},"/",{"type":21,"tag":210,"props":520,"children":521},{"style":254},[522],{"type":26,"value":523}," 1000",{"type":21,"tag":210,"props":525,"children":526},{"style":243},[527],{"type":26,"value":273},{"type":21,"tag":210,"props":529,"children":530},{"class":212,"line":233},[531],{"type":21,"tag":210,"props":532,"children":533},{"style":237},[534],{"type":26,"value":535},"end\n",{"type":21,"tag":200,"props":537,"children":540},{"className":538,"code":539,"language":12,"meta":7,"style":7},"language-lisp shiki shiki-themes github-light","(fn sleep [ms]\n (os.execute (.. \"sleep \" (/ (tonumber ms) 1000))))\n",[541],{"type":21,"tag":109,"props":542,"children":543},{"__ignoreMap":7},[544,561],{"type":21,"tag":210,"props":545,"children":546},{"class":212,"line":213},[547,552,556],{"type":21,"tag":210,"props":548,"children":549},{"style":243},[550],{"type":26,"value":551},"(fn ",{"type":21,"tag":210,"props":553,"children":554},{"style":254},[555],{"type":26,"value":447},{"type":21,"tag":210,"props":557,"children":558},{"style":243},[559],{"type":26,"value":560}," [ms]\n",{"type":21,"tag":210,"props":562,"children":563},{"class":212,"line":223},[564,569,574,579,583,588,593],{"type":21,"tag":210,"props":565,"children":566},{"style":243},[567],{"type":26,"value":568}," (os.execute (.. ",{"type":21,"tag":210,"props":570,"children":571},{"style":265},[572],{"type":26,"value":573},"\"sleep \"",{"type":21,"tag":210,"props":575,"children":576},{"style":243},[577],{"type":26,"value":578}," (",{"type":21,"tag":210,"props":580,"children":581},{"style":254},[582],{"type":26,"value":518},{"type":21,"tag":210,"props":584,"children":585},{"style":243},[586],{"type":26,"value":587}," (tonumber ms) ",{"type":21,"tag":210,"props":589,"children":590},{"style":254},[591],{"type":26,"value":592},"1000",{"type":21,"tag":210,"props":594,"children":595},{"style":243},[596],{"type":26,"value":597},"))))\n",{"type":21,"tag":22,"props":599,"children":600},{},[601,603,609],{"type":26,"value":602},"As another example, here is the output for my ",{"type":21,"tag":604,"props":605,"children":606},"em",{},[607],{"type":26,"value":608},"caffeine",{"type":26,"value":610}," toggle:",{"type":21,"tag":200,"props":612,"children":614},{"className":202,"code":613,"language":204,"meta":7,"style":7},"hs.hotkey.bind(HYPER, \"0\", function()\n hs.caffeinate.toggle(\"displayIdle\")\n if hs.caffeinate.get(\"displayIdle\") then\n helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n else\n helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n end\nend)\n",[615],{"type":21,"tag":109,"props":616,"children":617},{"__ignoreMap":7},[618,664,699,742,819,827,897,905],{"type":21,"tag":210,"props":619,"children":620},{"class":212,"line":213},[621,626,631,635,640,645,650,655,659],{"type":21,"tag":210,"props":622,"children":623},{"style":243},[624],{"type":26,"value":625},"hs.",{"type":21,"tag":210,"props":627,"children":628},{"style":293},[629],{"type":26,"value":630},"hotkey",{"type":21,"tag":210,"props":632,"children":633},{"style":243},[634],{"type":26,"value":66},{"type":21,"tag":210,"props":636,"children":637},{"style":254},[638],{"type":26,"value":639},"bind",{"type":21,"tag":210,"props":641,"children":642},{"style":243},[643],{"type":26,"value":644},"(HYPER, ",{"type":21,"tag":210,"props":646,"children":647},{"style":265},[648],{"type":26,"value":649},"\"0\"",{"type":21,"tag":210,"props":651,"children":652},{"style":243},[653],{"type":26,"value":654},", ",{"type":21,"tag":210,"props":656,"children":657},{"style":237},[658],{"type":26,"value":472},{"type":21,"tag":210,"props":660,"children":661},{"style":243},[662],{"type":26,"value":663},"()\n",{"type":21,"tag":210,"props":665,"children":666},{"class":212,"line":223},[667,672,677,681,686,690,695],{"type":21,"tag":210,"props":668,"children":669},{"style":243},[670],{"type":26,"value":671}," hs.",{"type":21,"tag":210,"props":673,"children":674},{"style":293},[675],{"type":26,"value":676},"caffeinate",{"type":21,"tag":210,"props":678,"children":679},{"style":243},[680],{"type":26,"value":66},{"type":21,"tag":210,"props":682,"children":683},{"style":254},[684],{"type":26,"value":685},"toggle",{"type":21,"tag":210,"props":687,"children":688},{"style":243},[689],{"type":26,"value":262},{"type":21,"tag":210,"props":691,"children":692},{"style":265},[693],{"type":26,"value":694},"\"displayIdle\"",{"type":21,"tag":210,"props":696,"children":697},{"style":243},[698],{"type":26,"value":273},{"type":21,"tag":210,"props":700,"children":701},{"class":212,"line":233},[702,707,712,716,720,725,729,733,737],{"type":21,"tag":210,"props":703,"children":704},{"style":237},[705],{"type":26,"value":706}," if",{"type":21,"tag":210,"props":708,"children":709},{"style":243},[710],{"type":26,"value":711}," hs.",{"type":21,"tag":210,"props":713,"children":714},{"style":293},[715],{"type":26,"value":676},{"type":21,"tag":210,"props":717,"children":718},{"style":243},[719],{"type":26,"value":66},{"type":21,"tag":210,"props":721,"children":722},{"style":254},[723],{"type":26,"value":724},"get",{"type":21,"tag":210,"props":726,"children":727},{"style":243},[728],{"type":26,"value":262},{"type":21,"tag":210,"props":730,"children":731},{"style":265},[732],{"type":26,"value":694},{"type":21,"tag":210,"props":734,"children":735},{"style":243},[736],{"type":26,"value":340},{"type":21,"tag":210,"props":738,"children":739},{"style":237},[740],{"type":26,"value":741},"then\n",{"type":21,"tag":210,"props":743,"children":744},{"class":212,"line":276},[745,750,755,760,764,769,773,778,783,788,792,797,801,806,810,815],{"type":21,"tag":210,"props":746,"children":747},{"style":293},[748],{"type":26,"value":749}," helpers",{"type":21,"tag":210,"props":751,"children":752},{"style":243},[753],{"type":26,"value":754},":",{"type":21,"tag":210,"props":756,"children":757},{"style":254},[758],{"type":26,"value":759},"show",{"type":21,"tag":210,"props":761,"children":762},{"style":243},[763],{"type":26,"value":262},{"type":21,"tag":210,"props":765,"children":766},{"style":265},[767],{"type":26,"value":768},"\"Caffeine Enabled\"",{"type":21,"tag":210,"props":770,"children":771},{"style":243},[772],{"type":26,"value":654},{"type":21,"tag":210,"props":774,"children":775},{"style":254},[776],{"type":26,"value":777},"nil",{"type":21,"tag":210,"props":779,"children":780},{"style":243},[781],{"type":26,"value":782},", helpers.",{"type":21,"tag":210,"props":784,"children":785},{"style":293},[786],{"type":26,"value":787},"styles",{"type":21,"tag":210,"props":789,"children":790},{"style":243},[791],{"type":26,"value":66},{"type":21,"tag":210,"props":793,"children":794},{"style":293},[795],{"type":26,"value":796},"success",{"type":21,"tag":210,"props":798,"children":799},{"style":243},[800],{"type":26,"value":782},{"type":21,"tag":210,"props":802,"children":803},{"style":293},[804],{"type":26,"value":805},"assets",{"type":21,"tag":210,"props":807,"children":808},{"style":243},[809],{"type":26,"value":66},{"type":21,"tag":210,"props":811,"children":812},{"style":293},[813],{"type":26,"value":814},"check",{"type":21,"tag":210,"props":816,"children":817},{"style":243},[818],{"type":26,"value":273},{"type":21,"tag":210,"props":820,"children":821},{"class":212,"line":284},[822],{"type":21,"tag":210,"props":823,"children":824},{"style":237},[825],{"type":26,"value":826}," else\n",{"type":21,"tag":210,"props":828,"children":829},{"class":212,"line":352},[830,834,838,842,846,851,855,859,863,867,871,876,880,884,888,893],{"type":21,"tag":210,"props":831,"children":832},{"style":293},[833],{"type":26,"value":749},{"type":21,"tag":210,"props":835,"children":836},{"style":243},[837],{"type":26,"value":754},{"type":21,"tag":210,"props":839,"children":840},{"style":254},[841],{"type":26,"value":759},{"type":21,"tag":210,"props":843,"children":844},{"style":243},[845],{"type":26,"value":262},{"type":21,"tag":210,"props":847,"children":848},{"style":265},[849],{"type":26,"value":850},"\"Caffeine Disabled\"",{"type":21,"tag":210,"props":852,"children":853},{"style":243},[854],{"type":26,"value":654},{"type":21,"tag":210,"props":856,"children":857},{"style":254},[858],{"type":26,"value":777},{"type":21,"tag":210,"props":860,"children":861},{"style":243},[862],{"type":26,"value":782},{"type":21,"tag":210,"props":864,"children":865},{"style":293},[866],{"type":26,"value":787},{"type":21,"tag":210,"props":868,"children":869},{"style":243},[870],{"type":26,"value":66},{"type":21,"tag":210,"props":872,"children":873},{"style":293},[874],{"type":26,"value":875},"error",{"type":21,"tag":210,"props":877,"children":878},{"style":243},[879],{"type":26,"value":782},{"type":21,"tag":210,"props":881,"children":882},{"style":293},[883],{"type":26,"value":805},{"type":21,"tag":210,"props":885,"children":886},{"style":243},[887],{"type":26,"value":66},{"type":21,"tag":210,"props":889,"children":890},{"style":293},[891],{"type":26,"value":892},"ban",{"type":21,"tag":210,"props":894,"children":895},{"style":243},[896],{"type":26,"value":273},{"type":21,"tag":210,"props":898,"children":899},{"class":212,"line":360},[900],{"type":21,"tag":210,"props":901,"children":902},{"style":237},[903],{"type":26,"value":904}," end\n",{"type":21,"tag":210,"props":906,"children":907},{"class":212,"line":402},[908,913],{"type":21,"tag":210,"props":909,"children":910},{"style":237},[911],{"type":26,"value":912},"end",{"type":21,"tag":210,"props":914,"children":915},{"style":243},[916],{"type":26,"value":273},{"type":21,"tag":200,"props":918,"children":920},{"className":538,"code":919,"language":12,"meta":7,"style":7},"(hs.hotkey.bind HYPER :0\n (fn [] (hs.caffeinate.toggle :displayIdle)\n (if (hs.caffeinate.get :displayIdle)\n (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban)))) \n",[921],{"type":21,"tag":109,"props":922,"children":923},{"__ignoreMap":7},[924,937,954,980,1011],{"type":21,"tag":210,"props":925,"children":926},{"class":212,"line":213},[927,932],{"type":21,"tag":210,"props":928,"children":929},{"style":243},[930],{"type":26,"value":931},"(hs.hotkey.bind HYPER ",{"type":21,"tag":210,"props":933,"children":934},{"style":293},[935],{"type":26,"value":936},":0\n",{"type":21,"tag":210,"props":938,"children":939},{"class":212,"line":223},[940,945,950],{"type":21,"tag":210,"props":941,"children":942},{"style":243},[943],{"type":26,"value":944}," (fn [] (hs.caffeinate.toggle ",{"type":21,"tag":210,"props":946,"children":947},{"style":293},[948],{"type":26,"value":949},":displayIdle",{"type":21,"tag":210,"props":951,"children":952},{"style":243},[953],{"type":26,"value":273},{"type":21,"tag":210,"props":955,"children":956},{"class":212,"line":233},[957,962,967,972,976],{"type":21,"tag":210,"props":958,"children":959},{"style":243},[960],{"type":26,"value":961}," (",{"type":21,"tag":210,"props":963,"children":964},{"style":237},[965],{"type":26,"value":966},"if",{"type":21,"tag":210,"props":968,"children":969},{"style":243},[970],{"type":26,"value":971}," (hs.caffeinate.get ",{"type":21,"tag":210,"props":973,"children":974},{"style":293},[975],{"type":26,"value":949},{"type":21,"tag":210,"props":977,"children":978},{"style":243},[979],{"type":26,"value":273},{"type":21,"tag":210,"props":981,"children":982},{"class":212,"line":276},[983,988,992,997,1001,1006],{"type":21,"tag":210,"props":984,"children":985},{"style":243},[986],{"type":26,"value":987}," (",{"type":21,"tag":210,"props":989,"children":990},{"style":254},[991],{"type":26,"value":455},{"type":21,"tag":210,"props":993,"children":994},{"style":243},[995],{"type":26,"value":996},":show ",{"type":21,"tag":210,"props":998,"children":999},{"style":265},[1000],{"type":26,"value":768},{"type":21,"tag":210,"props":1002,"children":1003},{"style":254},[1004],{"type":26,"value":1005}," nil",{"type":21,"tag":210,"props":1007,"children":1008},{"style":243},[1009],{"type":26,"value":1010}," helpers.styles.success helpers.assets.check)\n",{"type":21,"tag":210,"props":1012,"children":1013},{"class":212,"line":284},[1014,1018,1022,1026,1030,1034],{"type":21,"tag":210,"props":1015,"children":1016},{"style":243},[1017],{"type":26,"value":987},{"type":21,"tag":210,"props":1019,"children":1020},{"style":254},[1021],{"type":26,"value":455},{"type":21,"tag":210,"props":1023,"children":1024},{"style":243},[1025],{"type":26,"value":996},{"type":21,"tag":210,"props":1027,"children":1028},{"style":265},[1029],{"type":26,"value":850},{"type":21,"tag":210,"props":1031,"children":1032},{"style":254},[1033],{"type":26,"value":1005},{"type":21,"tag":210,"props":1035,"children":1036},{"style":243},[1037],{"type":26,"value":1038}," helpers.styles.error helpers.assets.ban))))\n",{"type":21,"tag":22,"props":1040,"children":1041},{},[1042,1044,1050],{"type":26,"value":1043},"This was especially helpful for more gnarly modules like the ",{"type":21,"tag":109,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":26,"value":1049},"window",{"type":26,"value":1051}," module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!",{"type":21,"tag":68,"props":1053,"children":1055},{"id":1054},"next-steps",[1056],{"type":26,"value":1057},"Next Steps",{"type":21,"tag":22,"props":1059,"children":1060},{},[1061],{"type":26,"value":1062},"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language.",{"type":21,"tag":22,"props":1064,"children":1065},{},[1066,1068,1075],{"type":26,"value":1067},"Additionally, before beginning this endeavor, I was already aware of projects like\n",{"type":21,"tag":39,"props":1069,"children":1072},{"href":1070,"rel":1071},"https://github.com/agzam/spacehammer",[43],[1073],{"type":26,"value":1074},"spacehammer",{"type":26,"value":1076},"; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own.",{"type":21,"tag":22,"props":1078,"children":1079},{},[1080,1082],{"type":26,"value":1081},"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: ",{"type":21,"tag":39,"props":1083,"children":1086},{"href":1084,"rel":1085},"https://github.com/cmpadden/dotfiles/pull/19/files",[43],[1087],{"type":26,"value":1084},{"type":21,"tag":1089,"props":1090,"children":1091},"style",{},[1092],{"type":26,"value":1093},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":223,"depth":223,"links":1095},[1096,1097,1098,1099],{"id":70,"depth":223,"text":73},{"id":90,"depth":223,"text":93},{"id":424,"depth":223,"text":427},{"id":1054,"depth":223,"text":1057},"markdown","content:articles:fennel-initial-exploration.md","content","articles/fennel-initial-exploration.md","md",1718891181746] \ No newline at end of file +[{"data":1,"prerenderedAt":1106},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":15,"cover_image":16,"excerpt":17,"body":27,"_type":1100,"_id":1101,"_source":1102,"_file":1103,"_stem":1104,"_extension":1105},"/articles/fennel-initial-exploration","articles",false,"","Impressions of Fennel with Hammerspoon","A while back I read an introductory book on Lisp programming titled, \"The Little\nSchemer\". This book opened my mind to new (to me) programming paradigms, and left me\nwith a strong desire to find a way to incorporate Lisp programming into my every day\nlife. It took some time, but I believe I've found what I've been looking for: Fennel.","2023-10-22",[12,13,14],"lisp","hammerspoon","fennel",[12],"/images/dall-e-fennel-hammer.jpeg",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25],{"type":26,"value":9},"text",{"type":18,"children":28,"toc":1094},[29,33,67,74,88,94,125,157,170,199,422,428,458,536,598,611,917,1039,1052,1058,1063,1077,1088],{"type":21,"tag":22,"props":30,"children":31},{},[32],{"type":26,"value":9},{"type":21,"tag":22,"props":34,"children":35},{},[36,38,47,49,56,58,65],{"type":26,"value":37},"The ",{"type":21,"tag":39,"props":40,"children":44},"a",{"href":41,"rel":42},"https://fennel-lang.org/",[43],"nofollow",[45],{"type":26,"value":46},"Fennel",{"type":26,"value":48}," programming language is a dialect of Lisp that boasts compatibility with\nLua, and it just so happens that two of my favorite applications are configured with\nexactly that language: ",{"type":21,"tag":39,"props":50,"children":53},{"href":51,"rel":52},"https://www.hammerspoon.org/",[43],[54],{"type":26,"value":55},"Hammerspoon",{"type":26,"value":57},", and ",{"type":21,"tag":39,"props":59,"children":62},{"href":60,"rel":61},"https://neovim.io/",[43],[63],{"type":26,"value":64},"Neovim",{"type":26,"value":66},".",{"type":21,"tag":68,"props":69,"children":71},"h2",{"id":70},"initial-observations",[72],{"type":26,"value":73},"Initial Observations",{"type":21,"tag":22,"props":75,"children":76},{},[77,79,86],{"type":26,"value":78},"To initially explore Fennel, I wanted to start small. My Hammerspoon configuration\nconsists of 7 ",{"type":21,"tag":39,"props":80,"children":83},{"href":81,"rel":82},"https://github.com/cmpadden/dotfiles/tree/795749fa17e1310bb001bb7deaa22be8689f0027/hammerspoon/.hammerspoon/modules",[43],[84],{"type":26,"value":85},"modules",{"type":26,"value":87}," that I use for operations such as: launching applications,\nmanaging windows, keeping my computer from going to sleep, and general operating system\nautomation. So the plan is to translate these modules into Fennel, while maintaining\nwithout breaking the existing functionality. However, at this point, I wasn't even sure\nhow to embed Fennel into my project...",{"type":21,"tag":68,"props":89,"children":91},{"id":90},"integrating-fennel-with-hammerspoon",[92],{"type":26,"value":93},"Integrating Fennel with Hammerspoon",{"type":21,"tag":22,"props":95,"children":96},{},[97,99,106,108,115,117,123],{"type":26,"value":98},"While official documentation exists describing how to ",{"type":21,"tag":39,"props":100,"children":103},{"href":101,"rel":102},"https://fennel-lang.org/setup#embedding-fennel",[43],[104],{"type":26,"value":105},"embed fennel",{"type":26,"value":107}," into your\nproject; it didn't provide me with enough clarity to know my next steps on integrating\nit with Hammerspoon. I found a few resources online demonstrating how to extend the\n",{"type":21,"tag":109,"props":110,"children":112},"code",{"className":111},[],[113],{"type":26,"value":114},"package.path",{"type":26,"value":116}," and ",{"type":21,"tag":109,"props":118,"children":120},{"className":119},[],[121],{"type":26,"value":122},"package.cpath",{"type":26,"value":124}," properties in Lua, but I was unable to get this to\nwork.",{"type":21,"tag":126,"props":127,"children":128},"ul",{},[129,139,148],{"type":21,"tag":130,"props":131,"children":132},"li",{},[133],{"type":21,"tag":39,"props":134,"children":137},{"href":135,"rel":136},"https://blog.exupero.org/hammerspoon-with-fennel/",[43],[138],{"type":26,"value":135},{"type":21,"tag":130,"props":140,"children":141},{},[142],{"type":21,"tag":39,"props":143,"children":146},{"href":144,"rel":145},"https://github.com/Hammerspoon/hammerspoon/issues/2377#issuecomment-636331435",[43],[147],{"type":26,"value":144},{"type":21,"tag":130,"props":149,"children":150},{},[151],{"type":21,"tag":39,"props":152,"children":155},{"href":153,"rel":154},"https://github.com/agzam/spacehammer/blob/master/init.lua",[43],[156],{"type":26,"value":153},{"type":21,"tag":22,"props":158,"children":159},{},[160,162,168],{"type":26,"value":161},"Ultimately, I opted to include the ",{"type":21,"tag":109,"props":163,"children":165},{"className":164},[],[166],{"type":26,"value":167},"fennel.lua",{"type":26,"value":169}," file to my Hammerspoon configuration,\nand while not ideal, it does make the configuration nicely self-contained. I'll leave it\nas a future task to include the module installed with LuaRocks.",{"type":21,"tag":22,"props":171,"children":172},{},[173,175,181,183,189,191,197],{"type":26,"value":174},"With Fennel now included in my Hammerspoon configuration, all I need to do is configure\nthe ",{"type":21,"tag":109,"props":176,"children":178},{"className":177},[],[179],{"type":26,"value":180},"fennel.path",{"type":26,"value":182}," to point to the ",{"type":21,"tag":109,"props":184,"children":186},{"className":185},[],[187],{"type":26,"value":188},"*.fnl",{"type":26,"value":190}," files in the ",{"type":21,"tag":109,"props":192,"children":194},{"className":193},[],[195],{"type":26,"value":196},".hammerspoon/",{"type":26,"value":198}," directory, and\nttranslating these modules can begin!",{"type":21,"tag":200,"props":201,"children":205},"pre",{"className":202,"code":203,"language":204,"meta":7,"style":7},"language-lua shiki shiki-themes github-light","-- init.lua\n\nlocal fennel = require('fennel')\n\nfennel.path = package.path .. \";\" .. os.getenv(\"HOME\") .. \"/.hammerspoon/?.fnl\"\n\ntable.insert(package.loaders or package.searchers, fennel.searcher)\n\nrequire 'main'\n","lua",[206],{"type":21,"tag":109,"props":207,"children":208},{"__ignoreMap":7},[209,221,231,274,282,350,358,400,408],{"type":21,"tag":210,"props":211,"children":214},"span",{"class":212,"line":213},"line",1,[215],{"type":21,"tag":210,"props":216,"children":218},{"style":217},"--shiki-default:#6A737D",[219],{"type":26,"value":220},"-- init.lua\n",{"type":21,"tag":210,"props":222,"children":224},{"class":212,"line":223},2,[225],{"type":21,"tag":210,"props":226,"children":228},{"emptyLinePlaceholder":227},true,[229],{"type":26,"value":230},"\n",{"type":21,"tag":210,"props":232,"children":234},{"class":212,"line":233},3,[235,241,247,252,258,263,269],{"type":21,"tag":210,"props":236,"children":238},{"style":237},"--shiki-default:#D73A49",[239],{"type":26,"value":240},"local",{"type":21,"tag":210,"props":242,"children":244},{"style":243},"--shiki-default:#24292E",[245],{"type":26,"value":246}," fennel ",{"type":21,"tag":210,"props":248,"children":249},{"style":237},[250],{"type":26,"value":251},"=",{"type":21,"tag":210,"props":253,"children":255},{"style":254},"--shiki-default:#005CC5",[256],{"type":26,"value":257}," require",{"type":21,"tag":210,"props":259,"children":260},{"style":243},[261],{"type":26,"value":262},"(",{"type":21,"tag":210,"props":264,"children":266},{"style":265},"--shiki-default:#032F62",[267],{"type":26,"value":268},"'fennel'",{"type":21,"tag":210,"props":270,"children":271},{"style":243},[272],{"type":26,"value":273},")\n",{"type":21,"tag":210,"props":275,"children":277},{"class":212,"line":276},4,[278],{"type":21,"tag":210,"props":279,"children":280},{"emptyLinePlaceholder":227},[281],{"type":26,"value":230},{"type":21,"tag":210,"props":283,"children":285},{"class":212,"line":284},5,[286,291,297,302,307,312,317,322,327,331,336,341,345],{"type":21,"tag":210,"props":287,"children":288},{"style":243},[289],{"type":26,"value":290},"fennel.",{"type":21,"tag":210,"props":292,"children":294},{"style":293},"--shiki-default:#6F42C1",[295],{"type":26,"value":296},"path",{"type":21,"tag":210,"props":298,"children":299},{"style":237},[300],{"type":26,"value":301}," =",{"type":21,"tag":210,"props":303,"children":304},{"style":254},[305],{"type":26,"value":306}," package.path",{"type":21,"tag":210,"props":308,"children":309},{"style":237},[310],{"type":26,"value":311}," ..",{"type":21,"tag":210,"props":313,"children":314},{"style":265},[315],{"type":26,"value":316}," \";\" ",{"type":21,"tag":210,"props":318,"children":319},{"style":237},[320],{"type":26,"value":321},"..",{"type":21,"tag":210,"props":323,"children":324},{"style":254},[325],{"type":26,"value":326}," os.getenv",{"type":21,"tag":210,"props":328,"children":329},{"style":243},[330],{"type":26,"value":262},{"type":21,"tag":210,"props":332,"children":333},{"style":265},[334],{"type":26,"value":335},"\"HOME\"",{"type":21,"tag":210,"props":337,"children":338},{"style":243},[339],{"type":26,"value":340},") ",{"type":21,"tag":210,"props":342,"children":343},{"style":237},[344],{"type":26,"value":321},{"type":21,"tag":210,"props":346,"children":347},{"style":265},[348],{"type":26,"value":349}," \"/.hammerspoon/?.fnl\"\n",{"type":21,"tag":210,"props":351,"children":353},{"class":212,"line":352},6,[354],{"type":21,"tag":210,"props":355,"children":356},{"emptyLinePlaceholder":227},[357],{"type":26,"value":230},{"type":21,"tag":210,"props":359,"children":361},{"class":212,"line":360},7,[362,367,371,376,381,386,391,396],{"type":21,"tag":210,"props":363,"children":364},{"style":254},[365],{"type":26,"value":366},"table.insert",{"type":21,"tag":210,"props":368,"children":369},{"style":243},[370],{"type":26,"value":262},{"type":21,"tag":210,"props":372,"children":373},{"style":254},[374],{"type":26,"value":375},"package.loaders",{"type":21,"tag":210,"props":377,"children":378},{"style":237},[379],{"type":26,"value":380}," or",{"type":21,"tag":210,"props":382,"children":383},{"style":254},[384],{"type":26,"value":385}," package.searchers",{"type":21,"tag":210,"props":387,"children":388},{"style":243},[389],{"type":26,"value":390},", fennel.",{"type":21,"tag":210,"props":392,"children":393},{"style":293},[394],{"type":26,"value":395},"searcher",{"type":21,"tag":210,"props":397,"children":398},{"style":243},[399],{"type":26,"value":273},{"type":21,"tag":210,"props":401,"children":403},{"class":212,"line":402},8,[404],{"type":21,"tag":210,"props":405,"children":406},{"emptyLinePlaceholder":227},[407],{"type":26,"value":230},{"type":21,"tag":210,"props":409,"children":411},{"class":212,"line":410},9,[412,417],{"type":21,"tag":210,"props":413,"children":414},{"style":254},[415],{"type":26,"value":416},"require",{"type":21,"tag":210,"props":418,"children":419},{"style":265},[420],{"type":26,"value":421}," 'main'\n",{"type":21,"tag":68,"props":423,"children":425},{"id":424},"translating-lua-to-fennel",[426],{"type":26,"value":427},"Translating Lua to Fennel",{"type":21,"tag":22,"props":429,"children":430},{},[431,433,440,442,448,450,456],{"type":26,"value":432},"As a Fennel novice, I was happy to see that the Fennel project provides an online\ncross-compiler for Lua and Fennel called ",{"type":21,"tag":39,"props":434,"children":437},{"href":435,"rel":436},"https://fennel-lang.org/see",[43],[438],{"type":26,"value":439},"anti-fennel",{"type":26,"value":441},", and while it can generate some\nstrange-looking Fennel code, it was an extremely useful tool for me to get\nup-and-running right away. For example, by pasting the simple ",{"type":21,"tag":109,"props":443,"children":445},{"className":444},[],[446],{"type":26,"value":447},"sleep",{"type":26,"value":449}," function\nfrom the ",{"type":21,"tag":109,"props":451,"children":453},{"className":452},[],[454],{"type":26,"value":455},"helpers",{"type":26,"value":457}," module into the compiler:",{"type":21,"tag":200,"props":459,"children":461},{"className":202,"code":460,"language":204,"meta":7,"style":7},"function sleep(ms)\n os.execute(\"sleep \" .. tonumber(ms) / 1000)\nend\n",[462],{"type":21,"tag":109,"props":463,"children":464},{"__ignoreMap":7},[465,483,528],{"type":21,"tag":210,"props":466,"children":467},{"class":212,"line":213},[468,473,478],{"type":21,"tag":210,"props":469,"children":470},{"style":237},[471],{"type":26,"value":472},"function",{"type":21,"tag":210,"props":474,"children":475},{"style":293},[476],{"type":26,"value":477}," sleep",{"type":21,"tag":210,"props":479,"children":480},{"style":243},[481],{"type":26,"value":482},"(ms)\n",{"type":21,"tag":210,"props":484,"children":485},{"class":212,"line":223},[486,491,495,500,504,509,514,519,524],{"type":21,"tag":210,"props":487,"children":488},{"style":254},[489],{"type":26,"value":490}," os.execute",{"type":21,"tag":210,"props":492,"children":493},{"style":243},[494],{"type":26,"value":262},{"type":21,"tag":210,"props":496,"children":497},{"style":265},[498],{"type":26,"value":499},"\"sleep \" ",{"type":21,"tag":210,"props":501,"children":502},{"style":237},[503],{"type":26,"value":321},{"type":21,"tag":210,"props":505,"children":506},{"style":254},[507],{"type":26,"value":508}," tonumber",{"type":21,"tag":210,"props":510,"children":511},{"style":243},[512],{"type":26,"value":513},"(ms) ",{"type":21,"tag":210,"props":515,"children":516},{"style":237},[517],{"type":26,"value":518},"/",{"type":21,"tag":210,"props":520,"children":521},{"style":254},[522],{"type":26,"value":523}," 1000",{"type":21,"tag":210,"props":525,"children":526},{"style":243},[527],{"type":26,"value":273},{"type":21,"tag":210,"props":529,"children":530},{"class":212,"line":233},[531],{"type":21,"tag":210,"props":532,"children":533},{"style":237},[534],{"type":26,"value":535},"end\n",{"type":21,"tag":200,"props":537,"children":540},{"className":538,"code":539,"language":12,"meta":7,"style":7},"language-lisp shiki shiki-themes github-light","(fn sleep [ms]\n (os.execute (.. \"sleep \" (/ (tonumber ms) 1000))))\n",[541],{"type":21,"tag":109,"props":542,"children":543},{"__ignoreMap":7},[544,561],{"type":21,"tag":210,"props":545,"children":546},{"class":212,"line":213},[547,552,556],{"type":21,"tag":210,"props":548,"children":549},{"style":243},[550],{"type":26,"value":551},"(fn ",{"type":21,"tag":210,"props":553,"children":554},{"style":254},[555],{"type":26,"value":447},{"type":21,"tag":210,"props":557,"children":558},{"style":243},[559],{"type":26,"value":560}," [ms]\n",{"type":21,"tag":210,"props":562,"children":563},{"class":212,"line":223},[564,569,574,579,583,588,593],{"type":21,"tag":210,"props":565,"children":566},{"style":243},[567],{"type":26,"value":568}," (os.execute (.. ",{"type":21,"tag":210,"props":570,"children":571},{"style":265},[572],{"type":26,"value":573},"\"sleep \"",{"type":21,"tag":210,"props":575,"children":576},{"style":243},[577],{"type":26,"value":578}," (",{"type":21,"tag":210,"props":580,"children":581},{"style":254},[582],{"type":26,"value":518},{"type":21,"tag":210,"props":584,"children":585},{"style":243},[586],{"type":26,"value":587}," (tonumber ms) ",{"type":21,"tag":210,"props":589,"children":590},{"style":254},[591],{"type":26,"value":592},"1000",{"type":21,"tag":210,"props":594,"children":595},{"style":243},[596],{"type":26,"value":597},"))))\n",{"type":21,"tag":22,"props":599,"children":600},{},[601,603,609],{"type":26,"value":602},"As another example, here is the output for my ",{"type":21,"tag":604,"props":605,"children":606},"em",{},[607],{"type":26,"value":608},"caffeine",{"type":26,"value":610}," toggle:",{"type":21,"tag":200,"props":612,"children":614},{"className":202,"code":613,"language":204,"meta":7,"style":7},"hs.hotkey.bind(HYPER, \"0\", function()\n hs.caffeinate.toggle(\"displayIdle\")\n if hs.caffeinate.get(\"displayIdle\") then\n helpers:show(\"Caffeine Enabled\", nil, helpers.styles.success, helpers.assets.check)\n else\n helpers:show(\"Caffeine Disabled\", nil, helpers.styles.error, helpers.assets.ban)\n end\nend)\n",[615],{"type":21,"tag":109,"props":616,"children":617},{"__ignoreMap":7},[618,664,699,742,819,827,897,905],{"type":21,"tag":210,"props":619,"children":620},{"class":212,"line":213},[621,626,631,635,640,645,650,655,659],{"type":21,"tag":210,"props":622,"children":623},{"style":243},[624],{"type":26,"value":625},"hs.",{"type":21,"tag":210,"props":627,"children":628},{"style":293},[629],{"type":26,"value":630},"hotkey",{"type":21,"tag":210,"props":632,"children":633},{"style":243},[634],{"type":26,"value":66},{"type":21,"tag":210,"props":636,"children":637},{"style":254},[638],{"type":26,"value":639},"bind",{"type":21,"tag":210,"props":641,"children":642},{"style":243},[643],{"type":26,"value":644},"(HYPER, ",{"type":21,"tag":210,"props":646,"children":647},{"style":265},[648],{"type":26,"value":649},"\"0\"",{"type":21,"tag":210,"props":651,"children":652},{"style":243},[653],{"type":26,"value":654},", ",{"type":21,"tag":210,"props":656,"children":657},{"style":237},[658],{"type":26,"value":472},{"type":21,"tag":210,"props":660,"children":661},{"style":243},[662],{"type":26,"value":663},"()\n",{"type":21,"tag":210,"props":665,"children":666},{"class":212,"line":223},[667,672,677,681,686,690,695],{"type":21,"tag":210,"props":668,"children":669},{"style":243},[670],{"type":26,"value":671}," hs.",{"type":21,"tag":210,"props":673,"children":674},{"style":293},[675],{"type":26,"value":676},"caffeinate",{"type":21,"tag":210,"props":678,"children":679},{"style":243},[680],{"type":26,"value":66},{"type":21,"tag":210,"props":682,"children":683},{"style":254},[684],{"type":26,"value":685},"toggle",{"type":21,"tag":210,"props":687,"children":688},{"style":243},[689],{"type":26,"value":262},{"type":21,"tag":210,"props":691,"children":692},{"style":265},[693],{"type":26,"value":694},"\"displayIdle\"",{"type":21,"tag":210,"props":696,"children":697},{"style":243},[698],{"type":26,"value":273},{"type":21,"tag":210,"props":700,"children":701},{"class":212,"line":233},[702,707,712,716,720,725,729,733,737],{"type":21,"tag":210,"props":703,"children":704},{"style":237},[705],{"type":26,"value":706}," if",{"type":21,"tag":210,"props":708,"children":709},{"style":243},[710],{"type":26,"value":711}," hs.",{"type":21,"tag":210,"props":713,"children":714},{"style":293},[715],{"type":26,"value":676},{"type":21,"tag":210,"props":717,"children":718},{"style":243},[719],{"type":26,"value":66},{"type":21,"tag":210,"props":721,"children":722},{"style":254},[723],{"type":26,"value":724},"get",{"type":21,"tag":210,"props":726,"children":727},{"style":243},[728],{"type":26,"value":262},{"type":21,"tag":210,"props":730,"children":731},{"style":265},[732],{"type":26,"value":694},{"type":21,"tag":210,"props":734,"children":735},{"style":243},[736],{"type":26,"value":340},{"type":21,"tag":210,"props":738,"children":739},{"style":237},[740],{"type":26,"value":741},"then\n",{"type":21,"tag":210,"props":743,"children":744},{"class":212,"line":276},[745,750,755,760,764,769,773,778,783,788,792,797,801,806,810,815],{"type":21,"tag":210,"props":746,"children":747},{"style":293},[748],{"type":26,"value":749}," helpers",{"type":21,"tag":210,"props":751,"children":752},{"style":243},[753],{"type":26,"value":754},":",{"type":21,"tag":210,"props":756,"children":757},{"style":254},[758],{"type":26,"value":759},"show",{"type":21,"tag":210,"props":761,"children":762},{"style":243},[763],{"type":26,"value":262},{"type":21,"tag":210,"props":765,"children":766},{"style":265},[767],{"type":26,"value":768},"\"Caffeine Enabled\"",{"type":21,"tag":210,"props":770,"children":771},{"style":243},[772],{"type":26,"value":654},{"type":21,"tag":210,"props":774,"children":775},{"style":254},[776],{"type":26,"value":777},"nil",{"type":21,"tag":210,"props":779,"children":780},{"style":243},[781],{"type":26,"value":782},", helpers.",{"type":21,"tag":210,"props":784,"children":785},{"style":293},[786],{"type":26,"value":787},"styles",{"type":21,"tag":210,"props":789,"children":790},{"style":243},[791],{"type":26,"value":66},{"type":21,"tag":210,"props":793,"children":794},{"style":293},[795],{"type":26,"value":796},"success",{"type":21,"tag":210,"props":798,"children":799},{"style":243},[800],{"type":26,"value":782},{"type":21,"tag":210,"props":802,"children":803},{"style":293},[804],{"type":26,"value":805},"assets",{"type":21,"tag":210,"props":807,"children":808},{"style":243},[809],{"type":26,"value":66},{"type":21,"tag":210,"props":811,"children":812},{"style":293},[813],{"type":26,"value":814},"check",{"type":21,"tag":210,"props":816,"children":817},{"style":243},[818],{"type":26,"value":273},{"type":21,"tag":210,"props":820,"children":821},{"class":212,"line":284},[822],{"type":21,"tag":210,"props":823,"children":824},{"style":237},[825],{"type":26,"value":826}," else\n",{"type":21,"tag":210,"props":828,"children":829},{"class":212,"line":352},[830,834,838,842,846,851,855,859,863,867,871,876,880,884,888,893],{"type":21,"tag":210,"props":831,"children":832},{"style":293},[833],{"type":26,"value":749},{"type":21,"tag":210,"props":835,"children":836},{"style":243},[837],{"type":26,"value":754},{"type":21,"tag":210,"props":839,"children":840},{"style":254},[841],{"type":26,"value":759},{"type":21,"tag":210,"props":843,"children":844},{"style":243},[845],{"type":26,"value":262},{"type":21,"tag":210,"props":847,"children":848},{"style":265},[849],{"type":26,"value":850},"\"Caffeine Disabled\"",{"type":21,"tag":210,"props":852,"children":853},{"style":243},[854],{"type":26,"value":654},{"type":21,"tag":210,"props":856,"children":857},{"style":254},[858],{"type":26,"value":777},{"type":21,"tag":210,"props":860,"children":861},{"style":243},[862],{"type":26,"value":782},{"type":21,"tag":210,"props":864,"children":865},{"style":293},[866],{"type":26,"value":787},{"type":21,"tag":210,"props":868,"children":869},{"style":243},[870],{"type":26,"value":66},{"type":21,"tag":210,"props":872,"children":873},{"style":293},[874],{"type":26,"value":875},"error",{"type":21,"tag":210,"props":877,"children":878},{"style":243},[879],{"type":26,"value":782},{"type":21,"tag":210,"props":881,"children":882},{"style":293},[883],{"type":26,"value":805},{"type":21,"tag":210,"props":885,"children":886},{"style":243},[887],{"type":26,"value":66},{"type":21,"tag":210,"props":889,"children":890},{"style":293},[891],{"type":26,"value":892},"ban",{"type":21,"tag":210,"props":894,"children":895},{"style":243},[896],{"type":26,"value":273},{"type":21,"tag":210,"props":898,"children":899},{"class":212,"line":360},[900],{"type":21,"tag":210,"props":901,"children":902},{"style":237},[903],{"type":26,"value":904}," end\n",{"type":21,"tag":210,"props":906,"children":907},{"class":212,"line":402},[908,913],{"type":21,"tag":210,"props":909,"children":910},{"style":237},[911],{"type":26,"value":912},"end",{"type":21,"tag":210,"props":914,"children":915},{"style":243},[916],{"type":26,"value":273},{"type":21,"tag":200,"props":918,"children":920},{"className":538,"code":919,"language":12,"meta":7,"style":7},"(hs.hotkey.bind HYPER :0\n (fn [] (hs.caffeinate.toggle :displayIdle)\n (if (hs.caffeinate.get :displayIdle)\n (helpers:show \"Caffeine Enabled\" nil helpers.styles.success helpers.assets.check)\n (helpers:show \"Caffeine Disabled\" nil helpers.styles.error helpers.assets.ban)))) \n",[921],{"type":21,"tag":109,"props":922,"children":923},{"__ignoreMap":7},[924,937,954,980,1011],{"type":21,"tag":210,"props":925,"children":926},{"class":212,"line":213},[927,932],{"type":21,"tag":210,"props":928,"children":929},{"style":243},[930],{"type":26,"value":931},"(hs.hotkey.bind HYPER ",{"type":21,"tag":210,"props":933,"children":934},{"style":293},[935],{"type":26,"value":936},":0\n",{"type":21,"tag":210,"props":938,"children":939},{"class":212,"line":223},[940,945,950],{"type":21,"tag":210,"props":941,"children":942},{"style":243},[943],{"type":26,"value":944}," (fn [] (hs.caffeinate.toggle ",{"type":21,"tag":210,"props":946,"children":947},{"style":293},[948],{"type":26,"value":949},":displayIdle",{"type":21,"tag":210,"props":951,"children":952},{"style":243},[953],{"type":26,"value":273},{"type":21,"tag":210,"props":955,"children":956},{"class":212,"line":233},[957,962,967,972,976],{"type":21,"tag":210,"props":958,"children":959},{"style":243},[960],{"type":26,"value":961}," (",{"type":21,"tag":210,"props":963,"children":964},{"style":237},[965],{"type":26,"value":966},"if",{"type":21,"tag":210,"props":968,"children":969},{"style":243},[970],{"type":26,"value":971}," (hs.caffeinate.get ",{"type":21,"tag":210,"props":973,"children":974},{"style":293},[975],{"type":26,"value":949},{"type":21,"tag":210,"props":977,"children":978},{"style":243},[979],{"type":26,"value":273},{"type":21,"tag":210,"props":981,"children":982},{"class":212,"line":276},[983,988,992,997,1001,1006],{"type":21,"tag":210,"props":984,"children":985},{"style":243},[986],{"type":26,"value":987}," (",{"type":21,"tag":210,"props":989,"children":990},{"style":254},[991],{"type":26,"value":455},{"type":21,"tag":210,"props":993,"children":994},{"style":243},[995],{"type":26,"value":996},":show ",{"type":21,"tag":210,"props":998,"children":999},{"style":265},[1000],{"type":26,"value":768},{"type":21,"tag":210,"props":1002,"children":1003},{"style":254},[1004],{"type":26,"value":1005}," nil",{"type":21,"tag":210,"props":1007,"children":1008},{"style":243},[1009],{"type":26,"value":1010}," helpers.styles.success helpers.assets.check)\n",{"type":21,"tag":210,"props":1012,"children":1013},{"class":212,"line":284},[1014,1018,1022,1026,1030,1034],{"type":21,"tag":210,"props":1015,"children":1016},{"style":243},[1017],{"type":26,"value":987},{"type":21,"tag":210,"props":1019,"children":1020},{"style":254},[1021],{"type":26,"value":455},{"type":21,"tag":210,"props":1023,"children":1024},{"style":243},[1025],{"type":26,"value":996},{"type":21,"tag":210,"props":1027,"children":1028},{"style":265},[1029],{"type":26,"value":850},{"type":21,"tag":210,"props":1031,"children":1032},{"style":254},[1033],{"type":26,"value":1005},{"type":21,"tag":210,"props":1035,"children":1036},{"style":243},[1037],{"type":26,"value":1038}," helpers.styles.error helpers.assets.ban))))\n",{"type":21,"tag":22,"props":1040,"children":1041},{},[1042,1044,1050],{"type":26,"value":1043},"This was especially helpful for more gnarly modules like the ",{"type":21,"tag":109,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":26,"value":1049},"window",{"type":26,"value":1051}," module used for\nwindow management, and seeing the Lua and Fennel code side-by-side was a kick starter in\nlearning the language!",{"type":21,"tag":68,"props":1053,"children":1055},{"id":1054},"next-steps",[1056],{"type":26,"value":1057},"Next Steps",{"type":21,"tag":22,"props":1059,"children":1060},{},[1061],{"type":26,"value":1062},"While my Fennel Hammerspoon configuration now works with parity to its Lua counterpart,\nI have not yet added new features or modules. I look forward to writing new Fennel code,\nand deepen my understanding of Lisp and the Fennel programming language.",{"type":21,"tag":22,"props":1064,"children":1065},{},[1066,1068,1075],{"type":26,"value":1067},"Additionally, before beginning this endeavor, I was already aware of projects like\n",{"type":21,"tag":39,"props":1069,"children":1072},{"href":1070,"rel":1071},"https://github.com/agzam/spacehammer",[43],[1073],{"type":26,"value":1074},"spacehammer",{"type":26,"value":1076},"; a wildly impressive Hammerspoon configuration written in Fennel, but,\nI wanted to start small and learn the integration myself. However, with the basics out\nof the way, I hope to explore this project further, and seek lessons-learned for the\nconfiguration of my own.",{"type":21,"tag":22,"props":1078,"children":1079},{},[1080,1082],{"type":26,"value":1081},"The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be\nfound here: ",{"type":21,"tag":39,"props":1083,"children":1086},{"href":1084,"rel":1085},"https://github.com/cmpadden/dotfiles/pull/19/files",[43],[1087],{"type":26,"value":1084},{"type":21,"tag":1089,"props":1090,"children":1091},"style",{},[1092],{"type":26,"value":1093},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":223,"depth":223,"links":1095},[1096,1097,1098,1099],{"id":70,"depth":223,"text":73},{"id":90,"depth":223,"text":93},{"id":424,"depth":223,"text":427},{"id":1054,"depth":223,"text":1057},"markdown","content:articles:fennel-initial-exploration.md","content","articles/fennel-initial-exploration.md","articles/fennel-initial-exploration","md",1720229315492] \ No newline at end of file diff --git a/articles/fennel-initial-exploration/index.html b/articles/fennel-initial-exploration/index.html index 5055e30d..bd611eef 100644 --- a/articles/fennel-initial-exploration/index.html +++ b/articles/fennel-initial-exploration/index.html @@ -4,35 +4,36 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - - - - -

            Impressions of Fennel with Hammerspoon

            2023-10-22

            A while back I read an introductory book on Lisp programming titled, "The Little + + + + + + + + + + + + + + + + +

            Impressions of Fennel with Hammerspoon

            A while back I read an introductory book on Lisp programming titled, "The Little Schemer". This book opened my mind to new (to me) programming paradigms, and left me with a strong desire to find a way to incorporate Lisp programming into my every day life. It took some time, but I believe I've found what I've been looking for: Fennel.

            The Fennel programming language is a dialect of Lisp that boasts compatibility with @@ -90,5 +91,5 @@ I wanted to start small and learn the integration myself. However, with the basics out of the way, I hope to explore this project further, and seek lessons-learned for the configuration of my own.

            The full pull-request for translating my Lua Hammerspoon configuration to Fennel can be -found here: https://github.com/cmpadden/dotfiles/pull/19/files

            - \ No newline at end of file +found here: https://github.com/cmpadden/dotfiles/pull/19/files

            + \ No newline at end of file diff --git a/articles/index.html b/articles/index.html index 303be344..0e34de0d 100644 --- a/articles/index.html +++ b/articles/index.html @@ -4,44 +4,46 @@ - - - - - - + + + + + + - + + - - - - - - - - - -

            YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the "new" ed25519-sk key type that supports FIDO compliant hardware keys.

            unix
            configurations

            In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.

            vim
            tip

            If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.

            whisper.cpp
            ml

            If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.

            nuxt
            rss

            A while back I read an introductory book on Lisp programming titled, "The Little + + + + + + + + + + +

            YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the "new" ed25519-sk key type that supports FIDO compliant hardware keys.

            In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.

            If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.

            If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.

            A while back I read an introductory book on Lisp programming titled, "The Little Schemer". This book opened my mind to new (to me) programming paradigms, and left me with a strong desire to find a way to incorporate Lisp programming into my every day -life. It took some time, but I believe I've found what I've been looking for: Fennel.

            lisp
            hammerspoon
            fennel

            I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility. -This proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.

            linux
            digital-ocean

            This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years. -Not to mention, all of the great plugins in the Vue ecosystem!

            nuxt

            TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.

            homelab
            supermicro
            truenas

            If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these +life. It took some time, but I believe I've found what I've been looking for: Fennel.

            I recently had the need to spool up a small ephemeral Linux instance, and wanted to try something new by exploring the Digital Ocean doctl command line utility. +This proved to be an extremely easy way to configure, create, connect, and destroy a Linux box, and I foresee myself using this service even more in the future.

            This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years. +Not to mention, all of the great plugins in the Vue ecosystem!

            TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.

            If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these instructions will guide your through the process of resetting the credentials to their default values from the host -operating system.

            homelab
            supermicro
            truenas

            Do you ever find yourself having to re-run a Bash command? I often find this +operating system.

            Do you ever find yourself having to re-run a Bash command? I often find this happening to myself when I neglect to use sudo for a command that requires -root privileges.

            tip
            bash

            Unit testing code for embedded systems can be challenging. While it's possible +root privileges.

            Unit testing code for embedded systems can be challenging. While it's possible to leverage emulators, write side-effect free code, or run tests on the hardware itself, it's often easiest to unit test the code on your personal -computer with mocked hardware functionality.

            micropython
            testing
            mocks
            tutorial

            When installing a linux distribution, it is common for the instructions to have +computer with mocked hardware functionality.

            When installing a linux distribution, it is common for the instructions to have the user create a bootable USB, boot from the device, and proceed with the installation procedure from that live medium. However, this blog post will outline an alternative approach where a virtual machine created with Vagrant -will be used in favor of the live medium.

            vagrant
            archlinux

            Unfamiliar with running Docker on a SELinux enabled system, I found myself -running into a bunch of file permission errors while creating volumes.

            docker
            selinux

            I've had a PCEngines APU2 gathering dust for a +will be used in favor of the live medium.

            Unfamiliar with running Docker on a SELinux enabled system, I found myself +running into a bunch of file permission errors while creating volumes.

            I've had a PCEngines APU2 gathering dust for a few years, and have recently decided to dust it off.

            Since the last time the device has been powered on, there have been many great improvements to the firmware, and it was very-much due for an upgrade. The following steps outline how the firmware was upgraded on the APU from the -already-installed operating system -- CentOS.

            pcengine
            apu

            Tags

            apu
            archlinux
            bash
            configurations
            digital-ocean
            docker
            fennel
            hammerspoon
            homelab
            linux
            lisp
            micropython
            ml
            mocks
            nuxt
            pcengine
            rss
            selinux
            supermicro
            testing
            tip
            truenas
            tutorial
            unix
            vagrant
            vim
            whisper.cpp
            - \ No newline at end of file +already-installed operating system -- CentOS.

            Tags

            apu
            archlinux
            bash
            configurations
            digital-ocean
            docker
            fennel
            hammerspoon
            homelab
            linux
            lisp
            micropython
            ml
            mocks
            nuxt
            pcengine
            rss
            selinux
            supermicro
            testing
            tip
            truenas
            tutorial
            unix
            vagrant
            vim
            whisper.cpp
            + \ No newline at end of file diff --git a/articles/migrate-truenas-from-core-to-scale/_payload.json b/articles/migrate-truenas-from-core-to-scale/_payload.json index 8533e3ea..bab18f8b 100644 --- a/articles/migrate-truenas-from-core-to-scale/_payload.json +++ b/articles/migrate-truenas-from-core-to-scale/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":204},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":15,"excerpt":16,"body":26,"_type":199,"_id":200,"_source":201,"_file":202,"_extension":203},"/articles/migrate-truenas-from-core-to-scale","articles",false,"","Migrate to TrueNAS Scale from TrueNAS Core","TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","2021-12-28",[12,13,14],"homelab","supermicro","truenas",[12],{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":196},[28,32,45,175,180],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":21,"props":33,"children":34},{},[35,37,43],{"type":25,"value":36},"Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select ",{"type":20,"tag":38,"props":39,"children":40},"em",{},[41],{"type":25,"value":42},"Install/Upgrade",{"type":25,"value":44}," in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below.",{"type":20,"tag":46,"props":47,"children":48},"ol",{},[49,96,125,130,154,159],{"type":20,"tag":50,"props":51,"children":52},"li",{},[53,55],{"type":25,"value":54},"Make a backup of your system’s configuration\n",{"type":20,"tag":46,"props":56,"children":57},{},[58,70],{"type":20,"tag":50,"props":59,"children":60},{},[61,63],{"type":25,"value":62},"Navigate to ",{"type":20,"tag":64,"props":65,"children":67},"code",{"className":66},[],[68],{"type":25,"value":69},"System > General",{"type":20,"tag":50,"props":71,"children":72},{},[73,75,81,83,88,90],{"type":25,"value":74},"Click ",{"type":20,"tag":64,"props":76,"children":78},{"className":77},[],[79],{"type":25,"value":80},"Save Config",{"type":25,"value":82},", check the ",{"type":20,"tag":38,"props":84,"children":85},{},[86],{"type":25,"value":87},"Export Secret Seed",{"type":25,"value":89}," box, and click ",{"type":20,"tag":64,"props":91,"children":93},{"className":92},[],[94],{"type":25,"value":95},"Save",{"type":20,"tag":50,"props":97,"children":98},{},[99,101],{"type":25,"value":100},"Export dataset keys for the encrypted pools\n",{"type":20,"tag":46,"props":102,"children":103},{},[104,114],{"type":20,"tag":50,"props":105,"children":106},{},[107,108],{"type":25,"value":62},{"type":20,"tag":64,"props":109,"children":111},{"className":110},[],[112],{"type":25,"value":113},"Storage > Pools",{"type":20,"tag":50,"props":115,"children":116},{},[117,119],{"type":25,"value":118},"Click the cog icon, and select ",{"type":20,"tag":64,"props":120,"children":122},{"className":121},[],[123],{"type":25,"value":124},"Export Dataset Keys",{"type":20,"tag":50,"props":126,"children":127},{},[128],{"type":25,"value":129},"Insert the TrueNAS Core bootable USB into the NAS",{"type":20,"tag":50,"props":131,"children":132},{},[133,135,140,142,147,149],{"type":25,"value":134},"From the Supermicro IPMI interface select ",{"type":20,"tag":38,"props":136,"children":137},{},[138],{"type":25,"value":139},"Remote Control",{"type":25,"value":141}," and ",{"type":20,"tag":38,"props":143,"children":144},{},[145],{"type":25,"value":146},"iKVM/HTML5",{"type":25,"value":148}," and select ",{"type":20,"tag":38,"props":150,"children":151},{},[152],{"type":25,"value":153},"Reboot",{"type":20,"tag":50,"props":155,"children":156},{},[157],{"type":25,"value":158},"Select the bootable USB as the boot device",{"type":20,"tag":50,"props":160,"children":161},{},[162,164,168,170],{"type":25,"value":163},"From the TrueNAS installation wizard, select ",{"type":20,"tag":38,"props":165,"children":166},{},[167],{"type":25,"value":42},{"type":25,"value":169},", select the drive that contains the TrueNAS installation, and select ",{"type":20,"tag":38,"props":171,"children":172},{},[173],{"type":25,"value":174},"Upgrade Install",{"type":20,"tag":21,"props":176,"children":177},{},[178],{"type":25,"value":179},"Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!",{"type":20,"tag":21,"props":181,"children":182},{},[183,185,194],{"type":25,"value":184},"For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference ",{"type":20,"tag":186,"props":187,"children":191},"a",{"href":188,"rel":189},"https://www.truenas.com/help-me-choose/",[190],"nofollow",[192],{"type":25,"value":193},"this table",{"type":25,"value":195},".",{"title":7,"searchDepth":197,"depth":197,"links":198},2,[],"markdown","content:articles:migrate-truenas-from-core-to-scale.md","content","articles/migrate-truenas-from-core-to-scale.md","md",1718891181761] \ No newline at end of file +[{"data":1,"prerenderedAt":205},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":15,"excerpt":16,"body":26,"_type":199,"_id":200,"_source":201,"_file":202,"_stem":203,"_extension":204},"/articles/migrate-truenas-from-core-to-scale","articles",false,"","Migrate to TrueNAS Scale from TrueNAS Core","TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.","2021-12-28",[12,13,14],"homelab","supermicro","truenas",[12],{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":196},[28,32,45,175,180],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":21,"props":33,"children":34},{},[35,37,43],{"type":25,"value":36},"Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select ",{"type":20,"tag":38,"props":39,"children":40},"em",{},[41],{"type":25,"value":42},"Install/Upgrade",{"type":25,"value":44}," in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below.",{"type":20,"tag":46,"props":47,"children":48},"ol",{},[49,96,125,130,154,159],{"type":20,"tag":50,"props":51,"children":52},"li",{},[53,55],{"type":25,"value":54},"Make a backup of your system’s configuration\n",{"type":20,"tag":46,"props":56,"children":57},{},[58,70],{"type":20,"tag":50,"props":59,"children":60},{},[61,63],{"type":25,"value":62},"Navigate to ",{"type":20,"tag":64,"props":65,"children":67},"code",{"className":66},[],[68],{"type":25,"value":69},"System > General",{"type":20,"tag":50,"props":71,"children":72},{},[73,75,81,83,88,90],{"type":25,"value":74},"Click ",{"type":20,"tag":64,"props":76,"children":78},{"className":77},[],[79],{"type":25,"value":80},"Save Config",{"type":25,"value":82},", check the ",{"type":20,"tag":38,"props":84,"children":85},{},[86],{"type":25,"value":87},"Export Secret Seed",{"type":25,"value":89}," box, and click ",{"type":20,"tag":64,"props":91,"children":93},{"className":92},[],[94],{"type":25,"value":95},"Save",{"type":20,"tag":50,"props":97,"children":98},{},[99,101],{"type":25,"value":100},"Export dataset keys for the encrypted pools\n",{"type":20,"tag":46,"props":102,"children":103},{},[104,114],{"type":20,"tag":50,"props":105,"children":106},{},[107,108],{"type":25,"value":62},{"type":20,"tag":64,"props":109,"children":111},{"className":110},[],[112],{"type":25,"value":113},"Storage > Pools",{"type":20,"tag":50,"props":115,"children":116},{},[117,119],{"type":25,"value":118},"Click the cog icon, and select ",{"type":20,"tag":64,"props":120,"children":122},{"className":121},[],[123],{"type":25,"value":124},"Export Dataset Keys",{"type":20,"tag":50,"props":126,"children":127},{},[128],{"type":25,"value":129},"Insert the TrueNAS Core bootable USB into the NAS",{"type":20,"tag":50,"props":131,"children":132},{},[133,135,140,142,147,149],{"type":25,"value":134},"From the Supermicro IPMI interface select ",{"type":20,"tag":38,"props":136,"children":137},{},[138],{"type":25,"value":139},"Remote Control",{"type":25,"value":141}," and ",{"type":20,"tag":38,"props":143,"children":144},{},[145],{"type":25,"value":146},"iKVM/HTML5",{"type":25,"value":148}," and select ",{"type":20,"tag":38,"props":150,"children":151},{},[152],{"type":25,"value":153},"Reboot",{"type":20,"tag":50,"props":155,"children":156},{},[157],{"type":25,"value":158},"Select the bootable USB as the boot device",{"type":20,"tag":50,"props":160,"children":161},{},[162,164,168,170],{"type":25,"value":163},"From the TrueNAS installation wizard, select ",{"type":20,"tag":38,"props":165,"children":166},{},[167],{"type":25,"value":42},{"type":25,"value":169},", select the drive that contains the TrueNAS installation, and select ",{"type":20,"tag":38,"props":171,"children":172},{},[173],{"type":25,"value":174},"Upgrade Install",{"type":20,"tag":21,"props":176,"children":177},{},[178],{"type":25,"value":179},"Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!",{"type":20,"tag":21,"props":181,"children":182},{},[183,185,194],{"type":25,"value":184},"For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference ",{"type":20,"tag":186,"props":187,"children":191},"a",{"href":188,"rel":189},"https://www.truenas.com/help-me-choose/",[190],"nofollow",[192],{"type":25,"value":193},"this table",{"type":25,"value":195},".",{"title":7,"searchDepth":197,"depth":197,"links":198},2,[],"markdown","content:articles:migrate-truenas-from-core-to-scale.md","content","articles/migrate-truenas-from-core-to-scale.md","articles/migrate-truenas-from-core-to-scale","md",1720229315495] \ No newline at end of file diff --git a/articles/migrate-truenas-from-core-to-scale/index.html b/articles/migrate-truenas-from-core-to-scale/index.html index 93fe41e1..0d881a9c 100644 --- a/articles/migrate-truenas-from-core-to-scale/index.html +++ b/articles/migrate-truenas-from-core-to-scale/index.html @@ -4,29 +4,30 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - -

            Migrate to TrueNAS Scale from TrueNAS Core

            2021-12-28

            TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.

            Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select Install/Upgrade in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below.

            1. Make a backup of your system’s configuration + + + + + + + + + + + + +

              Migrate to TrueNAS Scale from TrueNAS Core

              TrueNAS Scale offers a variety of interesting features that are not supported in its TrueNAS Core counterpart. Most notably, because the base operating system is Debian Linux, opposed to FreeBSD, there is native support for Linux containers via Docker, and Kubernetes Pods! This post walks through the steps required to upgrade from TrueNAS Core to TrueNAS Scale.

              Thankfully, the upgrade procedure to migrate from TrueNAS Core to TrueNAS Scale is relatively straight forward. All it requires is to create a bootable USB of the TrueNAS Scale image, boot the USB, and select Install/Upgrade in the installation wizard. But for the sake of being thorough, you can find instructions on how to backup system configurations and install the OS below.

              1. Make a backup of your system’s configuration
                1. Navigate to System > General
                2. Click Save Config, check the Export Secret Seed box, and click Save
              2. Export dataset keys for the encrypted pools -
                1. Navigate to Storage > Pools
                2. Click the cog icon, and select Export Dataset Keys
              3. Insert the TrueNAS Core bootable USB into the NAS
              4. From the Supermicro IPMI interface select Remote Control and iKVM/HTML5 and select Reboot
              5. Select the bootable USB as the boot device
              6. From the TrueNAS installation wizard, select Install/Upgrade, select the drive that contains the TrueNAS installation, and select Upgrade Install

              Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!

              For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference this table.

              - \ No newline at end of file +
              1. Navigate to Storage > Pools
              2. Click the cog icon, and select Export Dataset Keys
            2. Insert the TrueNAS Core bootable USB into the NAS
            3. From the Supermicro IPMI interface select Remote Control and iKVM/HTML5 and select Reboot
            4. Select the bootable USB as the boot device
            5. From the TrueNAS installation wizard, select Install/Upgrade, select the drive that contains the TrueNAS installation, and select Upgrade Install

            Reboot the device, and voila — you should be up-and-running! Give the system a quick rundown to validate that your settings and pools have transferred correctly, and then enjoy all the container goodness!

            For a breakdown of the differences between TrueNAS Core, Enterprise, and Scale, you can reference this table.

            + \ No newline at end of file diff --git a/articles/nuxt-content-rss-feed/_payload.json b/articles/nuxt-content-rss-feed/_payload.json index 9d12d425..af0dc4ba 100644 --- a/articles/nuxt-content-rss-feed/_payload.json +++ b/articles/nuxt-content-rss-feed/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":1791},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"cover_image":16,"excerpt":17,"body":39,"_type":1786,"_id":1787,"_source":1788,"_file":1789,"_extension":1790},"/articles/nuxt-content-rss-feed","articles",false,"","How To Add an RSS Feed to a Nuxt Website","If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","2024-01-06",[12,13],"nuxt","rss",[15],"programming","/images/nuxt-content-rss-feed.jpg",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,28,37],{"type":26,"value":27},"text","If you are a user of ",{"type":21,"tag":29,"props":30,"children":34},"a",{"href":31,"rel":32},"https://content.nuxt.com/",[33],"nofollow",[35],{"type":26,"value":36},"Nuxt Content",{"type":26,"value":38}," and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.",{"type":18,"children":40,"toc":1781},[41,51,58,81,87,101,141,162,197,1139,1176,1246,1252,1265,1270,1297,1309,1685,1703,1775],{"type":21,"tag":22,"props":42,"children":43},{},[44,45,50],{"type":26,"value":27},{"type":21,"tag":29,"props":46,"children":48},{"href":31,"rel":47},[33],[49],{"type":26,"value":36},{"type":26,"value":38},{"type":21,"tag":52,"props":53,"children":55},"h2",{"id":54},"preface",[56],{"type":26,"value":57},"Preface",{"type":21,"tag":22,"props":59,"children":60},{},[61,63,70,72,79],{"type":26,"value":62},"In version 2 of Nuxt, the community module, ",{"type":21,"tag":29,"props":64,"children":67},{"href":65,"rel":66},"https://github.com/nuxt-community/feed-module",[33],[68],{"type":26,"value":69},"nuxt-community/feed-module",{"type":26,"value":71}," was a popular choice for adding an RSS feed to your website. However, there has been an unresolved ",{"type":21,"tag":29,"props":73,"children":76},{"href":74,"rel":75},"https://github.com/nuxt-community/feed-module/issues/106",[33],[77],{"type":26,"value":78},"open issue",{"type":26,"value":80}," since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward.",{"type":21,"tag":52,"props":82,"children":84},{"id":83},"instructions",[85],{"type":26,"value":86},"Instructions",{"type":21,"tag":22,"props":88,"children":89},{},[90,92,99],{"type":26,"value":91},"First, install the ",{"type":21,"tag":29,"props":93,"children":96},{"href":94,"rel":95},"https://www.npmjs.com/package/feed",[33],[97],{"type":26,"value":98},"feed",{"type":26,"value":100}," library into your project:",{"type":21,"tag":102,"props":103,"children":107},"pre",{"className":104,"code":105,"language":106,"meta":7,"style":7},"language-shell shiki shiki-themes github-light","npm i -D feed\n","shell",[108],{"type":21,"tag":109,"props":110,"children":111},"code",{"__ignoreMap":7},[112],{"type":21,"tag":113,"props":114,"children":117},"span",{"class":115,"line":116},"line",1,[118,124,130,136],{"type":21,"tag":113,"props":119,"children":121},{"style":120},"--shiki-default:#6F42C1",[122],{"type":26,"value":123},"npm",{"type":21,"tag":113,"props":125,"children":127},{"style":126},"--shiki-default:#032F62",[128],{"type":26,"value":129}," i",{"type":21,"tag":113,"props":131,"children":133},{"style":132},"--shiki-default:#005CC5",[134],{"type":26,"value":135}," -D",{"type":21,"tag":113,"props":137,"children":138},{"style":126},[139],{"type":26,"value":140}," feed\n",{"type":21,"tag":22,"props":142,"children":143},{},[144,146,152,154,160],{"type":26,"value":145},"Then, create a ",{"type":21,"tag":109,"props":147,"children":149},{"className":148},[],[150],{"type":26,"value":151},"server/",{"type":26,"value":153}," folder in your project if it does not already exist, and create a file named ",{"type":21,"tag":109,"props":155,"children":157},{"className":156},[],[158],{"type":26,"value":159},"server/routes/atom.ts",{"type":26,"value":161},".",{"type":21,"tag":22,"props":163,"children":164},{},[165,167,172,174,179,181,187,189,195],{"type":26,"value":166},"Here, we will leverage the ",{"type":21,"tag":109,"props":168,"children":170},{"className":169},[],[171],{"type":26,"value":98},{"type":26,"value":173}," library and construct an XML representation of our Nuxt content. As you can see, we first define our ",{"type":21,"tag":109,"props":175,"children":177},{"className":176},[],[178],{"type":26,"value":98},{"type":26,"value":180}," with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with ",{"type":21,"tag":109,"props":182,"children":184},{"className":183},[],[185],{"type":26,"value":186},"serverQueryContent",{"type":26,"value":188}," and append a ",{"type":21,"tag":109,"props":190,"children":192},{"className":191},[],[193],{"type":26,"value":194},"feed.addItem",{"type":26,"value":196}," for each article.",{"type":21,"tag":102,"props":198,"children":202},{"className":199,"code":200,"language":201,"meta":7,"style":7},"language-ts shiki shiki-themes github-light","import { serverQueryContent } from '#content/server';\nimport { Feed } from 'feed';\n\nconst BASE_URL = \"https://mywebsite.com\"\nconst AUTHOR_NAME = \"Firstname Lastname\"\n\nexport default defineEventHandler(async (event) => {\n\n const feed = new Feed({\n title: \"My Title\",\n description: \"My Description\",\n id: BASE_URL,\n link: BASE_URL,\n language: \"en\",\n image: `${BASE_URL}/images/placeholder.png`,\n favicon: `${BASE_URL}/favicon.ico`,\n copyright: `All rights reserved ${new Date().getFullYear()}, ${AUTHOR_NAME}`,\n updated: new Date(),\n generator: \"Nuxt static site generation + Feed for Node.js\",\n feedLinks: {\n atom: `${BASE_URL}/atom`\n },\n author: {\n name: AUTHOR_NAME,\n }\n });\n\n const articles = await serverQueryContent(event).find();\n\n articles.forEach((article) => {\n feed.addItem({\n title: article.title ? article.title : \"Missing Title\",\n id: article._path,\n link: `${BASE_URL}${article._path}`,\n description: article.description,\n author: [\n {\n name: AUTHOR_NAME,\n },\n ],\n date: new Date(article.date),\n image: article.cover_image ? `${BASE_URL}/${article.cover_image}` : undefined\n });\n });\n\n return feed.atom1();\n});\n","ts",[203],{"type":21,"tag":109,"props":204,"children":205},{"__ignoreMap":7},[206,236,262,272,296,318,326,381,389,422,441,459,477,494,512,539,565,623,645,663,672,694,703,712,729,738,747,755,797,805,841,859,892,901,944,953,962,971,988,997,1006,1028,1082,1091,1099,1107,1130],{"type":21,"tag":113,"props":207,"children":208},{"class":115,"line":116},[209,215,221,226,231],{"type":21,"tag":113,"props":210,"children":212},{"style":211},"--shiki-default:#D73A49",[213],{"type":26,"value":214},"import",{"type":21,"tag":113,"props":216,"children":218},{"style":217},"--shiki-default:#24292E",[219],{"type":26,"value":220}," { serverQueryContent } ",{"type":21,"tag":113,"props":222,"children":223},{"style":211},[224],{"type":26,"value":225},"from",{"type":21,"tag":113,"props":227,"children":228},{"style":126},[229],{"type":26,"value":230}," '#content/server'",{"type":21,"tag":113,"props":232,"children":233},{"style":217},[234],{"type":26,"value":235},";\n",{"type":21,"tag":113,"props":237,"children":239},{"class":115,"line":238},2,[240,244,249,253,258],{"type":21,"tag":113,"props":241,"children":242},{"style":211},[243],{"type":26,"value":214},{"type":21,"tag":113,"props":245,"children":246},{"style":217},[247],{"type":26,"value":248}," { Feed } ",{"type":21,"tag":113,"props":250,"children":251},{"style":211},[252],{"type":26,"value":225},{"type":21,"tag":113,"props":254,"children":255},{"style":126},[256],{"type":26,"value":257}," 'feed'",{"type":21,"tag":113,"props":259,"children":260},{"style":217},[261],{"type":26,"value":235},{"type":21,"tag":113,"props":263,"children":265},{"class":115,"line":264},3,[266],{"type":21,"tag":113,"props":267,"children":269},{"emptyLinePlaceholder":268},true,[270],{"type":26,"value":271},"\n",{"type":21,"tag":113,"props":273,"children":275},{"class":115,"line":274},4,[276,281,286,291],{"type":21,"tag":113,"props":277,"children":278},{"style":211},[279],{"type":26,"value":280},"const",{"type":21,"tag":113,"props":282,"children":283},{"style":132},[284],{"type":26,"value":285}," BASE_URL",{"type":21,"tag":113,"props":287,"children":288},{"style":211},[289],{"type":26,"value":290}," =",{"type":21,"tag":113,"props":292,"children":293},{"style":126},[294],{"type":26,"value":295}," \"https://mywebsite.com\"\n",{"type":21,"tag":113,"props":297,"children":299},{"class":115,"line":298},5,[300,304,309,313],{"type":21,"tag":113,"props":301,"children":302},{"style":211},[303],{"type":26,"value":280},{"type":21,"tag":113,"props":305,"children":306},{"style":132},[307],{"type":26,"value":308}," AUTHOR_NAME",{"type":21,"tag":113,"props":310,"children":311},{"style":211},[312],{"type":26,"value":290},{"type":21,"tag":113,"props":314,"children":315},{"style":126},[316],{"type":26,"value":317}," \"Firstname Lastname\"\n",{"type":21,"tag":113,"props":319,"children":321},{"class":115,"line":320},6,[322],{"type":21,"tag":113,"props":323,"children":324},{"emptyLinePlaceholder":268},[325],{"type":26,"value":271},{"type":21,"tag":113,"props":327,"children":329},{"class":115,"line":328},7,[330,335,340,345,350,355,360,366,371,376],{"type":21,"tag":113,"props":331,"children":332},{"style":211},[333],{"type":26,"value":334},"export",{"type":21,"tag":113,"props":336,"children":337},{"style":211},[338],{"type":26,"value":339}," default",{"type":21,"tag":113,"props":341,"children":342},{"style":120},[343],{"type":26,"value":344}," defineEventHandler",{"type":21,"tag":113,"props":346,"children":347},{"style":217},[348],{"type":26,"value":349},"(",{"type":21,"tag":113,"props":351,"children":352},{"style":211},[353],{"type":26,"value":354},"async",{"type":21,"tag":113,"props":356,"children":357},{"style":217},[358],{"type":26,"value":359}," (",{"type":21,"tag":113,"props":361,"children":363},{"style":362},"--shiki-default:#E36209",[364],{"type":26,"value":365},"event",{"type":21,"tag":113,"props":367,"children":368},{"style":217},[369],{"type":26,"value":370},") ",{"type":21,"tag":113,"props":372,"children":373},{"style":211},[374],{"type":26,"value":375},"=>",{"type":21,"tag":113,"props":377,"children":378},{"style":217},[379],{"type":26,"value":380}," {\n",{"type":21,"tag":113,"props":382,"children":384},{"class":115,"line":383},8,[385],{"type":21,"tag":113,"props":386,"children":387},{"emptyLinePlaceholder":268},[388],{"type":26,"value":271},{"type":21,"tag":113,"props":390,"children":392},{"class":115,"line":391},9,[393,398,403,407,412,417],{"type":21,"tag":113,"props":394,"children":395},{"style":211},[396],{"type":26,"value":397}," const",{"type":21,"tag":113,"props":399,"children":400},{"style":132},[401],{"type":26,"value":402}," feed",{"type":21,"tag":113,"props":404,"children":405},{"style":211},[406],{"type":26,"value":290},{"type":21,"tag":113,"props":408,"children":409},{"style":211},[410],{"type":26,"value":411}," new",{"type":21,"tag":113,"props":413,"children":414},{"style":120},[415],{"type":26,"value":416}," Feed",{"type":21,"tag":113,"props":418,"children":419},{"style":217},[420],{"type":26,"value":421},"({\n",{"type":21,"tag":113,"props":423,"children":425},{"class":115,"line":424},10,[426,431,436],{"type":21,"tag":113,"props":427,"children":428},{"style":217},[429],{"type":26,"value":430}," title: ",{"type":21,"tag":113,"props":432,"children":433},{"style":126},[434],{"type":26,"value":435},"\"My Title\"",{"type":21,"tag":113,"props":437,"children":438},{"style":217},[439],{"type":26,"value":440},",\n",{"type":21,"tag":113,"props":442,"children":444},{"class":115,"line":443},11,[445,450,455],{"type":21,"tag":113,"props":446,"children":447},{"style":217},[448],{"type":26,"value":449}," description: ",{"type":21,"tag":113,"props":451,"children":452},{"style":126},[453],{"type":26,"value":454},"\"My Description\"",{"type":21,"tag":113,"props":456,"children":457},{"style":217},[458],{"type":26,"value":440},{"type":21,"tag":113,"props":460,"children":462},{"class":115,"line":461},12,[463,468,473],{"type":21,"tag":113,"props":464,"children":465},{"style":217},[466],{"type":26,"value":467}," id: ",{"type":21,"tag":113,"props":469,"children":470},{"style":132},[471],{"type":26,"value":472},"BASE_URL",{"type":21,"tag":113,"props":474,"children":475},{"style":217},[476],{"type":26,"value":440},{"type":21,"tag":113,"props":478,"children":480},{"class":115,"line":479},13,[481,486,490],{"type":21,"tag":113,"props":482,"children":483},{"style":217},[484],{"type":26,"value":485}," link: ",{"type":21,"tag":113,"props":487,"children":488},{"style":132},[489],{"type":26,"value":472},{"type":21,"tag":113,"props":491,"children":492},{"style":217},[493],{"type":26,"value":440},{"type":21,"tag":113,"props":495,"children":497},{"class":115,"line":496},14,[498,503,508],{"type":21,"tag":113,"props":499,"children":500},{"style":217},[501],{"type":26,"value":502}," language: ",{"type":21,"tag":113,"props":504,"children":505},{"style":126},[506],{"type":26,"value":507},"\"en\"",{"type":21,"tag":113,"props":509,"children":510},{"style":217},[511],{"type":26,"value":440},{"type":21,"tag":113,"props":513,"children":515},{"class":115,"line":514},15,[516,521,526,530,535],{"type":21,"tag":113,"props":517,"children":518},{"style":217},[519],{"type":26,"value":520}," image: ",{"type":21,"tag":113,"props":522,"children":523},{"style":126},[524],{"type":26,"value":525},"`${",{"type":21,"tag":113,"props":527,"children":528},{"style":132},[529],{"type":26,"value":472},{"type":21,"tag":113,"props":531,"children":532},{"style":126},[533],{"type":26,"value":534},"}/images/placeholder.png`",{"type":21,"tag":113,"props":536,"children":537},{"style":217},[538],{"type":26,"value":440},{"type":21,"tag":113,"props":540,"children":542},{"class":115,"line":541},16,[543,548,552,556,561],{"type":21,"tag":113,"props":544,"children":545},{"style":217},[546],{"type":26,"value":547}," favicon: ",{"type":21,"tag":113,"props":549,"children":550},{"style":126},[551],{"type":26,"value":525},{"type":21,"tag":113,"props":553,"children":554},{"style":132},[555],{"type":26,"value":472},{"type":21,"tag":113,"props":557,"children":558},{"style":126},[559],{"type":26,"value":560},"}/favicon.ico`",{"type":21,"tag":113,"props":562,"children":563},{"style":217},[564],{"type":26,"value":440},{"type":21,"tag":113,"props":566,"children":568},{"class":115,"line":567},17,[569,574,579,584,589,594,599,604,609,614,619],{"type":21,"tag":113,"props":570,"children":571},{"style":217},[572],{"type":26,"value":573}," copyright: ",{"type":21,"tag":113,"props":575,"children":576},{"style":126},[577],{"type":26,"value":578},"`All rights reserved ${",{"type":21,"tag":113,"props":580,"children":581},{"style":211},[582],{"type":26,"value":583},"new",{"type":21,"tag":113,"props":585,"children":586},{"style":120},[587],{"type":26,"value":588}," Date",{"type":21,"tag":113,"props":590,"children":591},{"style":126},[592],{"type":26,"value":593},"().",{"type":21,"tag":113,"props":595,"children":596},{"style":120},[597],{"type":26,"value":598},"getFullYear",{"type":21,"tag":113,"props":600,"children":601},{"style":126},[602],{"type":26,"value":603},"()",{"type":21,"tag":113,"props":605,"children":606},{"style":126},[607],{"type":26,"value":608},"}, ${",{"type":21,"tag":113,"props":610,"children":611},{"style":132},[612],{"type":26,"value":613},"AUTHOR_NAME",{"type":21,"tag":113,"props":615,"children":616},{"style":126},[617],{"type":26,"value":618},"}`",{"type":21,"tag":113,"props":620,"children":621},{"style":217},[622],{"type":26,"value":440},{"type":21,"tag":113,"props":624,"children":626},{"class":115,"line":625},18,[627,632,636,640],{"type":21,"tag":113,"props":628,"children":629},{"style":217},[630],{"type":26,"value":631}," updated: ",{"type":21,"tag":113,"props":633,"children":634},{"style":211},[635],{"type":26,"value":583},{"type":21,"tag":113,"props":637,"children":638},{"style":120},[639],{"type":26,"value":588},{"type":21,"tag":113,"props":641,"children":642},{"style":217},[643],{"type":26,"value":644},"(),\n",{"type":21,"tag":113,"props":646,"children":648},{"class":115,"line":647},19,[649,654,659],{"type":21,"tag":113,"props":650,"children":651},{"style":217},[652],{"type":26,"value":653}," generator: ",{"type":21,"tag":113,"props":655,"children":656},{"style":126},[657],{"type":26,"value":658},"\"Nuxt static site generation + Feed for Node.js\"",{"type":21,"tag":113,"props":660,"children":661},{"style":217},[662],{"type":26,"value":440},{"type":21,"tag":113,"props":664,"children":666},{"class":115,"line":665},20,[667],{"type":21,"tag":113,"props":668,"children":669},{"style":217},[670],{"type":26,"value":671}," feedLinks: {\n",{"type":21,"tag":113,"props":673,"children":675},{"class":115,"line":674},21,[676,681,685,689],{"type":21,"tag":113,"props":677,"children":678},{"style":217},[679],{"type":26,"value":680}," atom: ",{"type":21,"tag":113,"props":682,"children":683},{"style":126},[684],{"type":26,"value":525},{"type":21,"tag":113,"props":686,"children":687},{"style":132},[688],{"type":26,"value":472},{"type":21,"tag":113,"props":690,"children":691},{"style":126},[692],{"type":26,"value":693},"}/atom`\n",{"type":21,"tag":113,"props":695,"children":697},{"class":115,"line":696},22,[698],{"type":21,"tag":113,"props":699,"children":700},{"style":217},[701],{"type":26,"value":702}," },\n",{"type":21,"tag":113,"props":704,"children":706},{"class":115,"line":705},23,[707],{"type":21,"tag":113,"props":708,"children":709},{"style":217},[710],{"type":26,"value":711}," author: {\n",{"type":21,"tag":113,"props":713,"children":715},{"class":115,"line":714},24,[716,721,725],{"type":21,"tag":113,"props":717,"children":718},{"style":217},[719],{"type":26,"value":720}," name: ",{"type":21,"tag":113,"props":722,"children":723},{"style":132},[724],{"type":26,"value":613},{"type":21,"tag":113,"props":726,"children":727},{"style":217},[728],{"type":26,"value":440},{"type":21,"tag":113,"props":730,"children":732},{"class":115,"line":731},25,[733],{"type":21,"tag":113,"props":734,"children":735},{"style":217},[736],{"type":26,"value":737}," }\n",{"type":21,"tag":113,"props":739,"children":741},{"class":115,"line":740},26,[742],{"type":21,"tag":113,"props":743,"children":744},{"style":217},[745],{"type":26,"value":746}," });\n",{"type":21,"tag":113,"props":748,"children":750},{"class":115,"line":749},27,[751],{"type":21,"tag":113,"props":752,"children":753},{"emptyLinePlaceholder":268},[754],{"type":26,"value":271},{"type":21,"tag":113,"props":756,"children":758},{"class":115,"line":757},28,[759,763,768,772,777,782,787,792],{"type":21,"tag":113,"props":760,"children":761},{"style":211},[762],{"type":26,"value":397},{"type":21,"tag":113,"props":764,"children":765},{"style":132},[766],{"type":26,"value":767}," articles",{"type":21,"tag":113,"props":769,"children":770},{"style":211},[771],{"type":26,"value":290},{"type":21,"tag":113,"props":773,"children":774},{"style":211},[775],{"type":26,"value":776}," await",{"type":21,"tag":113,"props":778,"children":779},{"style":120},[780],{"type":26,"value":781}," serverQueryContent",{"type":21,"tag":113,"props":783,"children":784},{"style":217},[785],{"type":26,"value":786},"(event).",{"type":21,"tag":113,"props":788,"children":789},{"style":120},[790],{"type":26,"value":791},"find",{"type":21,"tag":113,"props":793,"children":794},{"style":217},[795],{"type":26,"value":796},"();\n",{"type":21,"tag":113,"props":798,"children":800},{"class":115,"line":799},29,[801],{"type":21,"tag":113,"props":802,"children":803},{"emptyLinePlaceholder":268},[804],{"type":26,"value":271},{"type":21,"tag":113,"props":806,"children":808},{"class":115,"line":807},30,[809,814,819,824,829,833,837],{"type":21,"tag":113,"props":810,"children":811},{"style":217},[812],{"type":26,"value":813}," articles.",{"type":21,"tag":113,"props":815,"children":816},{"style":120},[817],{"type":26,"value":818},"forEach",{"type":21,"tag":113,"props":820,"children":821},{"style":217},[822],{"type":26,"value":823},"((",{"type":21,"tag":113,"props":825,"children":826},{"style":362},[827],{"type":26,"value":828},"article",{"type":21,"tag":113,"props":830,"children":831},{"style":217},[832],{"type":26,"value":370},{"type":21,"tag":113,"props":834,"children":835},{"style":211},[836],{"type":26,"value":375},{"type":21,"tag":113,"props":838,"children":839},{"style":217},[840],{"type":26,"value":380},{"type":21,"tag":113,"props":842,"children":844},{"class":115,"line":843},31,[845,850,855],{"type":21,"tag":113,"props":846,"children":847},{"style":217},[848],{"type":26,"value":849}," feed.",{"type":21,"tag":113,"props":851,"children":852},{"style":120},[853],{"type":26,"value":854},"addItem",{"type":21,"tag":113,"props":856,"children":857},{"style":217},[858],{"type":26,"value":421},{"type":21,"tag":113,"props":860,"children":862},{"class":115,"line":861},32,[863,868,873,878,883,888],{"type":21,"tag":113,"props":864,"children":865},{"style":217},[866],{"type":26,"value":867}," title: article.title ",{"type":21,"tag":113,"props":869,"children":870},{"style":211},[871],{"type":26,"value":872},"?",{"type":21,"tag":113,"props":874,"children":875},{"style":217},[876],{"type":26,"value":877}," article.title ",{"type":21,"tag":113,"props":879,"children":880},{"style":211},[881],{"type":26,"value":882},":",{"type":21,"tag":113,"props":884,"children":885},{"style":126},[886],{"type":26,"value":887}," \"Missing Title\"",{"type":21,"tag":113,"props":889,"children":890},{"style":217},[891],{"type":26,"value":440},{"type":21,"tag":113,"props":893,"children":895},{"class":115,"line":894},33,[896],{"type":21,"tag":113,"props":897,"children":898},{"style":217},[899],{"type":26,"value":900}," id: article._path,\n",{"type":21,"tag":113,"props":902,"children":904},{"class":115,"line":903},34,[905,910,914,918,923,927,931,936,940],{"type":21,"tag":113,"props":906,"children":907},{"style":217},[908],{"type":26,"value":909}," link: ",{"type":21,"tag":113,"props":911,"children":912},{"style":126},[913],{"type":26,"value":525},{"type":21,"tag":113,"props":915,"children":916},{"style":132},[917],{"type":26,"value":472},{"type":21,"tag":113,"props":919,"children":920},{"style":126},[921],{"type":26,"value":922},"}${",{"type":21,"tag":113,"props":924,"children":925},{"style":217},[926],{"type":26,"value":828},{"type":21,"tag":113,"props":928,"children":929},{"style":126},[930],{"type":26,"value":161},{"type":21,"tag":113,"props":932,"children":933},{"style":217},[934],{"type":26,"value":935},"_path",{"type":21,"tag":113,"props":937,"children":938},{"style":126},[939],{"type":26,"value":618},{"type":21,"tag":113,"props":941,"children":942},{"style":217},[943],{"type":26,"value":440},{"type":21,"tag":113,"props":945,"children":947},{"class":115,"line":946},35,[948],{"type":21,"tag":113,"props":949,"children":950},{"style":217},[951],{"type":26,"value":952}," description: article.description,\n",{"type":21,"tag":113,"props":954,"children":956},{"class":115,"line":955},36,[957],{"type":21,"tag":113,"props":958,"children":959},{"style":217},[960],{"type":26,"value":961}," author: [\n",{"type":21,"tag":113,"props":963,"children":965},{"class":115,"line":964},37,[966],{"type":21,"tag":113,"props":967,"children":968},{"style":217},[969],{"type":26,"value":970}," {\n",{"type":21,"tag":113,"props":972,"children":974},{"class":115,"line":973},38,[975,980,984],{"type":21,"tag":113,"props":976,"children":977},{"style":217},[978],{"type":26,"value":979}," name: ",{"type":21,"tag":113,"props":981,"children":982},{"style":132},[983],{"type":26,"value":613},{"type":21,"tag":113,"props":985,"children":986},{"style":217},[987],{"type":26,"value":440},{"type":21,"tag":113,"props":989,"children":991},{"class":115,"line":990},39,[992],{"type":21,"tag":113,"props":993,"children":994},{"style":217},[995],{"type":26,"value":996}," },\n",{"type":21,"tag":113,"props":998,"children":1000},{"class":115,"line":999},40,[1001],{"type":21,"tag":113,"props":1002,"children":1003},{"style":217},[1004],{"type":26,"value":1005}," ],\n",{"type":21,"tag":113,"props":1007,"children":1009},{"class":115,"line":1008},41,[1010,1015,1019,1023],{"type":21,"tag":113,"props":1011,"children":1012},{"style":217},[1013],{"type":26,"value":1014}," date: ",{"type":21,"tag":113,"props":1016,"children":1017},{"style":211},[1018],{"type":26,"value":583},{"type":21,"tag":113,"props":1020,"children":1021},{"style":120},[1022],{"type":26,"value":588},{"type":21,"tag":113,"props":1024,"children":1025},{"style":217},[1026],{"type":26,"value":1027},"(article.date),\n",{"type":21,"tag":113,"props":1029,"children":1031},{"class":115,"line":1030},42,[1032,1037,1041,1046,1050,1055,1059,1063,1068,1072,1077],{"type":21,"tag":113,"props":1033,"children":1034},{"style":217},[1035],{"type":26,"value":1036}," image: article.cover_image ",{"type":21,"tag":113,"props":1038,"children":1039},{"style":211},[1040],{"type":26,"value":872},{"type":21,"tag":113,"props":1042,"children":1043},{"style":126},[1044],{"type":26,"value":1045}," `${",{"type":21,"tag":113,"props":1047,"children":1048},{"style":132},[1049],{"type":26,"value":472},{"type":21,"tag":113,"props":1051,"children":1052},{"style":126},[1053],{"type":26,"value":1054},"}/${",{"type":21,"tag":113,"props":1056,"children":1057},{"style":217},[1058],{"type":26,"value":828},{"type":21,"tag":113,"props":1060,"children":1061},{"style":126},[1062],{"type":26,"value":161},{"type":21,"tag":113,"props":1064,"children":1065},{"style":217},[1066],{"type":26,"value":1067},"cover_image",{"type":21,"tag":113,"props":1069,"children":1070},{"style":126},[1071],{"type":26,"value":618},{"type":21,"tag":113,"props":1073,"children":1074},{"style":211},[1075],{"type":26,"value":1076}," :",{"type":21,"tag":113,"props":1078,"children":1079},{"style":132},[1080],{"type":26,"value":1081}," undefined\n",{"type":21,"tag":113,"props":1083,"children":1085},{"class":115,"line":1084},43,[1086],{"type":21,"tag":113,"props":1087,"children":1088},{"style":217},[1089],{"type":26,"value":1090}," });\n",{"type":21,"tag":113,"props":1092,"children":1094},{"class":115,"line":1093},44,[1095],{"type":21,"tag":113,"props":1096,"children":1097},{"style":217},[1098],{"type":26,"value":746},{"type":21,"tag":113,"props":1100,"children":1102},{"class":115,"line":1101},45,[1103],{"type":21,"tag":113,"props":1104,"children":1105},{"emptyLinePlaceholder":268},[1106],{"type":26,"value":271},{"type":21,"tag":113,"props":1108,"children":1110},{"class":115,"line":1109},46,[1111,1116,1121,1126],{"type":21,"tag":113,"props":1112,"children":1113},{"style":211},[1114],{"type":26,"value":1115}," return",{"type":21,"tag":113,"props":1117,"children":1118},{"style":217},[1119],{"type":26,"value":1120}," feed.",{"type":21,"tag":113,"props":1122,"children":1123},{"style":120},[1124],{"type":26,"value":1125},"atom1",{"type":21,"tag":113,"props":1127,"children":1128},{"style":217},[1129],{"type":26,"value":796},{"type":21,"tag":113,"props":1131,"children":1133},{"class":115,"line":1132},47,[1134],{"type":21,"tag":113,"props":1135,"children":1136},{"style":217},[1137],{"type":26,"value":1138},"});\n",{"type":21,"tag":22,"props":1140,"children":1141},{},[1142,1144,1150,1152,1158,1160,1166,1168,1174],{"type":26,"value":1143},"And that's just about it! Except, if you are statically generating your website with the ",{"type":21,"tag":109,"props":1145,"children":1147},{"className":1146},[],[1148],{"type":26,"value":1149},"nuxt generate",{"type":26,"value":1151}," command, you will need to configure this server-side route to be pre-rendered on site generation. This is as simple as adding a ",{"type":21,"tag":109,"props":1153,"children":1155},{"className":1154},[],[1156],{"type":26,"value":1157},"nitro",{"type":26,"value":1159}," ",{"type":21,"tag":109,"props":1161,"children":1163},{"className":1162},[],[1164],{"type":26,"value":1165},"prerender",{"type":26,"value":1167}," definition in your ",{"type":21,"tag":109,"props":1169,"children":1171},{"className":1170},[],[1172],{"type":26,"value":1173},"nuxt.config.ts",{"type":26,"value":1175}," file, like so:",{"type":21,"tag":102,"props":1177,"children":1179},{"className":199,"code":1178,"language":201,"meta":7,"style":7},"nitro: {\n prerender: {\n routes: ['/atom']\n }\n}\n",[1180],{"type":21,"tag":109,"props":1181,"children":1182},{"__ignoreMap":7},[1183,1195,1207,1230,1238],{"type":21,"tag":113,"props":1184,"children":1185},{"class":115,"line":116},[1186,1190],{"type":21,"tag":113,"props":1187,"children":1188},{"style":120},[1189],{"type":26,"value":1157},{"type":21,"tag":113,"props":1191,"children":1192},{"style":217},[1193],{"type":26,"value":1194},": {\n",{"type":21,"tag":113,"props":1196,"children":1197},{"class":115,"line":238},[1198,1203],{"type":21,"tag":113,"props":1199,"children":1200},{"style":120},[1201],{"type":26,"value":1202}," prerender",{"type":21,"tag":113,"props":1204,"children":1205},{"style":217},[1206],{"type":26,"value":1194},{"type":21,"tag":113,"props":1208,"children":1209},{"class":115,"line":264},[1210,1215,1220,1225],{"type":21,"tag":113,"props":1211,"children":1212},{"style":120},[1213],{"type":26,"value":1214}," routes",{"type":21,"tag":113,"props":1216,"children":1217},{"style":217},[1218],{"type":26,"value":1219},": [",{"type":21,"tag":113,"props":1221,"children":1222},{"style":126},[1223],{"type":26,"value":1224},"'/atom'",{"type":21,"tag":113,"props":1226,"children":1227},{"style":217},[1228],{"type":26,"value":1229},"]\n",{"type":21,"tag":113,"props":1231,"children":1232},{"class":115,"line":274},[1233],{"type":21,"tag":113,"props":1234,"children":1235},{"style":217},[1236],{"type":26,"value":1237}," }\n",{"type":21,"tag":113,"props":1239,"children":1240},{"class":115,"line":298},[1241],{"type":21,"tag":113,"props":1242,"children":1243},{"style":217},[1244],{"type":26,"value":1245},"}\n",{"type":21,"tag":52,"props":1247,"children":1249},{"id":1248},"bonus",[1250],{"type":26,"value":1251},"Bonus",{"type":21,"tag":22,"props":1253,"children":1254},{},[1255,1257,1263],{"type":26,"value":1256},"You may also be interested in adding a ",{"type":21,"tag":109,"props":1258,"children":1260},{"className":1259},[],[1261],{"type":26,"value":1262},"sitemap.xml",{"type":26,"value":1264}," to your website. This can be done in almost an identical fashion!",{"type":21,"tag":22,"props":1266,"children":1267},{},[1268],{"type":26,"value":1269},"Install the dependency:",{"type":21,"tag":102,"props":1271,"children":1273},{"className":104,"code":1272,"language":106,"meta":7,"style":7},"npm i -D sitemap\n",[1274],{"type":21,"tag":109,"props":1275,"children":1276},{"__ignoreMap":7},[1277],{"type":21,"tag":113,"props":1278,"children":1279},{"class":115,"line":116},[1280,1284,1288,1292],{"type":21,"tag":113,"props":1281,"children":1282},{"style":120},[1283],{"type":26,"value":123},{"type":21,"tag":113,"props":1285,"children":1286},{"style":126},[1287],{"type":26,"value":129},{"type":21,"tag":113,"props":1289,"children":1290},{"style":132},[1291],{"type":26,"value":135},{"type":21,"tag":113,"props":1293,"children":1294},{"style":126},[1295],{"type":26,"value":1296}," sitemap\n",{"type":21,"tag":22,"props":1298,"children":1299},{},[1300,1302,1308],{"type":26,"value":1301},"Create a route at ",{"type":21,"tag":109,"props":1303,"children":1305},{"className":1304},[],[1306],{"type":26,"value":1307},"server/routes/sitemap.xml.ts",{"type":26,"value":882},{"type":21,"tag":102,"props":1310,"children":1312},{"className":199,"code":1311,"language":201,"meta":7,"style":7},"import { serverQueryContent } from '#content/server';\nimport { SitemapStream, streamToPromise } from 'sitemap';\n\nexport default defineEventHandler(async (event) => {\n const articles = await serverQueryContent(event).find();\n\n const sitemap = new SitemapStream({ hostname: 'https://my-website.com/' });\n\n // Add non nuxt content endpoints here\n sitemap.write({ url: '/' });\n sitemap.write({ url: '/articles' });\n\n // Dynamically generate routes for Nuxt markdown content\n articles.forEach((article) => sitemap.write({ url: article._path, changefreq: 'monthly' }));\n sitemap.end();\n\n return (await streamToPromise(sitemap));\n});\n",[1313],{"type":21,"tag":109,"props":1314,"children":1315},{"__ignoreMap":7},[1316,1339,1364,1371,1414,1449,1456,1496,1503,1512,1539,1563,1570,1578,1629,1645,1652,1678],{"type":21,"tag":113,"props":1317,"children":1318},{"class":115,"line":116},[1319,1323,1327,1331,1335],{"type":21,"tag":113,"props":1320,"children":1321},{"style":211},[1322],{"type":26,"value":214},{"type":21,"tag":113,"props":1324,"children":1325},{"style":217},[1326],{"type":26,"value":220},{"type":21,"tag":113,"props":1328,"children":1329},{"style":211},[1330],{"type":26,"value":225},{"type":21,"tag":113,"props":1332,"children":1333},{"style":126},[1334],{"type":26,"value":230},{"type":21,"tag":113,"props":1336,"children":1337},{"style":217},[1338],{"type":26,"value":235},{"type":21,"tag":113,"props":1340,"children":1341},{"class":115,"line":238},[1342,1346,1351,1355,1360],{"type":21,"tag":113,"props":1343,"children":1344},{"style":211},[1345],{"type":26,"value":214},{"type":21,"tag":113,"props":1347,"children":1348},{"style":217},[1349],{"type":26,"value":1350}," { SitemapStream, streamToPromise } ",{"type":21,"tag":113,"props":1352,"children":1353},{"style":211},[1354],{"type":26,"value":225},{"type":21,"tag":113,"props":1356,"children":1357},{"style":126},[1358],{"type":26,"value":1359}," 'sitemap'",{"type":21,"tag":113,"props":1361,"children":1362},{"style":217},[1363],{"type":26,"value":235},{"type":21,"tag":113,"props":1365,"children":1366},{"class":115,"line":264},[1367],{"type":21,"tag":113,"props":1368,"children":1369},{"emptyLinePlaceholder":268},[1370],{"type":26,"value":271},{"type":21,"tag":113,"props":1372,"children":1373},{"class":115,"line":274},[1374,1378,1382,1386,1390,1394,1398,1402,1406,1410],{"type":21,"tag":113,"props":1375,"children":1376},{"style":211},[1377],{"type":26,"value":334},{"type":21,"tag":113,"props":1379,"children":1380},{"style":211},[1381],{"type":26,"value":339},{"type":21,"tag":113,"props":1383,"children":1384},{"style":120},[1385],{"type":26,"value":344},{"type":21,"tag":113,"props":1387,"children":1388},{"style":217},[1389],{"type":26,"value":349},{"type":21,"tag":113,"props":1391,"children":1392},{"style":211},[1393],{"type":26,"value":354},{"type":21,"tag":113,"props":1395,"children":1396},{"style":217},[1397],{"type":26,"value":359},{"type":21,"tag":113,"props":1399,"children":1400},{"style":362},[1401],{"type":26,"value":365},{"type":21,"tag":113,"props":1403,"children":1404},{"style":217},[1405],{"type":26,"value":370},{"type":21,"tag":113,"props":1407,"children":1408},{"style":211},[1409],{"type":26,"value":375},{"type":21,"tag":113,"props":1411,"children":1412},{"style":217},[1413],{"type":26,"value":380},{"type":21,"tag":113,"props":1415,"children":1416},{"class":115,"line":298},[1417,1421,1425,1429,1433,1437,1441,1445],{"type":21,"tag":113,"props":1418,"children":1419},{"style":211},[1420],{"type":26,"value":397},{"type":21,"tag":113,"props":1422,"children":1423},{"style":132},[1424],{"type":26,"value":767},{"type":21,"tag":113,"props":1426,"children":1427},{"style":211},[1428],{"type":26,"value":290},{"type":21,"tag":113,"props":1430,"children":1431},{"style":211},[1432],{"type":26,"value":776},{"type":21,"tag":113,"props":1434,"children":1435},{"style":120},[1436],{"type":26,"value":781},{"type":21,"tag":113,"props":1438,"children":1439},{"style":217},[1440],{"type":26,"value":786},{"type":21,"tag":113,"props":1442,"children":1443},{"style":120},[1444],{"type":26,"value":791},{"type":21,"tag":113,"props":1446,"children":1447},{"style":217},[1448],{"type":26,"value":796},{"type":21,"tag":113,"props":1450,"children":1451},{"class":115,"line":320},[1452],{"type":21,"tag":113,"props":1453,"children":1454},{"emptyLinePlaceholder":268},[1455],{"type":26,"value":271},{"type":21,"tag":113,"props":1457,"children":1458},{"class":115,"line":328},[1459,1463,1468,1472,1476,1481,1486,1491],{"type":21,"tag":113,"props":1460,"children":1461},{"style":211},[1462],{"type":26,"value":397},{"type":21,"tag":113,"props":1464,"children":1465},{"style":132},[1466],{"type":26,"value":1467}," sitemap",{"type":21,"tag":113,"props":1469,"children":1470},{"style":211},[1471],{"type":26,"value":290},{"type":21,"tag":113,"props":1473,"children":1474},{"style":211},[1475],{"type":26,"value":411},{"type":21,"tag":113,"props":1477,"children":1478},{"style":120},[1479],{"type":26,"value":1480}," SitemapStream",{"type":21,"tag":113,"props":1482,"children":1483},{"style":217},[1484],{"type":26,"value":1485},"({ hostname: ",{"type":21,"tag":113,"props":1487,"children":1488},{"style":126},[1489],{"type":26,"value":1490},"'https://my-website.com/'",{"type":21,"tag":113,"props":1492,"children":1493},{"style":217},[1494],{"type":26,"value":1495}," });\n",{"type":21,"tag":113,"props":1497,"children":1498},{"class":115,"line":383},[1499],{"type":21,"tag":113,"props":1500,"children":1501},{"emptyLinePlaceholder":268},[1502],{"type":26,"value":271},{"type":21,"tag":113,"props":1504,"children":1505},{"class":115,"line":391},[1506],{"type":21,"tag":113,"props":1507,"children":1509},{"style":1508},"--shiki-default:#6A737D",[1510],{"type":26,"value":1511}," // Add non nuxt content endpoints here\n",{"type":21,"tag":113,"props":1513,"children":1514},{"class":115,"line":424},[1515,1520,1525,1530,1535],{"type":21,"tag":113,"props":1516,"children":1517},{"style":217},[1518],{"type":26,"value":1519}," sitemap.",{"type":21,"tag":113,"props":1521,"children":1522},{"style":120},[1523],{"type":26,"value":1524},"write",{"type":21,"tag":113,"props":1526,"children":1527},{"style":217},[1528],{"type":26,"value":1529},"({ url: ",{"type":21,"tag":113,"props":1531,"children":1532},{"style":126},[1533],{"type":26,"value":1534},"'/'",{"type":21,"tag":113,"props":1536,"children":1537},{"style":217},[1538],{"type":26,"value":1495},{"type":21,"tag":113,"props":1540,"children":1541},{"class":115,"line":443},[1542,1546,1550,1554,1559],{"type":21,"tag":113,"props":1543,"children":1544},{"style":217},[1545],{"type":26,"value":1519},{"type":21,"tag":113,"props":1547,"children":1548},{"style":120},[1549],{"type":26,"value":1524},{"type":21,"tag":113,"props":1551,"children":1552},{"style":217},[1553],{"type":26,"value":1529},{"type":21,"tag":113,"props":1555,"children":1556},{"style":126},[1557],{"type":26,"value":1558},"'/articles'",{"type":21,"tag":113,"props":1560,"children":1561},{"style":217},[1562],{"type":26,"value":1495},{"type":21,"tag":113,"props":1564,"children":1565},{"class":115,"line":461},[1566],{"type":21,"tag":113,"props":1567,"children":1568},{"emptyLinePlaceholder":268},[1569],{"type":26,"value":271},{"type":21,"tag":113,"props":1571,"children":1572},{"class":115,"line":479},[1573],{"type":21,"tag":113,"props":1574,"children":1575},{"style":1508},[1576],{"type":26,"value":1577}," // Dynamically generate routes for Nuxt markdown content\n",{"type":21,"tag":113,"props":1579,"children":1580},{"class":115,"line":496},[1581,1585,1589,1593,1597,1601,1605,1610,1614,1619,1624],{"type":21,"tag":113,"props":1582,"children":1583},{"style":217},[1584],{"type":26,"value":813},{"type":21,"tag":113,"props":1586,"children":1587},{"style":120},[1588],{"type":26,"value":818},{"type":21,"tag":113,"props":1590,"children":1591},{"style":217},[1592],{"type":26,"value":823},{"type":21,"tag":113,"props":1594,"children":1595},{"style":362},[1596],{"type":26,"value":828},{"type":21,"tag":113,"props":1598,"children":1599},{"style":217},[1600],{"type":26,"value":370},{"type":21,"tag":113,"props":1602,"children":1603},{"style":211},[1604],{"type":26,"value":375},{"type":21,"tag":113,"props":1606,"children":1607},{"style":217},[1608],{"type":26,"value":1609}," sitemap.",{"type":21,"tag":113,"props":1611,"children":1612},{"style":120},[1613],{"type":26,"value":1524},{"type":21,"tag":113,"props":1615,"children":1616},{"style":217},[1617],{"type":26,"value":1618},"({ url: article._path, changefreq: ",{"type":21,"tag":113,"props":1620,"children":1621},{"style":126},[1622],{"type":26,"value":1623},"'monthly'",{"type":21,"tag":113,"props":1625,"children":1626},{"style":217},[1627],{"type":26,"value":1628}," }));\n",{"type":21,"tag":113,"props":1630,"children":1631},{"class":115,"line":514},[1632,1636,1641],{"type":21,"tag":113,"props":1633,"children":1634},{"style":217},[1635],{"type":26,"value":1519},{"type":21,"tag":113,"props":1637,"children":1638},{"style":120},[1639],{"type":26,"value":1640},"end",{"type":21,"tag":113,"props":1642,"children":1643},{"style":217},[1644],{"type":26,"value":796},{"type":21,"tag":113,"props":1646,"children":1647},{"class":115,"line":541},[1648],{"type":21,"tag":113,"props":1649,"children":1650},{"emptyLinePlaceholder":268},[1651],{"type":26,"value":271},{"type":21,"tag":113,"props":1653,"children":1654},{"class":115,"line":567},[1655,1659,1663,1668,1673],{"type":21,"tag":113,"props":1656,"children":1657},{"style":211},[1658],{"type":26,"value":1115},{"type":21,"tag":113,"props":1660,"children":1661},{"style":217},[1662],{"type":26,"value":359},{"type":21,"tag":113,"props":1664,"children":1665},{"style":211},[1666],{"type":26,"value":1667},"await",{"type":21,"tag":113,"props":1669,"children":1670},{"style":120},[1671],{"type":26,"value":1672}," streamToPromise",{"type":21,"tag":113,"props":1674,"children":1675},{"style":217},[1676],{"type":26,"value":1677},"(sitemap));\n",{"type":21,"tag":113,"props":1679,"children":1680},{"class":115,"line":625},[1681],{"type":21,"tag":113,"props":1682,"children":1683},{"style":217},[1684],{"type":26,"value":1138},{"type":21,"tag":22,"props":1686,"children":1687},{},[1688,1690,1695,1697,1702],{"type":26,"value":1689},"And add the ",{"type":21,"tag":109,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":26,"value":1165},{"type":26,"value":1696}," entry in your ",{"type":21,"tag":109,"props":1698,"children":1700},{"className":1699},[],[1701],{"type":26,"value":1173},{"type":26,"value":882},{"type":21,"tag":102,"props":1704,"children":1706},{"className":199,"code":1705,"language":201,"meta":7,"style":7},"nitro: {\n prerender: {\n routes: ['/sitemap.xml', '/atom']\n }\n}\n",[1707],{"type":21,"tag":109,"props":1708,"children":1709},{"__ignoreMap":7},[1710,1721,1732,1761,1768],{"type":21,"tag":113,"props":1711,"children":1712},{"class":115,"line":116},[1713,1717],{"type":21,"tag":113,"props":1714,"children":1715},{"style":120},[1716],{"type":26,"value":1157},{"type":21,"tag":113,"props":1718,"children":1719},{"style":217},[1720],{"type":26,"value":1194},{"type":21,"tag":113,"props":1722,"children":1723},{"class":115,"line":238},[1724,1728],{"type":21,"tag":113,"props":1725,"children":1726},{"style":120},[1727],{"type":26,"value":1202},{"type":21,"tag":113,"props":1729,"children":1730},{"style":217},[1731],{"type":26,"value":1194},{"type":21,"tag":113,"props":1733,"children":1734},{"class":115,"line":264},[1735,1739,1743,1748,1753,1757],{"type":21,"tag":113,"props":1736,"children":1737},{"style":120},[1738],{"type":26,"value":1214},{"type":21,"tag":113,"props":1740,"children":1741},{"style":217},[1742],{"type":26,"value":1219},{"type":21,"tag":113,"props":1744,"children":1745},{"style":126},[1746],{"type":26,"value":1747},"'/sitemap.xml'",{"type":21,"tag":113,"props":1749,"children":1750},{"style":217},[1751],{"type":26,"value":1752},", ",{"type":21,"tag":113,"props":1754,"children":1755},{"style":126},[1756],{"type":26,"value":1224},{"type":21,"tag":113,"props":1758,"children":1759},{"style":217},[1760],{"type":26,"value":1229},{"type":21,"tag":113,"props":1762,"children":1763},{"class":115,"line":274},[1764],{"type":21,"tag":113,"props":1765,"children":1766},{"style":217},[1767],{"type":26,"value":1237},{"type":21,"tag":113,"props":1769,"children":1770},{"class":115,"line":298},[1771],{"type":21,"tag":113,"props":1772,"children":1773},{"style":217},[1774],{"type":26,"value":1245},{"type":21,"tag":1776,"props":1777,"children":1778},"style",{},[1779],{"type":26,"value":1780},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":238,"depth":238,"links":1782},[1783,1784,1785],{"id":54,"depth":238,"text":57},{"id":83,"depth":238,"text":86},{"id":1248,"depth":238,"text":1251},"markdown","content:articles:nuxt-content-rss-feed.md","content","articles/nuxt-content-rss-feed.md","md",1718891181718] \ No newline at end of file +[{"data":1,"prerenderedAt":1792},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"cover_image":16,"excerpt":17,"body":39,"_type":1786,"_id":1787,"_source":1788,"_file":1789,"_stem":1790,"_extension":1791},"/articles/nuxt-content-rss-feed","articles",false,"","How To Add an RSS Feed to a Nuxt Website","If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.","2024-01-06",[12,13],"nuxt","rss",[15],"programming","/images/nuxt-content-rss-feed.jpg",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,28,37],{"type":26,"value":27},"text","If you are a user of ",{"type":21,"tag":29,"props":30,"children":34},"a",{"href":31,"rel":32},"https://content.nuxt.com/",[33],"nofollow",[35],{"type":26,"value":36},"Nuxt Content",{"type":26,"value":38}," and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.",{"type":18,"children":40,"toc":1781},[41,51,58,81,87,101,141,162,197,1139,1176,1246,1252,1265,1270,1297,1309,1685,1703,1775],{"type":21,"tag":22,"props":42,"children":43},{},[44,45,50],{"type":26,"value":27},{"type":21,"tag":29,"props":46,"children":48},{"href":31,"rel":47},[33],[49],{"type":26,"value":36},{"type":26,"value":38},{"type":21,"tag":52,"props":53,"children":55},"h2",{"id":54},"preface",[56],{"type":26,"value":57},"Preface",{"type":21,"tag":22,"props":59,"children":60},{},[61,63,70,72,79],{"type":26,"value":62},"In version 2 of Nuxt, the community module, ",{"type":21,"tag":29,"props":64,"children":67},{"href":65,"rel":66},"https://github.com/nuxt-community/feed-module",[33],[68],{"type":26,"value":69},"nuxt-community/feed-module",{"type":26,"value":71}," was a popular choice for adding an RSS feed to your website. However, there has been an unresolved ",{"type":21,"tag":29,"props":73,"children":76},{"href":74,"rel":75},"https://github.com/nuxt-community/feed-module/issues/106",[33],[77],{"type":26,"value":78},"open issue",{"type":26,"value":80}," since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward.",{"type":21,"tag":52,"props":82,"children":84},{"id":83},"instructions",[85],{"type":26,"value":86},"Instructions",{"type":21,"tag":22,"props":88,"children":89},{},[90,92,99],{"type":26,"value":91},"First, install the ",{"type":21,"tag":29,"props":93,"children":96},{"href":94,"rel":95},"https://www.npmjs.com/package/feed",[33],[97],{"type":26,"value":98},"feed",{"type":26,"value":100}," library into your project:",{"type":21,"tag":102,"props":103,"children":107},"pre",{"className":104,"code":105,"language":106,"meta":7,"style":7},"language-shell shiki shiki-themes github-light","npm i -D feed\n","shell",[108],{"type":21,"tag":109,"props":110,"children":111},"code",{"__ignoreMap":7},[112],{"type":21,"tag":113,"props":114,"children":117},"span",{"class":115,"line":116},"line",1,[118,124,130,136],{"type":21,"tag":113,"props":119,"children":121},{"style":120},"--shiki-default:#6F42C1",[122],{"type":26,"value":123},"npm",{"type":21,"tag":113,"props":125,"children":127},{"style":126},"--shiki-default:#032F62",[128],{"type":26,"value":129}," i",{"type":21,"tag":113,"props":131,"children":133},{"style":132},"--shiki-default:#005CC5",[134],{"type":26,"value":135}," -D",{"type":21,"tag":113,"props":137,"children":138},{"style":126},[139],{"type":26,"value":140}," feed\n",{"type":21,"tag":22,"props":142,"children":143},{},[144,146,152,154,160],{"type":26,"value":145},"Then, create a ",{"type":21,"tag":109,"props":147,"children":149},{"className":148},[],[150],{"type":26,"value":151},"server/",{"type":26,"value":153}," folder in your project if it does not already exist, and create a file named ",{"type":21,"tag":109,"props":155,"children":157},{"className":156},[],[158],{"type":26,"value":159},"server/routes/atom.ts",{"type":26,"value":161},".",{"type":21,"tag":22,"props":163,"children":164},{},[165,167,172,174,179,181,187,189,195],{"type":26,"value":166},"Here, we will leverage the ",{"type":21,"tag":109,"props":168,"children":170},{"className":169},[],[171],{"type":26,"value":98},{"type":26,"value":173}," library and construct an XML representation of our Nuxt content. As you can see, we first define our ",{"type":21,"tag":109,"props":175,"children":177},{"className":176},[],[178],{"type":26,"value":98},{"type":26,"value":180}," with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with ",{"type":21,"tag":109,"props":182,"children":184},{"className":183},[],[185],{"type":26,"value":186},"serverQueryContent",{"type":26,"value":188}," and append a ",{"type":21,"tag":109,"props":190,"children":192},{"className":191},[],[193],{"type":26,"value":194},"feed.addItem",{"type":26,"value":196}," for each article.",{"type":21,"tag":102,"props":198,"children":202},{"className":199,"code":200,"language":201,"meta":7,"style":7},"language-ts shiki shiki-themes github-light","import { serverQueryContent } from '#content/server';\nimport { Feed } from 'feed';\n\nconst BASE_URL = \"https://mywebsite.com\"\nconst AUTHOR_NAME = \"Firstname Lastname\"\n\nexport default defineEventHandler(async (event) => {\n\n const feed = new Feed({\n title: \"My Title\",\n description: \"My Description\",\n id: BASE_URL,\n link: BASE_URL,\n language: \"en\",\n image: `${BASE_URL}/images/placeholder.png`,\n favicon: `${BASE_URL}/favicon.ico`,\n copyright: `All rights reserved ${new Date().getFullYear()}, ${AUTHOR_NAME}`,\n updated: new Date(),\n generator: \"Nuxt static site generation + Feed for Node.js\",\n feedLinks: {\n atom: `${BASE_URL}/atom`\n },\n author: {\n name: AUTHOR_NAME,\n }\n });\n\n const articles = await serverQueryContent(event).find();\n\n articles.forEach((article) => {\n feed.addItem({\n title: article.title ? article.title : \"Missing Title\",\n id: article._path,\n link: `${BASE_URL}${article._path}`,\n description: article.description,\n author: [\n {\n name: AUTHOR_NAME,\n },\n ],\n date: new Date(article.date),\n image: article.cover_image ? `${BASE_URL}/${article.cover_image}` : undefined\n });\n });\n\n return feed.atom1();\n});\n","ts",[203],{"type":21,"tag":109,"props":204,"children":205},{"__ignoreMap":7},[206,236,262,272,296,318,326,381,389,422,441,459,477,494,512,539,565,623,645,663,672,694,703,712,729,738,747,755,797,805,841,859,892,901,944,953,962,971,988,997,1006,1028,1082,1091,1099,1107,1130],{"type":21,"tag":113,"props":207,"children":208},{"class":115,"line":116},[209,215,221,226,231],{"type":21,"tag":113,"props":210,"children":212},{"style":211},"--shiki-default:#D73A49",[213],{"type":26,"value":214},"import",{"type":21,"tag":113,"props":216,"children":218},{"style":217},"--shiki-default:#24292E",[219],{"type":26,"value":220}," { serverQueryContent } ",{"type":21,"tag":113,"props":222,"children":223},{"style":211},[224],{"type":26,"value":225},"from",{"type":21,"tag":113,"props":227,"children":228},{"style":126},[229],{"type":26,"value":230}," '#content/server'",{"type":21,"tag":113,"props":232,"children":233},{"style":217},[234],{"type":26,"value":235},";\n",{"type":21,"tag":113,"props":237,"children":239},{"class":115,"line":238},2,[240,244,249,253,258],{"type":21,"tag":113,"props":241,"children":242},{"style":211},[243],{"type":26,"value":214},{"type":21,"tag":113,"props":245,"children":246},{"style":217},[247],{"type":26,"value":248}," { Feed } ",{"type":21,"tag":113,"props":250,"children":251},{"style":211},[252],{"type":26,"value":225},{"type":21,"tag":113,"props":254,"children":255},{"style":126},[256],{"type":26,"value":257}," 'feed'",{"type":21,"tag":113,"props":259,"children":260},{"style":217},[261],{"type":26,"value":235},{"type":21,"tag":113,"props":263,"children":265},{"class":115,"line":264},3,[266],{"type":21,"tag":113,"props":267,"children":269},{"emptyLinePlaceholder":268},true,[270],{"type":26,"value":271},"\n",{"type":21,"tag":113,"props":273,"children":275},{"class":115,"line":274},4,[276,281,286,291],{"type":21,"tag":113,"props":277,"children":278},{"style":211},[279],{"type":26,"value":280},"const",{"type":21,"tag":113,"props":282,"children":283},{"style":132},[284],{"type":26,"value":285}," BASE_URL",{"type":21,"tag":113,"props":287,"children":288},{"style":211},[289],{"type":26,"value":290}," =",{"type":21,"tag":113,"props":292,"children":293},{"style":126},[294],{"type":26,"value":295}," \"https://mywebsite.com\"\n",{"type":21,"tag":113,"props":297,"children":299},{"class":115,"line":298},5,[300,304,309,313],{"type":21,"tag":113,"props":301,"children":302},{"style":211},[303],{"type":26,"value":280},{"type":21,"tag":113,"props":305,"children":306},{"style":132},[307],{"type":26,"value":308}," AUTHOR_NAME",{"type":21,"tag":113,"props":310,"children":311},{"style":211},[312],{"type":26,"value":290},{"type":21,"tag":113,"props":314,"children":315},{"style":126},[316],{"type":26,"value":317}," \"Firstname Lastname\"\n",{"type":21,"tag":113,"props":319,"children":321},{"class":115,"line":320},6,[322],{"type":21,"tag":113,"props":323,"children":324},{"emptyLinePlaceholder":268},[325],{"type":26,"value":271},{"type":21,"tag":113,"props":327,"children":329},{"class":115,"line":328},7,[330,335,340,345,350,355,360,366,371,376],{"type":21,"tag":113,"props":331,"children":332},{"style":211},[333],{"type":26,"value":334},"export",{"type":21,"tag":113,"props":336,"children":337},{"style":211},[338],{"type":26,"value":339}," default",{"type":21,"tag":113,"props":341,"children":342},{"style":120},[343],{"type":26,"value":344}," defineEventHandler",{"type":21,"tag":113,"props":346,"children":347},{"style":217},[348],{"type":26,"value":349},"(",{"type":21,"tag":113,"props":351,"children":352},{"style":211},[353],{"type":26,"value":354},"async",{"type":21,"tag":113,"props":356,"children":357},{"style":217},[358],{"type":26,"value":359}," (",{"type":21,"tag":113,"props":361,"children":363},{"style":362},"--shiki-default:#E36209",[364],{"type":26,"value":365},"event",{"type":21,"tag":113,"props":367,"children":368},{"style":217},[369],{"type":26,"value":370},") ",{"type":21,"tag":113,"props":372,"children":373},{"style":211},[374],{"type":26,"value":375},"=>",{"type":21,"tag":113,"props":377,"children":378},{"style":217},[379],{"type":26,"value":380}," {\n",{"type":21,"tag":113,"props":382,"children":384},{"class":115,"line":383},8,[385],{"type":21,"tag":113,"props":386,"children":387},{"emptyLinePlaceholder":268},[388],{"type":26,"value":271},{"type":21,"tag":113,"props":390,"children":392},{"class":115,"line":391},9,[393,398,403,407,412,417],{"type":21,"tag":113,"props":394,"children":395},{"style":211},[396],{"type":26,"value":397}," const",{"type":21,"tag":113,"props":399,"children":400},{"style":132},[401],{"type":26,"value":402}," feed",{"type":21,"tag":113,"props":404,"children":405},{"style":211},[406],{"type":26,"value":290},{"type":21,"tag":113,"props":408,"children":409},{"style":211},[410],{"type":26,"value":411}," new",{"type":21,"tag":113,"props":413,"children":414},{"style":120},[415],{"type":26,"value":416}," Feed",{"type":21,"tag":113,"props":418,"children":419},{"style":217},[420],{"type":26,"value":421},"({\n",{"type":21,"tag":113,"props":423,"children":425},{"class":115,"line":424},10,[426,431,436],{"type":21,"tag":113,"props":427,"children":428},{"style":217},[429],{"type":26,"value":430}," title: ",{"type":21,"tag":113,"props":432,"children":433},{"style":126},[434],{"type":26,"value":435},"\"My Title\"",{"type":21,"tag":113,"props":437,"children":438},{"style":217},[439],{"type":26,"value":440},",\n",{"type":21,"tag":113,"props":442,"children":444},{"class":115,"line":443},11,[445,450,455],{"type":21,"tag":113,"props":446,"children":447},{"style":217},[448],{"type":26,"value":449}," description: ",{"type":21,"tag":113,"props":451,"children":452},{"style":126},[453],{"type":26,"value":454},"\"My Description\"",{"type":21,"tag":113,"props":456,"children":457},{"style":217},[458],{"type":26,"value":440},{"type":21,"tag":113,"props":460,"children":462},{"class":115,"line":461},12,[463,468,473],{"type":21,"tag":113,"props":464,"children":465},{"style":217},[466],{"type":26,"value":467}," id: ",{"type":21,"tag":113,"props":469,"children":470},{"style":132},[471],{"type":26,"value":472},"BASE_URL",{"type":21,"tag":113,"props":474,"children":475},{"style":217},[476],{"type":26,"value":440},{"type":21,"tag":113,"props":478,"children":480},{"class":115,"line":479},13,[481,486,490],{"type":21,"tag":113,"props":482,"children":483},{"style":217},[484],{"type":26,"value":485}," link: ",{"type":21,"tag":113,"props":487,"children":488},{"style":132},[489],{"type":26,"value":472},{"type":21,"tag":113,"props":491,"children":492},{"style":217},[493],{"type":26,"value":440},{"type":21,"tag":113,"props":495,"children":497},{"class":115,"line":496},14,[498,503,508],{"type":21,"tag":113,"props":499,"children":500},{"style":217},[501],{"type":26,"value":502}," language: ",{"type":21,"tag":113,"props":504,"children":505},{"style":126},[506],{"type":26,"value":507},"\"en\"",{"type":21,"tag":113,"props":509,"children":510},{"style":217},[511],{"type":26,"value":440},{"type":21,"tag":113,"props":513,"children":515},{"class":115,"line":514},15,[516,521,526,530,535],{"type":21,"tag":113,"props":517,"children":518},{"style":217},[519],{"type":26,"value":520}," image: ",{"type":21,"tag":113,"props":522,"children":523},{"style":126},[524],{"type":26,"value":525},"`${",{"type":21,"tag":113,"props":527,"children":528},{"style":132},[529],{"type":26,"value":472},{"type":21,"tag":113,"props":531,"children":532},{"style":126},[533],{"type":26,"value":534},"}/images/placeholder.png`",{"type":21,"tag":113,"props":536,"children":537},{"style":217},[538],{"type":26,"value":440},{"type":21,"tag":113,"props":540,"children":542},{"class":115,"line":541},16,[543,548,552,556,561],{"type":21,"tag":113,"props":544,"children":545},{"style":217},[546],{"type":26,"value":547}," favicon: ",{"type":21,"tag":113,"props":549,"children":550},{"style":126},[551],{"type":26,"value":525},{"type":21,"tag":113,"props":553,"children":554},{"style":132},[555],{"type":26,"value":472},{"type":21,"tag":113,"props":557,"children":558},{"style":126},[559],{"type":26,"value":560},"}/favicon.ico`",{"type":21,"tag":113,"props":562,"children":563},{"style":217},[564],{"type":26,"value":440},{"type":21,"tag":113,"props":566,"children":568},{"class":115,"line":567},17,[569,574,579,584,589,594,599,604,609,614,619],{"type":21,"tag":113,"props":570,"children":571},{"style":217},[572],{"type":26,"value":573}," copyright: ",{"type":21,"tag":113,"props":575,"children":576},{"style":126},[577],{"type":26,"value":578},"`All rights reserved ${",{"type":21,"tag":113,"props":580,"children":581},{"style":211},[582],{"type":26,"value":583},"new",{"type":21,"tag":113,"props":585,"children":586},{"style":120},[587],{"type":26,"value":588}," Date",{"type":21,"tag":113,"props":590,"children":591},{"style":126},[592],{"type":26,"value":593},"().",{"type":21,"tag":113,"props":595,"children":596},{"style":120},[597],{"type":26,"value":598},"getFullYear",{"type":21,"tag":113,"props":600,"children":601},{"style":126},[602],{"type":26,"value":603},"()",{"type":21,"tag":113,"props":605,"children":606},{"style":126},[607],{"type":26,"value":608},"}, ${",{"type":21,"tag":113,"props":610,"children":611},{"style":132},[612],{"type":26,"value":613},"AUTHOR_NAME",{"type":21,"tag":113,"props":615,"children":616},{"style":126},[617],{"type":26,"value":618},"}`",{"type":21,"tag":113,"props":620,"children":621},{"style":217},[622],{"type":26,"value":440},{"type":21,"tag":113,"props":624,"children":626},{"class":115,"line":625},18,[627,632,636,640],{"type":21,"tag":113,"props":628,"children":629},{"style":217},[630],{"type":26,"value":631}," updated: ",{"type":21,"tag":113,"props":633,"children":634},{"style":211},[635],{"type":26,"value":583},{"type":21,"tag":113,"props":637,"children":638},{"style":120},[639],{"type":26,"value":588},{"type":21,"tag":113,"props":641,"children":642},{"style":217},[643],{"type":26,"value":644},"(),\n",{"type":21,"tag":113,"props":646,"children":648},{"class":115,"line":647},19,[649,654,659],{"type":21,"tag":113,"props":650,"children":651},{"style":217},[652],{"type":26,"value":653}," generator: ",{"type":21,"tag":113,"props":655,"children":656},{"style":126},[657],{"type":26,"value":658},"\"Nuxt static site generation + Feed for Node.js\"",{"type":21,"tag":113,"props":660,"children":661},{"style":217},[662],{"type":26,"value":440},{"type":21,"tag":113,"props":664,"children":666},{"class":115,"line":665},20,[667],{"type":21,"tag":113,"props":668,"children":669},{"style":217},[670],{"type":26,"value":671}," feedLinks: {\n",{"type":21,"tag":113,"props":673,"children":675},{"class":115,"line":674},21,[676,681,685,689],{"type":21,"tag":113,"props":677,"children":678},{"style":217},[679],{"type":26,"value":680}," atom: ",{"type":21,"tag":113,"props":682,"children":683},{"style":126},[684],{"type":26,"value":525},{"type":21,"tag":113,"props":686,"children":687},{"style":132},[688],{"type":26,"value":472},{"type":21,"tag":113,"props":690,"children":691},{"style":126},[692],{"type":26,"value":693},"}/atom`\n",{"type":21,"tag":113,"props":695,"children":697},{"class":115,"line":696},22,[698],{"type":21,"tag":113,"props":699,"children":700},{"style":217},[701],{"type":26,"value":702}," },\n",{"type":21,"tag":113,"props":704,"children":706},{"class":115,"line":705},23,[707],{"type":21,"tag":113,"props":708,"children":709},{"style":217},[710],{"type":26,"value":711}," author: {\n",{"type":21,"tag":113,"props":713,"children":715},{"class":115,"line":714},24,[716,721,725],{"type":21,"tag":113,"props":717,"children":718},{"style":217},[719],{"type":26,"value":720}," name: ",{"type":21,"tag":113,"props":722,"children":723},{"style":132},[724],{"type":26,"value":613},{"type":21,"tag":113,"props":726,"children":727},{"style":217},[728],{"type":26,"value":440},{"type":21,"tag":113,"props":730,"children":732},{"class":115,"line":731},25,[733],{"type":21,"tag":113,"props":734,"children":735},{"style":217},[736],{"type":26,"value":737}," }\n",{"type":21,"tag":113,"props":739,"children":741},{"class":115,"line":740},26,[742],{"type":21,"tag":113,"props":743,"children":744},{"style":217},[745],{"type":26,"value":746}," });\n",{"type":21,"tag":113,"props":748,"children":750},{"class":115,"line":749},27,[751],{"type":21,"tag":113,"props":752,"children":753},{"emptyLinePlaceholder":268},[754],{"type":26,"value":271},{"type":21,"tag":113,"props":756,"children":758},{"class":115,"line":757},28,[759,763,768,772,777,782,787,792],{"type":21,"tag":113,"props":760,"children":761},{"style":211},[762],{"type":26,"value":397},{"type":21,"tag":113,"props":764,"children":765},{"style":132},[766],{"type":26,"value":767}," articles",{"type":21,"tag":113,"props":769,"children":770},{"style":211},[771],{"type":26,"value":290},{"type":21,"tag":113,"props":773,"children":774},{"style":211},[775],{"type":26,"value":776}," await",{"type":21,"tag":113,"props":778,"children":779},{"style":120},[780],{"type":26,"value":781}," serverQueryContent",{"type":21,"tag":113,"props":783,"children":784},{"style":217},[785],{"type":26,"value":786},"(event).",{"type":21,"tag":113,"props":788,"children":789},{"style":120},[790],{"type":26,"value":791},"find",{"type":21,"tag":113,"props":793,"children":794},{"style":217},[795],{"type":26,"value":796},"();\n",{"type":21,"tag":113,"props":798,"children":800},{"class":115,"line":799},29,[801],{"type":21,"tag":113,"props":802,"children":803},{"emptyLinePlaceholder":268},[804],{"type":26,"value":271},{"type":21,"tag":113,"props":806,"children":808},{"class":115,"line":807},30,[809,814,819,824,829,833,837],{"type":21,"tag":113,"props":810,"children":811},{"style":217},[812],{"type":26,"value":813}," articles.",{"type":21,"tag":113,"props":815,"children":816},{"style":120},[817],{"type":26,"value":818},"forEach",{"type":21,"tag":113,"props":820,"children":821},{"style":217},[822],{"type":26,"value":823},"((",{"type":21,"tag":113,"props":825,"children":826},{"style":362},[827],{"type":26,"value":828},"article",{"type":21,"tag":113,"props":830,"children":831},{"style":217},[832],{"type":26,"value":370},{"type":21,"tag":113,"props":834,"children":835},{"style":211},[836],{"type":26,"value":375},{"type":21,"tag":113,"props":838,"children":839},{"style":217},[840],{"type":26,"value":380},{"type":21,"tag":113,"props":842,"children":844},{"class":115,"line":843},31,[845,850,855],{"type":21,"tag":113,"props":846,"children":847},{"style":217},[848],{"type":26,"value":849}," feed.",{"type":21,"tag":113,"props":851,"children":852},{"style":120},[853],{"type":26,"value":854},"addItem",{"type":21,"tag":113,"props":856,"children":857},{"style":217},[858],{"type":26,"value":421},{"type":21,"tag":113,"props":860,"children":862},{"class":115,"line":861},32,[863,868,873,878,883,888],{"type":21,"tag":113,"props":864,"children":865},{"style":217},[866],{"type":26,"value":867}," title: article.title ",{"type":21,"tag":113,"props":869,"children":870},{"style":211},[871],{"type":26,"value":872},"?",{"type":21,"tag":113,"props":874,"children":875},{"style":217},[876],{"type":26,"value":877}," article.title ",{"type":21,"tag":113,"props":879,"children":880},{"style":211},[881],{"type":26,"value":882},":",{"type":21,"tag":113,"props":884,"children":885},{"style":126},[886],{"type":26,"value":887}," \"Missing Title\"",{"type":21,"tag":113,"props":889,"children":890},{"style":217},[891],{"type":26,"value":440},{"type":21,"tag":113,"props":893,"children":895},{"class":115,"line":894},33,[896],{"type":21,"tag":113,"props":897,"children":898},{"style":217},[899],{"type":26,"value":900}," id: article._path,\n",{"type":21,"tag":113,"props":902,"children":904},{"class":115,"line":903},34,[905,910,914,918,923,927,931,936,940],{"type":21,"tag":113,"props":906,"children":907},{"style":217},[908],{"type":26,"value":909}," link: ",{"type":21,"tag":113,"props":911,"children":912},{"style":126},[913],{"type":26,"value":525},{"type":21,"tag":113,"props":915,"children":916},{"style":132},[917],{"type":26,"value":472},{"type":21,"tag":113,"props":919,"children":920},{"style":126},[921],{"type":26,"value":922},"}${",{"type":21,"tag":113,"props":924,"children":925},{"style":217},[926],{"type":26,"value":828},{"type":21,"tag":113,"props":928,"children":929},{"style":126},[930],{"type":26,"value":161},{"type":21,"tag":113,"props":932,"children":933},{"style":217},[934],{"type":26,"value":935},"_path",{"type":21,"tag":113,"props":937,"children":938},{"style":126},[939],{"type":26,"value":618},{"type":21,"tag":113,"props":941,"children":942},{"style":217},[943],{"type":26,"value":440},{"type":21,"tag":113,"props":945,"children":947},{"class":115,"line":946},35,[948],{"type":21,"tag":113,"props":949,"children":950},{"style":217},[951],{"type":26,"value":952}," description: article.description,\n",{"type":21,"tag":113,"props":954,"children":956},{"class":115,"line":955},36,[957],{"type":21,"tag":113,"props":958,"children":959},{"style":217},[960],{"type":26,"value":961}," author: [\n",{"type":21,"tag":113,"props":963,"children":965},{"class":115,"line":964},37,[966],{"type":21,"tag":113,"props":967,"children":968},{"style":217},[969],{"type":26,"value":970}," {\n",{"type":21,"tag":113,"props":972,"children":974},{"class":115,"line":973},38,[975,980,984],{"type":21,"tag":113,"props":976,"children":977},{"style":217},[978],{"type":26,"value":979}," name: ",{"type":21,"tag":113,"props":981,"children":982},{"style":132},[983],{"type":26,"value":613},{"type":21,"tag":113,"props":985,"children":986},{"style":217},[987],{"type":26,"value":440},{"type":21,"tag":113,"props":989,"children":991},{"class":115,"line":990},39,[992],{"type":21,"tag":113,"props":993,"children":994},{"style":217},[995],{"type":26,"value":996}," },\n",{"type":21,"tag":113,"props":998,"children":1000},{"class":115,"line":999},40,[1001],{"type":21,"tag":113,"props":1002,"children":1003},{"style":217},[1004],{"type":26,"value":1005}," ],\n",{"type":21,"tag":113,"props":1007,"children":1009},{"class":115,"line":1008},41,[1010,1015,1019,1023],{"type":21,"tag":113,"props":1011,"children":1012},{"style":217},[1013],{"type":26,"value":1014}," date: ",{"type":21,"tag":113,"props":1016,"children":1017},{"style":211},[1018],{"type":26,"value":583},{"type":21,"tag":113,"props":1020,"children":1021},{"style":120},[1022],{"type":26,"value":588},{"type":21,"tag":113,"props":1024,"children":1025},{"style":217},[1026],{"type":26,"value":1027},"(article.date),\n",{"type":21,"tag":113,"props":1029,"children":1031},{"class":115,"line":1030},42,[1032,1037,1041,1046,1050,1055,1059,1063,1068,1072,1077],{"type":21,"tag":113,"props":1033,"children":1034},{"style":217},[1035],{"type":26,"value":1036}," image: article.cover_image ",{"type":21,"tag":113,"props":1038,"children":1039},{"style":211},[1040],{"type":26,"value":872},{"type":21,"tag":113,"props":1042,"children":1043},{"style":126},[1044],{"type":26,"value":1045}," `${",{"type":21,"tag":113,"props":1047,"children":1048},{"style":132},[1049],{"type":26,"value":472},{"type":21,"tag":113,"props":1051,"children":1052},{"style":126},[1053],{"type":26,"value":1054},"}/${",{"type":21,"tag":113,"props":1056,"children":1057},{"style":217},[1058],{"type":26,"value":828},{"type":21,"tag":113,"props":1060,"children":1061},{"style":126},[1062],{"type":26,"value":161},{"type":21,"tag":113,"props":1064,"children":1065},{"style":217},[1066],{"type":26,"value":1067},"cover_image",{"type":21,"tag":113,"props":1069,"children":1070},{"style":126},[1071],{"type":26,"value":618},{"type":21,"tag":113,"props":1073,"children":1074},{"style":211},[1075],{"type":26,"value":1076}," :",{"type":21,"tag":113,"props":1078,"children":1079},{"style":132},[1080],{"type":26,"value":1081}," undefined\n",{"type":21,"tag":113,"props":1083,"children":1085},{"class":115,"line":1084},43,[1086],{"type":21,"tag":113,"props":1087,"children":1088},{"style":217},[1089],{"type":26,"value":1090}," });\n",{"type":21,"tag":113,"props":1092,"children":1094},{"class":115,"line":1093},44,[1095],{"type":21,"tag":113,"props":1096,"children":1097},{"style":217},[1098],{"type":26,"value":746},{"type":21,"tag":113,"props":1100,"children":1102},{"class":115,"line":1101},45,[1103],{"type":21,"tag":113,"props":1104,"children":1105},{"emptyLinePlaceholder":268},[1106],{"type":26,"value":271},{"type":21,"tag":113,"props":1108,"children":1110},{"class":115,"line":1109},46,[1111,1116,1121,1126],{"type":21,"tag":113,"props":1112,"children":1113},{"style":211},[1114],{"type":26,"value":1115}," return",{"type":21,"tag":113,"props":1117,"children":1118},{"style":217},[1119],{"type":26,"value":1120}," feed.",{"type":21,"tag":113,"props":1122,"children":1123},{"style":120},[1124],{"type":26,"value":1125},"atom1",{"type":21,"tag":113,"props":1127,"children":1128},{"style":217},[1129],{"type":26,"value":796},{"type":21,"tag":113,"props":1131,"children":1133},{"class":115,"line":1132},47,[1134],{"type":21,"tag":113,"props":1135,"children":1136},{"style":217},[1137],{"type":26,"value":1138},"});\n",{"type":21,"tag":22,"props":1140,"children":1141},{},[1142,1144,1150,1152,1158,1160,1166,1168,1174],{"type":26,"value":1143},"And that's just about it! Except, if you are statically generating your website with the ",{"type":21,"tag":109,"props":1145,"children":1147},{"className":1146},[],[1148],{"type":26,"value":1149},"nuxt generate",{"type":26,"value":1151}," command, you will need to configure this server-side route to be pre-rendered on site generation. This is as simple as adding a ",{"type":21,"tag":109,"props":1153,"children":1155},{"className":1154},[],[1156],{"type":26,"value":1157},"nitro",{"type":26,"value":1159}," ",{"type":21,"tag":109,"props":1161,"children":1163},{"className":1162},[],[1164],{"type":26,"value":1165},"prerender",{"type":26,"value":1167}," definition in your ",{"type":21,"tag":109,"props":1169,"children":1171},{"className":1170},[],[1172],{"type":26,"value":1173},"nuxt.config.ts",{"type":26,"value":1175}," file, like so:",{"type":21,"tag":102,"props":1177,"children":1179},{"className":199,"code":1178,"language":201,"meta":7,"style":7},"nitro: {\n prerender: {\n routes: ['/atom']\n }\n}\n",[1180],{"type":21,"tag":109,"props":1181,"children":1182},{"__ignoreMap":7},[1183,1195,1207,1230,1238],{"type":21,"tag":113,"props":1184,"children":1185},{"class":115,"line":116},[1186,1190],{"type":21,"tag":113,"props":1187,"children":1188},{"style":120},[1189],{"type":26,"value":1157},{"type":21,"tag":113,"props":1191,"children":1192},{"style":217},[1193],{"type":26,"value":1194},": {\n",{"type":21,"tag":113,"props":1196,"children":1197},{"class":115,"line":238},[1198,1203],{"type":21,"tag":113,"props":1199,"children":1200},{"style":120},[1201],{"type":26,"value":1202}," prerender",{"type":21,"tag":113,"props":1204,"children":1205},{"style":217},[1206],{"type":26,"value":1194},{"type":21,"tag":113,"props":1208,"children":1209},{"class":115,"line":264},[1210,1215,1220,1225],{"type":21,"tag":113,"props":1211,"children":1212},{"style":120},[1213],{"type":26,"value":1214}," routes",{"type":21,"tag":113,"props":1216,"children":1217},{"style":217},[1218],{"type":26,"value":1219},": [",{"type":21,"tag":113,"props":1221,"children":1222},{"style":126},[1223],{"type":26,"value":1224},"'/atom'",{"type":21,"tag":113,"props":1226,"children":1227},{"style":217},[1228],{"type":26,"value":1229},"]\n",{"type":21,"tag":113,"props":1231,"children":1232},{"class":115,"line":274},[1233],{"type":21,"tag":113,"props":1234,"children":1235},{"style":217},[1236],{"type":26,"value":1237}," }\n",{"type":21,"tag":113,"props":1239,"children":1240},{"class":115,"line":298},[1241],{"type":21,"tag":113,"props":1242,"children":1243},{"style":217},[1244],{"type":26,"value":1245},"}\n",{"type":21,"tag":52,"props":1247,"children":1249},{"id":1248},"bonus",[1250],{"type":26,"value":1251},"Bonus",{"type":21,"tag":22,"props":1253,"children":1254},{},[1255,1257,1263],{"type":26,"value":1256},"You may also be interested in adding a ",{"type":21,"tag":109,"props":1258,"children":1260},{"className":1259},[],[1261],{"type":26,"value":1262},"sitemap.xml",{"type":26,"value":1264}," to your website. This can be done in almost an identical fashion!",{"type":21,"tag":22,"props":1266,"children":1267},{},[1268],{"type":26,"value":1269},"Install the dependency:",{"type":21,"tag":102,"props":1271,"children":1273},{"className":104,"code":1272,"language":106,"meta":7,"style":7},"npm i -D sitemap\n",[1274],{"type":21,"tag":109,"props":1275,"children":1276},{"__ignoreMap":7},[1277],{"type":21,"tag":113,"props":1278,"children":1279},{"class":115,"line":116},[1280,1284,1288,1292],{"type":21,"tag":113,"props":1281,"children":1282},{"style":120},[1283],{"type":26,"value":123},{"type":21,"tag":113,"props":1285,"children":1286},{"style":126},[1287],{"type":26,"value":129},{"type":21,"tag":113,"props":1289,"children":1290},{"style":132},[1291],{"type":26,"value":135},{"type":21,"tag":113,"props":1293,"children":1294},{"style":126},[1295],{"type":26,"value":1296}," sitemap\n",{"type":21,"tag":22,"props":1298,"children":1299},{},[1300,1302,1308],{"type":26,"value":1301},"Create a route at ",{"type":21,"tag":109,"props":1303,"children":1305},{"className":1304},[],[1306],{"type":26,"value":1307},"server/routes/sitemap.xml.ts",{"type":26,"value":882},{"type":21,"tag":102,"props":1310,"children":1312},{"className":199,"code":1311,"language":201,"meta":7,"style":7},"import { serverQueryContent } from '#content/server';\nimport { SitemapStream, streamToPromise } from 'sitemap';\n\nexport default defineEventHandler(async (event) => {\n const articles = await serverQueryContent(event).find();\n\n const sitemap = new SitemapStream({ hostname: 'https://my-website.com/' });\n\n // Add non nuxt content endpoints here\n sitemap.write({ url: '/' });\n sitemap.write({ url: '/articles' });\n\n // Dynamically generate routes for Nuxt markdown content\n articles.forEach((article) => sitemap.write({ url: article._path, changefreq: 'monthly' }));\n sitemap.end();\n\n return (await streamToPromise(sitemap));\n});\n",[1313],{"type":21,"tag":109,"props":1314,"children":1315},{"__ignoreMap":7},[1316,1339,1364,1371,1414,1449,1456,1496,1503,1512,1539,1563,1570,1578,1629,1645,1652,1678],{"type":21,"tag":113,"props":1317,"children":1318},{"class":115,"line":116},[1319,1323,1327,1331,1335],{"type":21,"tag":113,"props":1320,"children":1321},{"style":211},[1322],{"type":26,"value":214},{"type":21,"tag":113,"props":1324,"children":1325},{"style":217},[1326],{"type":26,"value":220},{"type":21,"tag":113,"props":1328,"children":1329},{"style":211},[1330],{"type":26,"value":225},{"type":21,"tag":113,"props":1332,"children":1333},{"style":126},[1334],{"type":26,"value":230},{"type":21,"tag":113,"props":1336,"children":1337},{"style":217},[1338],{"type":26,"value":235},{"type":21,"tag":113,"props":1340,"children":1341},{"class":115,"line":238},[1342,1346,1351,1355,1360],{"type":21,"tag":113,"props":1343,"children":1344},{"style":211},[1345],{"type":26,"value":214},{"type":21,"tag":113,"props":1347,"children":1348},{"style":217},[1349],{"type":26,"value":1350}," { SitemapStream, streamToPromise } ",{"type":21,"tag":113,"props":1352,"children":1353},{"style":211},[1354],{"type":26,"value":225},{"type":21,"tag":113,"props":1356,"children":1357},{"style":126},[1358],{"type":26,"value":1359}," 'sitemap'",{"type":21,"tag":113,"props":1361,"children":1362},{"style":217},[1363],{"type":26,"value":235},{"type":21,"tag":113,"props":1365,"children":1366},{"class":115,"line":264},[1367],{"type":21,"tag":113,"props":1368,"children":1369},{"emptyLinePlaceholder":268},[1370],{"type":26,"value":271},{"type":21,"tag":113,"props":1372,"children":1373},{"class":115,"line":274},[1374,1378,1382,1386,1390,1394,1398,1402,1406,1410],{"type":21,"tag":113,"props":1375,"children":1376},{"style":211},[1377],{"type":26,"value":334},{"type":21,"tag":113,"props":1379,"children":1380},{"style":211},[1381],{"type":26,"value":339},{"type":21,"tag":113,"props":1383,"children":1384},{"style":120},[1385],{"type":26,"value":344},{"type":21,"tag":113,"props":1387,"children":1388},{"style":217},[1389],{"type":26,"value":349},{"type":21,"tag":113,"props":1391,"children":1392},{"style":211},[1393],{"type":26,"value":354},{"type":21,"tag":113,"props":1395,"children":1396},{"style":217},[1397],{"type":26,"value":359},{"type":21,"tag":113,"props":1399,"children":1400},{"style":362},[1401],{"type":26,"value":365},{"type":21,"tag":113,"props":1403,"children":1404},{"style":217},[1405],{"type":26,"value":370},{"type":21,"tag":113,"props":1407,"children":1408},{"style":211},[1409],{"type":26,"value":375},{"type":21,"tag":113,"props":1411,"children":1412},{"style":217},[1413],{"type":26,"value":380},{"type":21,"tag":113,"props":1415,"children":1416},{"class":115,"line":298},[1417,1421,1425,1429,1433,1437,1441,1445],{"type":21,"tag":113,"props":1418,"children":1419},{"style":211},[1420],{"type":26,"value":397},{"type":21,"tag":113,"props":1422,"children":1423},{"style":132},[1424],{"type":26,"value":767},{"type":21,"tag":113,"props":1426,"children":1427},{"style":211},[1428],{"type":26,"value":290},{"type":21,"tag":113,"props":1430,"children":1431},{"style":211},[1432],{"type":26,"value":776},{"type":21,"tag":113,"props":1434,"children":1435},{"style":120},[1436],{"type":26,"value":781},{"type":21,"tag":113,"props":1438,"children":1439},{"style":217},[1440],{"type":26,"value":786},{"type":21,"tag":113,"props":1442,"children":1443},{"style":120},[1444],{"type":26,"value":791},{"type":21,"tag":113,"props":1446,"children":1447},{"style":217},[1448],{"type":26,"value":796},{"type":21,"tag":113,"props":1450,"children":1451},{"class":115,"line":320},[1452],{"type":21,"tag":113,"props":1453,"children":1454},{"emptyLinePlaceholder":268},[1455],{"type":26,"value":271},{"type":21,"tag":113,"props":1457,"children":1458},{"class":115,"line":328},[1459,1463,1468,1472,1476,1481,1486,1491],{"type":21,"tag":113,"props":1460,"children":1461},{"style":211},[1462],{"type":26,"value":397},{"type":21,"tag":113,"props":1464,"children":1465},{"style":132},[1466],{"type":26,"value":1467}," sitemap",{"type":21,"tag":113,"props":1469,"children":1470},{"style":211},[1471],{"type":26,"value":290},{"type":21,"tag":113,"props":1473,"children":1474},{"style":211},[1475],{"type":26,"value":411},{"type":21,"tag":113,"props":1477,"children":1478},{"style":120},[1479],{"type":26,"value":1480}," SitemapStream",{"type":21,"tag":113,"props":1482,"children":1483},{"style":217},[1484],{"type":26,"value":1485},"({ hostname: ",{"type":21,"tag":113,"props":1487,"children":1488},{"style":126},[1489],{"type":26,"value":1490},"'https://my-website.com/'",{"type":21,"tag":113,"props":1492,"children":1493},{"style":217},[1494],{"type":26,"value":1495}," });\n",{"type":21,"tag":113,"props":1497,"children":1498},{"class":115,"line":383},[1499],{"type":21,"tag":113,"props":1500,"children":1501},{"emptyLinePlaceholder":268},[1502],{"type":26,"value":271},{"type":21,"tag":113,"props":1504,"children":1505},{"class":115,"line":391},[1506],{"type":21,"tag":113,"props":1507,"children":1509},{"style":1508},"--shiki-default:#6A737D",[1510],{"type":26,"value":1511}," // Add non nuxt content endpoints here\n",{"type":21,"tag":113,"props":1513,"children":1514},{"class":115,"line":424},[1515,1520,1525,1530,1535],{"type":21,"tag":113,"props":1516,"children":1517},{"style":217},[1518],{"type":26,"value":1519}," sitemap.",{"type":21,"tag":113,"props":1521,"children":1522},{"style":120},[1523],{"type":26,"value":1524},"write",{"type":21,"tag":113,"props":1526,"children":1527},{"style":217},[1528],{"type":26,"value":1529},"({ url: ",{"type":21,"tag":113,"props":1531,"children":1532},{"style":126},[1533],{"type":26,"value":1534},"'/'",{"type":21,"tag":113,"props":1536,"children":1537},{"style":217},[1538],{"type":26,"value":1495},{"type":21,"tag":113,"props":1540,"children":1541},{"class":115,"line":443},[1542,1546,1550,1554,1559],{"type":21,"tag":113,"props":1543,"children":1544},{"style":217},[1545],{"type":26,"value":1519},{"type":21,"tag":113,"props":1547,"children":1548},{"style":120},[1549],{"type":26,"value":1524},{"type":21,"tag":113,"props":1551,"children":1552},{"style":217},[1553],{"type":26,"value":1529},{"type":21,"tag":113,"props":1555,"children":1556},{"style":126},[1557],{"type":26,"value":1558},"'/articles'",{"type":21,"tag":113,"props":1560,"children":1561},{"style":217},[1562],{"type":26,"value":1495},{"type":21,"tag":113,"props":1564,"children":1565},{"class":115,"line":461},[1566],{"type":21,"tag":113,"props":1567,"children":1568},{"emptyLinePlaceholder":268},[1569],{"type":26,"value":271},{"type":21,"tag":113,"props":1571,"children":1572},{"class":115,"line":479},[1573],{"type":21,"tag":113,"props":1574,"children":1575},{"style":1508},[1576],{"type":26,"value":1577}," // Dynamically generate routes for Nuxt markdown content\n",{"type":21,"tag":113,"props":1579,"children":1580},{"class":115,"line":496},[1581,1585,1589,1593,1597,1601,1605,1610,1614,1619,1624],{"type":21,"tag":113,"props":1582,"children":1583},{"style":217},[1584],{"type":26,"value":813},{"type":21,"tag":113,"props":1586,"children":1587},{"style":120},[1588],{"type":26,"value":818},{"type":21,"tag":113,"props":1590,"children":1591},{"style":217},[1592],{"type":26,"value":823},{"type":21,"tag":113,"props":1594,"children":1595},{"style":362},[1596],{"type":26,"value":828},{"type":21,"tag":113,"props":1598,"children":1599},{"style":217},[1600],{"type":26,"value":370},{"type":21,"tag":113,"props":1602,"children":1603},{"style":211},[1604],{"type":26,"value":375},{"type":21,"tag":113,"props":1606,"children":1607},{"style":217},[1608],{"type":26,"value":1609}," sitemap.",{"type":21,"tag":113,"props":1611,"children":1612},{"style":120},[1613],{"type":26,"value":1524},{"type":21,"tag":113,"props":1615,"children":1616},{"style":217},[1617],{"type":26,"value":1618},"({ url: article._path, changefreq: ",{"type":21,"tag":113,"props":1620,"children":1621},{"style":126},[1622],{"type":26,"value":1623},"'monthly'",{"type":21,"tag":113,"props":1625,"children":1626},{"style":217},[1627],{"type":26,"value":1628}," }));\n",{"type":21,"tag":113,"props":1630,"children":1631},{"class":115,"line":514},[1632,1636,1641],{"type":21,"tag":113,"props":1633,"children":1634},{"style":217},[1635],{"type":26,"value":1519},{"type":21,"tag":113,"props":1637,"children":1638},{"style":120},[1639],{"type":26,"value":1640},"end",{"type":21,"tag":113,"props":1642,"children":1643},{"style":217},[1644],{"type":26,"value":796},{"type":21,"tag":113,"props":1646,"children":1647},{"class":115,"line":541},[1648],{"type":21,"tag":113,"props":1649,"children":1650},{"emptyLinePlaceholder":268},[1651],{"type":26,"value":271},{"type":21,"tag":113,"props":1653,"children":1654},{"class":115,"line":567},[1655,1659,1663,1668,1673],{"type":21,"tag":113,"props":1656,"children":1657},{"style":211},[1658],{"type":26,"value":1115},{"type":21,"tag":113,"props":1660,"children":1661},{"style":217},[1662],{"type":26,"value":359},{"type":21,"tag":113,"props":1664,"children":1665},{"style":211},[1666],{"type":26,"value":1667},"await",{"type":21,"tag":113,"props":1669,"children":1670},{"style":120},[1671],{"type":26,"value":1672}," streamToPromise",{"type":21,"tag":113,"props":1674,"children":1675},{"style":217},[1676],{"type":26,"value":1677},"(sitemap));\n",{"type":21,"tag":113,"props":1679,"children":1680},{"class":115,"line":625},[1681],{"type":21,"tag":113,"props":1682,"children":1683},{"style":217},[1684],{"type":26,"value":1138},{"type":21,"tag":22,"props":1686,"children":1687},{},[1688,1690,1695,1697,1702],{"type":26,"value":1689},"And add the ",{"type":21,"tag":109,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":26,"value":1165},{"type":26,"value":1696}," entry in your ",{"type":21,"tag":109,"props":1698,"children":1700},{"className":1699},[],[1701],{"type":26,"value":1173},{"type":26,"value":882},{"type":21,"tag":102,"props":1704,"children":1706},{"className":199,"code":1705,"language":201,"meta":7,"style":7},"nitro: {\n prerender: {\n routes: ['/sitemap.xml', '/atom']\n }\n}\n",[1707],{"type":21,"tag":109,"props":1708,"children":1709},{"__ignoreMap":7},[1710,1721,1732,1761,1768],{"type":21,"tag":113,"props":1711,"children":1712},{"class":115,"line":116},[1713,1717],{"type":21,"tag":113,"props":1714,"children":1715},{"style":120},[1716],{"type":26,"value":1157},{"type":21,"tag":113,"props":1718,"children":1719},{"style":217},[1720],{"type":26,"value":1194},{"type":21,"tag":113,"props":1722,"children":1723},{"class":115,"line":238},[1724,1728],{"type":21,"tag":113,"props":1725,"children":1726},{"style":120},[1727],{"type":26,"value":1202},{"type":21,"tag":113,"props":1729,"children":1730},{"style":217},[1731],{"type":26,"value":1194},{"type":21,"tag":113,"props":1733,"children":1734},{"class":115,"line":264},[1735,1739,1743,1748,1753,1757],{"type":21,"tag":113,"props":1736,"children":1737},{"style":120},[1738],{"type":26,"value":1214},{"type":21,"tag":113,"props":1740,"children":1741},{"style":217},[1742],{"type":26,"value":1219},{"type":21,"tag":113,"props":1744,"children":1745},{"style":126},[1746],{"type":26,"value":1747},"'/sitemap.xml'",{"type":21,"tag":113,"props":1749,"children":1750},{"style":217},[1751],{"type":26,"value":1752},", ",{"type":21,"tag":113,"props":1754,"children":1755},{"style":126},[1756],{"type":26,"value":1224},{"type":21,"tag":113,"props":1758,"children":1759},{"style":217},[1760],{"type":26,"value":1229},{"type":21,"tag":113,"props":1762,"children":1763},{"class":115,"line":274},[1764],{"type":21,"tag":113,"props":1765,"children":1766},{"style":217},[1767],{"type":26,"value":1237},{"type":21,"tag":113,"props":1769,"children":1770},{"class":115,"line":298},[1771],{"type":21,"tag":113,"props":1772,"children":1773},{"style":217},[1774],{"type":26,"value":1245},{"type":21,"tag":1776,"props":1777,"children":1778},"style",{},[1779],{"type":26,"value":1780},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":238,"depth":238,"links":1782},[1783,1784,1785],{"id":54,"depth":238,"text":57},{"id":83,"depth":238,"text":86},{"id":1248,"depth":238,"text":1251},"markdown","content:articles:nuxt-content-rss-feed.md","content","articles/nuxt-content-rss-feed.md","articles/nuxt-content-rss-feed","md",1720229315489] \ No newline at end of file diff --git a/articles/nuxt-content-rss-feed/index.html b/articles/nuxt-content-rss-feed/index.html index d800b754..641114fe 100644 --- a/articles/nuxt-content-rss-feed/index.html +++ b/articles/nuxt-content-rss-feed/index.html @@ -4,32 +4,33 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - -

            How To Add an RSS Feed to a Nuxt Website

            2024-01-06

            If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.

            Preface

            In version 2 of Nuxt, the community module, nuxt-community/feed-module was a popular choice for adding an RSS feed to your website. However, there has been an unresolved open issue since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward.

            Instructions

            First, install the feed library into your project:

            npm i -D feed
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            How To Add an RSS Feed to a Nuxt Website

            If you are a user of Nuxt Content and you wish to configure an RSS feed for your website, it's a surprisingly straight forward process! In this article, we will walk through the code changes required to host an RSS feed for both a statically generated, and Universal Nuxt application.

            Preface

            In version 2 of Nuxt, the community module, nuxt-community/feed-module was a popular choice for adding an RSS feed to your website. However, there has been an unresolved open issue since April 1st, 2022 to add support for Nuxt v3. Thankfully, implementing this feature without a module is relatively straight forward.

            Instructions

            First, install the feed library into your project:

            npm i -D feed
             

            Then, create a server/ folder in your project if it does not already exist, and create a file named server/routes/atom.ts.

            Here, we will leverage the feed library and construct an XML representation of our Nuxt content. As you can see, we first define our feed with metadata associated with our RSS feed. This will be used by RSS readers to provide context to the end user. Then, we query our Nuxt content with serverQueryContent and append a feed.addItem for each article.

            import { serverQueryContent } from '#content/server';
             import { Feed } from 'feed';
             
            @@ -106,5 +107,5 @@
                 routes: ['/sitemap.xml', '/atom']
               }
             }
            -
            - \ No newline at end of file +
            + \ No newline at end of file diff --git a/articles/nuxt-v3-migration/_payload.json b/articles/nuxt-v3-migration/_payload.json index 7ce1cab2..c01672ee 100644 --- a/articles/nuxt-v3-migration/_payload.json +++ b/articles/nuxt-v3-migration/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":124},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":13,"excerpt":15,"body":25,"_type":119,"_id":120,"_source":121,"_file":122,"_extension":123},"/articles/nuxt-v3-migration","articles",false,"","This Website Has Been Migrated to Nuxt 3 🎉","This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","2022-12-31",[12],"nuxt",[14],"web",{"type":16,"children":17},"root",[18],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23],{"type":24,"value":9},"text",{"type":16,"children":26,"toc":116},[27,31,47,56,61,66,111],{"type":19,"tag":20,"props":28,"children":29},{},[30],{"type":24,"value":9},{"type":19,"tag":20,"props":32,"children":33},{},[34,36,45],{"type":24,"value":35},"If you're curious what changes were required to make the migration, you can check out ",{"type":19,"tag":37,"props":38,"children":42},"a",{"href":39,"rel":40},"https://github.com/cmpadden/cmpadden.github.io/pull/3",[41],"nofollow",[43],{"type":24,"value":44},"pull request #3",{"type":24,"value":46}," in the GitHub repository.",{"type":19,"tag":20,"props":48,"children":49},{},[50],{"type":19,"tag":51,"props":52,"children":55},"img",{"alt":53,"src":54},"Screenshot of Nuxt Migration Pull Request","/images/nuxt-migration-pr.png",[],{"type":19,"tag":20,"props":57,"children":58},{},[59],{"type":24,"value":60},"While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious.\nFor this reason, I opted to generate a new project entirely, and port existing code to this clean slate.\nI believe that this resulted in a project with a bit less cruft.",{"type":19,"tag":20,"props":62,"children":63},{},[64],{"type":24,"value":65},"The most valuable resources for making these changes include:",{"type":19,"tag":67,"props":68,"children":69},"ul",{},[70,81,91,101],{"type":19,"tag":71,"props":72,"children":73},"li",{},[74],{"type":19,"tag":37,"props":75,"children":78},{"href":76,"rel":77},"https://nuxt.com/docs/migration/overview",[41],[79],{"type":24,"value":80},"The Nuxt Migration Guide",{"type":19,"tag":71,"props":82,"children":83},{},[84],{"type":19,"tag":37,"props":85,"children":88},{"href":86,"rel":87},"https://nuxt.com/docs/getting-started/introduction",[41],[89],{"type":24,"value":90},"The Nuxt Framework Guide",{"type":19,"tag":71,"props":92,"children":93},{},[94],{"type":19,"tag":37,"props":95,"children":98},{"href":96,"rel":97},"https://tailwindcss.nuxt.dev/",[41],[99],{"type":24,"value":100},"Nuxt Tailwind Module Documentation",{"type":19,"tag":71,"props":102,"children":103},{},[104],{"type":19,"tag":37,"props":105,"children":108},{"href":106,"rel":107},"https://content.nuxtjs.org/",[41],[109],{"type":24,"value":110},"Nuxt Content Module Documentation",{"type":19,"tag":20,"props":112,"children":113},{},[114],{"type":24,"value":115},"Part of the delay for doing this upgrade was in waiting for module developers to support this major release.\nI'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available!\nI just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3.",{"title":7,"searchDepth":117,"depth":117,"links":118},2,[],"markdown","content:articles:nuxt-v3-migration.md","content","articles/nuxt-v3-migration.md","md",1718891181757] \ No newline at end of file +[{"data":1,"prerenderedAt":125},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":13,"excerpt":15,"body":25,"_type":119,"_id":120,"_source":121,"_file":122,"_stem":123,"_extension":124},"/articles/nuxt-v3-migration","articles",false,"","This Website Has Been Migrated to Nuxt 3 🎉","This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years.\nNot to mention, all of the great plugins in the Vue ecosystem!","2022-12-31",[12],"nuxt",[14],"web",{"type":16,"children":17},"root",[18],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23],{"type":24,"value":9},"text",{"type":16,"children":26,"toc":116},[27,31,47,56,61,66,111],{"type":19,"tag":20,"props":28,"children":29},{},[30],{"type":24,"value":9},{"type":19,"tag":20,"props":32,"children":33},{},[34,36,45],{"type":24,"value":35},"If you're curious what changes were required to make the migration, you can check out ",{"type":19,"tag":37,"props":38,"children":42},"a",{"href":39,"rel":40},"https://github.com/cmpadden/cmpadden.github.io/pull/3",[41],"nofollow",[43],{"type":24,"value":44},"pull request #3",{"type":24,"value":46}," in the GitHub repository.",{"type":19,"tag":20,"props":48,"children":49},{},[50],{"type":19,"tag":51,"props":52,"children":55},"img",{"alt":53,"src":54},"Screenshot of Nuxt Migration Pull Request","/images/nuxt-migration-pr.png",[],{"type":19,"tag":20,"props":57,"children":58},{},[59],{"type":24,"value":60},"While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious.\nFor this reason, I opted to generate a new project entirely, and port existing code to this clean slate.\nI believe that this resulted in a project with a bit less cruft.",{"type":19,"tag":20,"props":62,"children":63},{},[64],{"type":24,"value":65},"The most valuable resources for making these changes include:",{"type":19,"tag":67,"props":68,"children":69},"ul",{},[70,81,91,101],{"type":19,"tag":71,"props":72,"children":73},"li",{},[74],{"type":19,"tag":37,"props":75,"children":78},{"href":76,"rel":77},"https://nuxt.com/docs/migration/overview",[41],[79],{"type":24,"value":80},"The Nuxt Migration Guide",{"type":19,"tag":71,"props":82,"children":83},{},[84],{"type":19,"tag":37,"props":85,"children":88},{"href":86,"rel":87},"https://nuxt.com/docs/getting-started/introduction",[41],[89],{"type":24,"value":90},"The Nuxt Framework Guide",{"type":19,"tag":71,"props":92,"children":93},{},[94],{"type":19,"tag":37,"props":95,"children":98},{"href":96,"rel":97},"https://tailwindcss.nuxt.dev/",[41],[99],{"type":24,"value":100},"Nuxt Tailwind Module Documentation",{"type":19,"tag":71,"props":102,"children":103},{},[104],{"type":19,"tag":37,"props":105,"children":108},{"href":106,"rel":107},"https://content.nuxtjs.org/",[41],[109],{"type":24,"value":110},"Nuxt Content Module Documentation",{"type":19,"tag":20,"props":112,"children":113},{},[114],{"type":24,"value":115},"Part of the delay for doing this upgrade was in waiting for module developers to support this major release.\nI'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available!\nI just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3.",{"title":7,"searchDepth":117,"depth":117,"links":118},2,[],"markdown","content:articles:nuxt-v3-migration.md","content","articles/nuxt-v3-migration.md","articles/nuxt-v3-migration","md",1720229315494] \ No newline at end of file diff --git a/articles/nuxt-v3-migration/index.html b/articles/nuxt-v3-migration/index.html index 7a3330fb..fbb9b2f0 100644 --- a/articles/nuxt-v3-migration/index.html +++ b/articles/nuxt-v3-migration/index.html @@ -4,31 +4,32 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - -

            This Website Has Been Migrated to Nuxt 3 🎉

            2022-12-31

            This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years. + + + + + + + + + + + +

            This Website Has Been Migrated to Nuxt 3 🎉

            This website has been migrated to the latest version of the Nuxt web framework, and with it comes all of the exciting goodies that the Vue and Nuxt teams have been concocting over the past few years. Not to mention, all of the great plugins in the Vue ecosystem!

            If you're curious what changes were required to make the migration, you can check out pull request #3 in the GitHub repository.

            Screenshot of Nuxt Migration Pull Request

            While the documentation for making this migration is great, there were many breaking changes, and the overall process was quite tedious. For this reason, I opted to generate a new project entirely, and port existing code to this clean slate. I believe that this resulted in a project with a bit less cruft.

            The most valuable resources for making these changes include:

            Part of the delay for doing this upgrade was in waiting for module developers to support this major release. I'm super thankful for all of the hard work they've don, and I'm excited to explore all of the new features available! -I just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3.

            - \ No newline at end of file +I just hope that the breaking changes in this release don't cause too much fracturing of the community, as it does feel like déjà vu of Python 2 and 3.

            + \ No newline at end of file diff --git a/articles/persistent-archlinux-usb/_payload.json b/articles/persistent-archlinux-usb/_payload.json index 40365515..81b0c85c 100644 --- a/articles/persistent-archlinux-usb/_payload.json +++ b/articles/persistent-archlinux-usb/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":1336},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":26,"_type":1331,"_id":1332,"_source":1333,"_file":1334,"_extension":1335},"/articles/persistent-archlinux-usb","articles",false,"","Create a Persistent Arch Linux Bootable USB with Vagrant","When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","2020-01-09",[12,13],"vagrant","archlinux",[15],"linux",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":1320},[28,32,39,85,91,98,115,152,165,190,246,354,367,388,654,660,674,681,705,825,831,846,885,908,941,947,1002,1067,1073,1081,1089,1097,1120,1128,1133,1138,1144,1174,1204,1210,1314],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":33,"props":34,"children":36},"h1",{"id":35},"preface",[37],{"type":25,"value":38},"Preface",{"type":20,"tag":21,"props":40,"children":41},{},[42,44,51,53,83],{"type":25,"value":43},"The original intention was to use Docker for this process -- leveraging the\n",{"type":20,"tag":45,"props":46,"children":48},"code",{"className":47},[],[49],{"type":25,"value":50},"--device",{"type":25,"value":52}," flag and mounting the target USB device in the Docker container,\nbut the underlying hypervisor in Docker Desktop for Mac does not support this.\n",{"type":20,"tag":54,"props":55,"children":56},"sup",{},[57,66,68,75,76],{"type":20,"tag":58,"props":59,"children":63},"a",{"href":60,"rel":61},"https://docs.docker.com/docker-for-mac/docker-toolbox/",[62],"nofollow",[64],{"type":25,"value":65},"1",{"type":25,"value":67}," ",{"type":20,"tag":58,"props":69,"children":72},{"href":70,"rel":71},"https://github.com/moby/hyperkit",[62],[73],{"type":25,"value":74},"2",{"type":25,"value":67},{"type":20,"tag":58,"props":77,"children":80},{"href":78,"rel":79},"https://github.com/docker/for-mac/issues/900",[62],[81],{"type":25,"value":82},"3",{"type":25,"value":84}," While there are workarounds using Docker\nMachine, Vagrant felt like the path of least resistance.",{"type":20,"tag":33,"props":86,"children":88},{"id":87},"instructions",[89],{"type":25,"value":90},"Instructions",{"type":20,"tag":92,"props":93,"children":95},"h2",{"id":94},"create-an-arch-linux-virtual-machine-with-vagrant",[96],{"type":25,"value":97},"Create an Arch Linux Virtual Machine with Vagrant",{"type":20,"tag":21,"props":99,"children":100},{},[101,103,113],{"type":25,"value":102},"Get the latest Arch Linux image ",{"type":20,"tag":54,"props":104,"children":105},{},[106],{"type":20,"tag":58,"props":107,"children":110},{"href":108,"rel":109},"https://app.vagrantup.com/archlinux/boxes/archlinux",[62],[111],{"type":25,"value":112},"4",{"type":25,"value":114}," from the Vagrant Cloud Box\nCatalog.",{"type":20,"tag":116,"props":117,"children":121},"pre",{"code":118,"language":119,"meta":7,"className":120,"style":7},"vagrant box add archlinux/archlinux\n","bash","language-bash shiki shiki-themes github-light",[122],{"type":20,"tag":45,"props":123,"children":124},{"__ignoreMap":7},[125],{"type":20,"tag":126,"props":127,"children":130},"span",{"class":128,"line":129},"line",1,[131,136,142,147],{"type":20,"tag":126,"props":132,"children":134},{"style":133},"--shiki-default:#6F42C1",[135],{"type":25,"value":12},{"type":20,"tag":126,"props":137,"children":139},{"style":138},"--shiki-default:#032F62",[140],{"type":25,"value":141}," box",{"type":20,"tag":126,"props":143,"children":144},{"style":138},[145],{"type":25,"value":146}," add",{"type":20,"tag":126,"props":148,"children":149},{"style":138},[150],{"type":25,"value":151}," archlinux/archlinux\n",{"type":20,"tag":21,"props":153,"children":154},{},[155,157,163],{"type":25,"value":156},"Determine the USB vendor information for the thumb-drive that we will\npass-through to the virtual machine. Using the ",{"type":20,"tag":45,"props":158,"children":160},{"className":159},[],[161],{"type":25,"value":162},"VBoxManage",{"type":25,"value":164}," utility that comes\nwith Virtual Box, list the devices, and make note of the Vendor and Product ID.",{"type":20,"tag":116,"props":166,"children":168},{"code":167,"language":119,"meta":7,"className":120,"style":7}," VBoxManage list usbhost\n",[169],{"type":20,"tag":45,"props":170,"children":171},{"__ignoreMap":7},[172],{"type":20,"tag":126,"props":173,"children":174},{"class":128,"line":129},[175,180,185],{"type":20,"tag":126,"props":176,"children":177},{"style":133},[178],{"type":25,"value":179}," VBoxManage",{"type":20,"tag":126,"props":181,"children":182},{"style":138},[183],{"type":25,"value":184}," list",{"type":20,"tag":126,"props":186,"children":187},{"style":138},[188],{"type":25,"value":189}," usbhost\n",{"type":20,"tag":21,"props":191,"children":192},{},[193,195,201,203,209,211,229,231,237,239,244],{"type":25,"value":194},"Create a ",{"type":20,"tag":45,"props":196,"children":198},{"className":197},[],[199],{"type":25,"value":200},"Vagrantfile",{"type":25,"value":202}," with ",{"type":20,"tag":45,"props":204,"children":206},{"className":205},[],[207],{"type":25,"value":208},"archlinx/archlinux",{"type":25,"value":210}," as the target box, and the USB\ndevice information that is passed through. ",{"type":20,"tag":54,"props":212,"children":213},{},[214,221,222],{"type":20,"tag":58,"props":215,"children":218},{"href":216,"rel":217},"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/",[62],[219],{"type":25,"value":220},"5",{"type":25,"value":67},{"type":20,"tag":58,"props":223,"children":226},{"href":224,"rel":225},"https://gist.github.com/dscape/7d829c0c116ef419f963",[62],[227],{"type":25,"value":228},"6",{"type":25,"value":230}," Vagrant\noffers a handy customization parameter ",{"type":20,"tag":45,"props":232,"children":234},{"className":233},[],[235],{"type":25,"value":236},"vb.customize",{"type":25,"value":238}," that calls the\n",{"type":20,"tag":45,"props":240,"children":242},{"className":241},[],[243],{"type":25,"value":162},{"type":25,"value":245}," command under-the-hood, allowing one to enable the guest machine\nto access the host machine's USB devices.",{"type":20,"tag":116,"props":247,"children":251},{"code":248,"language":249,"meta":7,"className":250,"style":7},"# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\nVagrant.configure(\"2\") do |config|\n config.vm.box = \"archlinux/archlinux\"\n config.vm.provider \"virtualbox\" do |vb|\n vb.name = \"archlinux\"\n vb.customize ['modifyvm', :id, '--usb', 'on']\n vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n end\nend\n","txt","language-txt shiki shiki-themes github-light",[252],{"type":20,"tag":45,"props":253,"children":254},{"__ignoreMap":7},[255,263,272,282,291,300,309,318,327,336,345],{"type":20,"tag":126,"props":256,"children":257},{"class":128,"line":129},[258],{"type":20,"tag":126,"props":259,"children":260},{},[261],{"type":25,"value":262},"# -*- mode: ruby -*-\n",{"type":20,"tag":126,"props":264,"children":266},{"class":128,"line":265},2,[267],{"type":20,"tag":126,"props":268,"children":269},{},[270],{"type":25,"value":271},"# vi: set ft=ruby :\n",{"type":20,"tag":126,"props":273,"children":275},{"class":128,"line":274},3,[276],{"type":20,"tag":126,"props":277,"children":279},{"emptyLinePlaceholder":278},true,[280],{"type":25,"value":281},"\n",{"type":20,"tag":126,"props":283,"children":285},{"class":128,"line":284},4,[286],{"type":20,"tag":126,"props":287,"children":288},{},[289],{"type":25,"value":290},"Vagrant.configure(\"2\") do |config|\n",{"type":20,"tag":126,"props":292,"children":294},{"class":128,"line":293},5,[295],{"type":20,"tag":126,"props":296,"children":297},{},[298],{"type":25,"value":299}," config.vm.box = \"archlinux/archlinux\"\n",{"type":20,"tag":126,"props":301,"children":303},{"class":128,"line":302},6,[304],{"type":20,"tag":126,"props":305,"children":306},{},[307],{"type":25,"value":308}," config.vm.provider \"virtualbox\" do |vb|\n",{"type":20,"tag":126,"props":310,"children":312},{"class":128,"line":311},7,[313],{"type":20,"tag":126,"props":314,"children":315},{},[316],{"type":25,"value":317}," vb.name = \"archlinux\"\n",{"type":20,"tag":126,"props":319,"children":321},{"class":128,"line":320},8,[322],{"type":20,"tag":126,"props":323,"children":324},{},[325],{"type":25,"value":326}," vb.customize ['modifyvm', :id, '--usb', 'on']\n",{"type":20,"tag":126,"props":328,"children":330},{"class":128,"line":329},9,[331],{"type":20,"tag":126,"props":332,"children":333},{},[334],{"type":25,"value":335}," vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n",{"type":20,"tag":126,"props":337,"children":339},{"class":128,"line":338},10,[340],{"type":20,"tag":126,"props":341,"children":342},{},[343],{"type":25,"value":344}," end\n",{"type":20,"tag":126,"props":346,"children":348},{"class":128,"line":347},11,[349],{"type":20,"tag":126,"props":350,"children":351},{},[352],{"type":25,"value":353},"end\n",{"type":20,"tag":21,"props":355,"children":356},{},[357,359,365],{"type":25,"value":358},"When virtual machine is brought up, the ",{"type":20,"tag":45,"props":360,"children":362},{"className":361},[],[363],{"type":25,"value":364},"usbfilter",{"type":25,"value":366}," is applied, and the guest\nis able to access to the host machine's USB device that was specified in the\nfilter.",{"type":20,"tag":21,"props":368,"children":369},{},[370,372,378,380,386],{"type":25,"value":371},"Start the machine, ",{"type":20,"tag":45,"props":373,"children":375},{"className":374},[],[376],{"type":25,"value":377},"ssh",{"type":25,"value":379}," into the guest, and list the devices to confirm that\nthe USB device is available (see: ",{"type":20,"tag":45,"props":381,"children":383},{"className":382},[],[384],{"type":25,"value":385},"/dev/sdb",{"type":25,"value":387},").",{"type":20,"tag":116,"props":389,"children":391},{"code":390,"language":119,"meta":7,"className":120,"style":7},"$ vagrant up\n$ vagrant ssh\n[vagrant@archlinux ~]$ lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 20G 0 disk\n├─sda1 8:1 0 1.9G 0 part [SWAP]\n└─sda2 8:2 0 18.1G 0 part /\nsdb 8:16 1 28.7G 0 disk\n└─sdb1 8:17 1 8G 0 part\n",[392],{"type":20,"tag":45,"props":393,"children":394},{"__ignoreMap":7},[395,413,429,449,487,521,557,592,623],{"type":20,"tag":126,"props":396,"children":397},{"class":128,"line":129},[398,403,408],{"type":20,"tag":126,"props":399,"children":400},{"style":133},[401],{"type":25,"value":402},"$",{"type":20,"tag":126,"props":404,"children":405},{"style":138},[406],{"type":25,"value":407}," vagrant",{"type":20,"tag":126,"props":409,"children":410},{"style":138},[411],{"type":25,"value":412}," up\n",{"type":20,"tag":126,"props":414,"children":415},{"class":128,"line":265},[416,420,424],{"type":20,"tag":126,"props":417,"children":418},{"style":133},[419],{"type":25,"value":402},{"type":20,"tag":126,"props":421,"children":422},{"style":138},[423],{"type":25,"value":407},{"type":20,"tag":126,"props":425,"children":426},{"style":138},[427],{"type":25,"value":428}," ssh\n",{"type":20,"tag":126,"props":430,"children":431},{"class":128,"line":274},[432,438,444],{"type":20,"tag":126,"props":433,"children":435},{"style":434},"--shiki-default:#24292E",[436],{"type":25,"value":437},"[vagrant@archlinux ",{"type":20,"tag":126,"props":439,"children":441},{"style":440},"--shiki-default:#D73A49",[442],{"type":25,"value":443},"~",{"type":20,"tag":126,"props":445,"children":446},{"style":434},[447],{"type":25,"value":448},"]$ lsblk\n",{"type":20,"tag":126,"props":450,"children":451},{"class":128,"line":284},[452,457,462,467,472,477,482],{"type":20,"tag":126,"props":453,"children":454},{"style":133},[455],{"type":25,"value":456},"NAME",{"type":20,"tag":126,"props":458,"children":459},{"style":138},[460],{"type":25,"value":461}," MAJ:MIN",{"type":20,"tag":126,"props":463,"children":464},{"style":138},[465],{"type":25,"value":466}," RM",{"type":20,"tag":126,"props":468,"children":469},{"style":138},[470],{"type":25,"value":471}," SIZE",{"type":20,"tag":126,"props":473,"children":474},{"style":138},[475],{"type":25,"value":476}," RO",{"type":20,"tag":126,"props":478,"children":479},{"style":138},[480],{"type":25,"value":481}," TYPE",{"type":20,"tag":126,"props":483,"children":484},{"style":138},[485],{"type":25,"value":486}," MOUNTPOINT\n",{"type":20,"tag":126,"props":488,"children":489},{"class":128,"line":293},[490,495,500,506,511,516],{"type":20,"tag":126,"props":491,"children":492},{"style":133},[493],{"type":25,"value":494},"sda",{"type":20,"tag":126,"props":496,"children":497},{"style":138},[498],{"type":25,"value":499}," 8:0",{"type":20,"tag":126,"props":501,"children":503},{"style":502},"--shiki-default:#005CC5",[504],{"type":25,"value":505}," 0",{"type":20,"tag":126,"props":507,"children":508},{"style":138},[509],{"type":25,"value":510}," 20G",{"type":20,"tag":126,"props":512,"children":513},{"style":502},[514],{"type":25,"value":515}," 0",{"type":20,"tag":126,"props":517,"children":518},{"style":138},[519],{"type":25,"value":520}," disk\n",{"type":20,"tag":126,"props":522,"children":523},{"class":128,"line":302},[524,529,534,538,543,547,552],{"type":20,"tag":126,"props":525,"children":526},{"style":133},[527],{"type":25,"value":528},"├─sda1",{"type":20,"tag":126,"props":530,"children":531},{"style":138},[532],{"type":25,"value":533}," 8:1",{"type":20,"tag":126,"props":535,"children":536},{"style":502},[537],{"type":25,"value":505},{"type":20,"tag":126,"props":539,"children":540},{"style":138},[541],{"type":25,"value":542}," 1.9G",{"type":20,"tag":126,"props":544,"children":545},{"style":502},[546],{"type":25,"value":515},{"type":20,"tag":126,"props":548,"children":549},{"style":138},[550],{"type":25,"value":551}," part",{"type":20,"tag":126,"props":553,"children":554},{"style":434},[555],{"type":25,"value":556}," [SWAP]\n",{"type":20,"tag":126,"props":558,"children":559},{"class":128,"line":311},[560,565,570,574,579,583,587],{"type":20,"tag":126,"props":561,"children":562},{"style":133},[563],{"type":25,"value":564},"└─sda2",{"type":20,"tag":126,"props":566,"children":567},{"style":138},[568],{"type":25,"value":569}," 8:2",{"type":20,"tag":126,"props":571,"children":572},{"style":502},[573],{"type":25,"value":505},{"type":20,"tag":126,"props":575,"children":576},{"style":138},[577],{"type":25,"value":578}," 18.1G",{"type":20,"tag":126,"props":580,"children":581},{"style":502},[582],{"type":25,"value":515},{"type":20,"tag":126,"props":584,"children":585},{"style":138},[586],{"type":25,"value":551},{"type":20,"tag":126,"props":588,"children":589},{"style":138},[590],{"type":25,"value":591}," /\n",{"type":20,"tag":126,"props":593,"children":594},{"class":128,"line":320},[595,600,605,610,615,619],{"type":20,"tag":126,"props":596,"children":597},{"style":133},[598],{"type":25,"value":599},"sdb",{"type":20,"tag":126,"props":601,"children":602},{"style":138},[603],{"type":25,"value":604}," 8:16",{"type":20,"tag":126,"props":606,"children":607},{"style":502},[608],{"type":25,"value":609}," 1",{"type":20,"tag":126,"props":611,"children":612},{"style":138},[613],{"type":25,"value":614}," 28.7G",{"type":20,"tag":126,"props":616,"children":617},{"style":502},[618],{"type":25,"value":515},{"type":20,"tag":126,"props":620,"children":621},{"style":138},[622],{"type":25,"value":520},{"type":20,"tag":126,"props":624,"children":625},{"class":128,"line":329},[626,631,636,640,645,649],{"type":20,"tag":126,"props":627,"children":628},{"style":133},[629],{"type":25,"value":630},"└─sdb1",{"type":20,"tag":126,"props":632,"children":633},{"style":138},[634],{"type":25,"value":635}," 8:17",{"type":20,"tag":126,"props":637,"children":638},{"style":502},[639],{"type":25,"value":609},{"type":20,"tag":126,"props":641,"children":642},{"style":138},[643],{"type":25,"value":644}," 8G",{"type":20,"tag":126,"props":646,"children":647},{"style":502},[648],{"type":25,"value":515},{"type":20,"tag":126,"props":650,"children":651},{"style":138},[652],{"type":25,"value":653}," part\n",{"type":20,"tag":92,"props":655,"children":657},{"id":656},"install-arch-linux-on-the-usb-drive",[658],{"type":25,"value":659},"Install Arch Linux on the USB Drive",{"type":20,"tag":21,"props":661,"children":662},{},[663,665,672],{"type":25,"value":664},"The ",{"type":20,"tag":58,"props":666,"children":669},{"href":667,"rel":668},"https://wiki.archlinux.org/index.php/Installation_guide",[62],[670],{"type":25,"value":671},"Arch Linux Installation Guide",{"type":25,"value":673}," outlines the installation procedure in\ngreat detail -- the following steps follow this closely with a few alteration\ndue to installing onto removable media.",{"type":20,"tag":675,"props":676,"children":678},"h3",{"id":677},"partition-the-disk-uefi-with-gpt",[679],{"type":25,"value":680},"Partition the Disk (UEFI with GPT)",{"type":20,"tag":116,"props":682,"children":684},{"code":683,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# fdisk /dev/sdb\n",[685],{"type":20,"tag":45,"props":686,"children":687},{"__ignoreMap":7},[688],{"type":20,"tag":126,"props":689,"children":690},{"class":128,"line":129},[691,696,700],{"type":20,"tag":126,"props":692,"children":693},{"style":434},[694],{"type":25,"value":695},"[root@archlinux ",{"type":20,"tag":126,"props":697,"children":698},{"style":440},[699],{"type":25,"value":443},{"type":20,"tag":126,"props":701,"children":702},{"style":434},[703],{"type":25,"value":704},"]# fdisk /dev/sdb\n",{"type":20,"tag":116,"props":706,"children":708},{"code":707,"language":249,"meta":7,"className":250,"style":7},"Command (m for help): p\nDisk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\nDisk model: Ultra Fit\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 1050623 1048576 512M EFI System\n/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n\nFilesystem/RAID signature on partition 1 will be wiped.\n",[709],{"type":20,"tag":45,"props":710,"children":711},{"__ignoreMap":7},[712,720,728,736,744,752,760,768,776,783,791,799,808,816],{"type":20,"tag":126,"props":713,"children":714},{"class":128,"line":129},[715],{"type":20,"tag":126,"props":716,"children":717},{},[718],{"type":25,"value":719},"Command (m for help): p\n",{"type":20,"tag":126,"props":721,"children":722},{"class":128,"line":265},[723],{"type":20,"tag":126,"props":724,"children":725},{},[726],{"type":25,"value":727},"Disk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\n",{"type":20,"tag":126,"props":729,"children":730},{"class":128,"line":274},[731],{"type":20,"tag":126,"props":732,"children":733},{},[734],{"type":25,"value":735},"Disk model: Ultra Fit\n",{"type":20,"tag":126,"props":737,"children":738},{"class":128,"line":284},[739],{"type":20,"tag":126,"props":740,"children":741},{},[742],{"type":25,"value":743},"Units: sectors of 1 * 512 = 512 bytes\n",{"type":20,"tag":126,"props":745,"children":746},{"class":128,"line":293},[747],{"type":20,"tag":126,"props":748,"children":749},{},[750],{"type":25,"value":751},"Sector size (logical/physical): 512 bytes / 512 bytes\n",{"type":20,"tag":126,"props":753,"children":754},{"class":128,"line":302},[755],{"type":20,"tag":126,"props":756,"children":757},{},[758],{"type":25,"value":759},"I/O size (minimum/optimal): 512 bytes / 512 bytes\n",{"type":20,"tag":126,"props":761,"children":762},{"class":128,"line":311},[763],{"type":20,"tag":126,"props":764,"children":765},{},[766],{"type":25,"value":767},"Disklabel type: gpt\n",{"type":20,"tag":126,"props":769,"children":770},{"class":128,"line":320},[771],{"type":20,"tag":126,"props":772,"children":773},{},[774],{"type":25,"value":775},"Disk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n",{"type":20,"tag":126,"props":777,"children":778},{"class":128,"line":329},[779],{"type":20,"tag":126,"props":780,"children":781},{"emptyLinePlaceholder":278},[782],{"type":25,"value":281},{"type":20,"tag":126,"props":784,"children":785},{"class":128,"line":338},[786],{"type":20,"tag":126,"props":787,"children":788},{},[789],{"type":25,"value":790},"Device Start End Sectors Size Type\n",{"type":20,"tag":126,"props":792,"children":793},{"class":128,"line":347},[794],{"type":20,"tag":126,"props":795,"children":796},{},[797],{"type":25,"value":798},"/dev/sdb1 2048 1050623 1048576 512M EFI System\n",{"type":20,"tag":126,"props":800,"children":802},{"class":128,"line":801},12,[803],{"type":20,"tag":126,"props":804,"children":805},{},[806],{"type":25,"value":807},"/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n",{"type":20,"tag":126,"props":809,"children":811},{"class":128,"line":810},13,[812],{"type":20,"tag":126,"props":813,"children":814},{"emptyLinePlaceholder":278},[815],{"type":25,"value":281},{"type":20,"tag":126,"props":817,"children":819},{"class":128,"line":818},14,[820],{"type":20,"tag":126,"props":821,"children":822},{},[823],{"type":25,"value":824},"Filesystem/RAID signature on partition 1 will be wiped.\n",{"type":20,"tag":675,"props":826,"children":828},{"id":827},"format-the-partitions",[829],{"type":25,"value":830},"Format the Partitions",{"type":20,"tag":21,"props":832,"children":833},{},[834,836],{"type":25,"value":835},"The UEFI specification mandates support for FAT file-systems, and FAT32 is\nrecommended for removable media. ",{"type":20,"tag":54,"props":837,"children":838},{},[839],{"type":20,"tag":58,"props":840,"children":843},{"href":841,"rel":842},"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition",[62],[844],{"type":25,"value":845},"7",{"type":20,"tag":116,"props":847,"children":849},{"code":848,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# pacman -Sy dosfstools\n[root@archlinux ~]# mkfs.fat -F32 /dev/sdb1\n",[850],{"type":20,"tag":45,"props":851,"children":852},{"__ignoreMap":7},[853,869],{"type":20,"tag":126,"props":854,"children":855},{"class":128,"line":129},[856,860,864],{"type":20,"tag":126,"props":857,"children":858},{"style":434},[859],{"type":25,"value":695},{"type":20,"tag":126,"props":861,"children":862},{"style":440},[863],{"type":25,"value":443},{"type":20,"tag":126,"props":865,"children":866},{"style":434},[867],{"type":25,"value":868},"]# pacman -Sy dosfstools\n",{"type":20,"tag":126,"props":870,"children":871},{"class":128,"line":265},[872,876,880],{"type":20,"tag":126,"props":873,"children":874},{"style":434},[875],{"type":25,"value":695},{"type":20,"tag":126,"props":877,"children":878},{"style":440},[879],{"type":25,"value":443},{"type":20,"tag":126,"props":881,"children":882},{"style":434},[883],{"type":25,"value":884},"]# mkfs.fat -F32 /dev/sdb1\n",{"type":20,"tag":21,"props":886,"children":887},{},[888,890,896,898],{"type":25,"value":889},"As for the root partition, it is recommended to use ",{"type":20,"tag":45,"props":891,"children":893},{"className":892},[],[894],{"type":25,"value":895},"ext4",{"type":25,"value":897}," without a journal to\nreduce the reads and writes to the file-system as this is detrimental to the\nflash-based USB drive. ",{"type":20,"tag":54,"props":899,"children":900},{},[901],{"type":20,"tag":58,"props":902,"children":905},{"href":903,"rel":904},"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks",[62],[906],{"type":25,"value":907},"8",{"type":20,"tag":116,"props":909,"children":911},{"code":910,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# mkfs.ext4 -O \"^has_journal\" /dev/sdb2\n",[912],{"type":20,"tag":45,"props":913,"children":914},{"__ignoreMap":7},[915],{"type":20,"tag":126,"props":916,"children":917},{"class":128,"line":129},[918,922,926,931,936],{"type":20,"tag":126,"props":919,"children":920},{"style":434},[921],{"type":25,"value":695},{"type":20,"tag":126,"props":923,"children":924},{"style":440},[925],{"type":25,"value":443},{"type":20,"tag":126,"props":927,"children":928},{"style":434},[929],{"type":25,"value":930},"]# mkfs.ext4 -O ",{"type":20,"tag":126,"props":932,"children":933},{"style":138},[934],{"type":25,"value":935},"\"^has_journal\"",{"type":20,"tag":126,"props":937,"children":938},{"style":434},[939],{"type":25,"value":940}," /dev/sdb2\n",{"type":20,"tag":675,"props":942,"children":944},{"id":943},"mount-the-partitions-and-bootstrap-the-environment",[945],{"type":25,"value":946},"Mount the Partitions and Bootstrap the Environment",{"type":20,"tag":116,"props":948,"children":950},{"code":949,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# mount /dev/sdb2 /mnt\n[root@archlinux ~]# mkdir -p /mnt/boot/efi\n[root@archlinux ~]# mount /dev/sdb1 /mnt/boot/efi\n",[951],{"type":20,"tag":45,"props":952,"children":953},{"__ignoreMap":7},[954,970,986],{"type":20,"tag":126,"props":955,"children":956},{"class":128,"line":129},[957,961,965],{"type":20,"tag":126,"props":958,"children":959},{"style":434},[960],{"type":25,"value":695},{"type":20,"tag":126,"props":962,"children":963},{"style":440},[964],{"type":25,"value":443},{"type":20,"tag":126,"props":966,"children":967},{"style":434},[968],{"type":25,"value":969},"]# mount /dev/sdb2 /mnt\n",{"type":20,"tag":126,"props":971,"children":972},{"class":128,"line":265},[973,977,981],{"type":20,"tag":126,"props":974,"children":975},{"style":434},[976],{"type":25,"value":695},{"type":20,"tag":126,"props":978,"children":979},{"style":440},[980],{"type":25,"value":443},{"type":20,"tag":126,"props":982,"children":983},{"style":434},[984],{"type":25,"value":985},"]# mkdir -p /mnt/boot/efi\n",{"type":20,"tag":126,"props":987,"children":988},{"class":128,"line":274},[989,993,997],{"type":20,"tag":126,"props":990,"children":991},{"style":434},[992],{"type":25,"value":695},{"type":20,"tag":126,"props":994,"children":995},{"style":440},[996],{"type":25,"value":443},{"type":20,"tag":126,"props":998,"children":999},{"style":434},[1000],{"type":25,"value":1001},"]# mount /dev/sdb1 /mnt/boot/efi\n",{"type":20,"tag":116,"props":1003,"children":1005},{"code":1004,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# pacman -S arch-install-scripts\n[root@archlinux ~]# pacstrap /mnt base linux linux-firmware\n[root@archlinux ~]# genfstab -U /mnt >> /mnt/etc/fstab\n",[1006],{"type":20,"tag":45,"props":1007,"children":1008},{"__ignoreMap":7},[1009,1025,1041],{"type":20,"tag":126,"props":1010,"children":1011},{"class":128,"line":129},[1012,1016,1020],{"type":20,"tag":126,"props":1013,"children":1014},{"style":434},[1015],{"type":25,"value":695},{"type":20,"tag":126,"props":1017,"children":1018},{"style":440},[1019],{"type":25,"value":443},{"type":20,"tag":126,"props":1021,"children":1022},{"style":434},[1023],{"type":25,"value":1024},"]# pacman -S arch-install-scripts\n",{"type":20,"tag":126,"props":1026,"children":1027},{"class":128,"line":265},[1028,1032,1036],{"type":20,"tag":126,"props":1029,"children":1030},{"style":434},[1031],{"type":25,"value":695},{"type":20,"tag":126,"props":1033,"children":1034},{"style":440},[1035],{"type":25,"value":443},{"type":20,"tag":126,"props":1037,"children":1038},{"style":434},[1039],{"type":25,"value":1040},"]# pacstrap /mnt base linux linux-firmware\n",{"type":20,"tag":126,"props":1042,"children":1043},{"class":128,"line":274},[1044,1048,1052,1057,1062],{"type":20,"tag":126,"props":1045,"children":1046},{"style":434},[1047],{"type":25,"value":695},{"type":20,"tag":126,"props":1049,"children":1050},{"style":440},[1051],{"type":25,"value":443},{"type":20,"tag":126,"props":1053,"children":1054},{"style":434},[1055],{"type":25,"value":1056},"]# genfstab -U /mnt ",{"type":20,"tag":126,"props":1058,"children":1059},{"style":440},[1060],{"type":25,"value":1061},">>",{"type":20,"tag":126,"props":1063,"children":1064},{"style":434},[1065],{"type":25,"value":1066}," /mnt/etc/fstab\n",{"type":20,"tag":675,"props":1068,"children":1070},{"id":1069},"configure-the-new-environment",[1071],{"type":25,"value":1072},"Configure the New Environment",{"type":20,"tag":116,"props":1074,"children":1076},{"code":1075},"[root@archlinux ~]# arch-chroot /mnt\n",[1077],{"type":20,"tag":45,"props":1078,"children":1079},{"__ignoreMap":7},[1080],{"type":25,"value":1075},{"type":20,"tag":116,"props":1082,"children":1084},{"code":1083},"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n",[1085],{"type":20,"tag":45,"props":1086,"children":1087},{"__ignoreMap":7},[1088],{"type":25,"value":1083},{"type":20,"tag":116,"props":1090,"children":1092},{"code":1091},"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n",[1093],{"type":20,"tag":45,"props":1094,"children":1095},{"__ignoreMap":7},[1096],{"type":25,"value":1091},{"type":20,"tag":21,"props":1098,"children":1099},{},[1100,1102,1108,1110],{"type":25,"value":1101},"Note, one difference here from a standard installation is that the\n",{"type":20,"tag":45,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":25,"value":1107},"--removable",{"type":25,"value":1109}," flag is specified when installing the GRUB bootloader.\n",{"type":20,"tag":54,"props":1111,"children":1112},{},[1113],{"type":20,"tag":58,"props":1114,"children":1117},{"href":1115,"rel":1116},"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems",[62],[1118],{"type":25,"value":1119},"10",{"type":20,"tag":116,"props":1121,"children":1123},{"code":1122},"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n",[1124],{"type":20,"tag":45,"props":1125,"children":1126},{"__ignoreMap":7},[1127],{"type":25,"value":1122},{"type":20,"tag":21,"props":1129,"children":1130},{},[1131],{"type":25,"value":1132},"Shutdown the virtual machine, restart the host machine, and boot the newly\ncreated Arch Linux thumb-drive!",{"type":20,"tag":21,"props":1134,"children":1135},{},[1136],{"type":25,"value":1137},"🎉",{"type":20,"tag":92,"props":1139,"children":1141},{"id":1140},"side-note",[1142],{"type":25,"value":1143},"Side-note",{"type":20,"tag":21,"props":1145,"children":1146},{},[1147,1149,1155,1157,1162,1164],{"type":25,"value":1148},"It was attempted to use the ",{"type":20,"tag":45,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":25,"value":1154},"controlvm usbattach",{"type":25,"value":1156}," command to pass the USB\ndevice to the guest machine, but this did not work as it expects the virtual\nmachine to already be running, and the ",{"type":20,"tag":45,"props":1158,"children":1160},{"className":1159},[],[1161],{"type":25,"value":236},{"type":25,"value":1163}," option runs prior to\nbooting the machine. ",{"type":20,"tag":54,"props":1165,"children":1166},{},[1167],{"type":20,"tag":58,"props":1168,"children":1171},{"href":1169,"rel":1170},"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations",[62],[1172],{"type":25,"value":1173},"11",{"type":20,"tag":116,"props":1175,"children":1177},{"code":1176,"language":249,"meta":7,"className":250,"style":7},"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n\nStderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n",[1178],{"type":20,"tag":45,"props":1179,"children":1180},{"__ignoreMap":7},[1181,1189,1196],{"type":20,"tag":126,"props":1182,"children":1183},{"class":128,"line":129},[1184],{"type":20,"tag":126,"props":1185,"children":1186},{},[1187],{"type":25,"value":1188},"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n",{"type":20,"tag":126,"props":1190,"children":1191},{"class":128,"line":265},[1192],{"type":20,"tag":126,"props":1193,"children":1194},{"emptyLinePlaceholder":278},[1195],{"type":25,"value":281},{"type":20,"tag":126,"props":1197,"children":1198},{"class":128,"line":274},[1199],{"type":20,"tag":126,"props":1200,"children":1201},{},[1202],{"type":25,"value":1203},"Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n",{"type":20,"tag":92,"props":1205,"children":1207},{"id":1206},"references",[1208],{"type":25,"value":1209},"References",{"type":20,"tag":1211,"props":1212,"children":1213},"ol",{},[1214,1224,1233,1242,1251,1260,1269,1278,1287,1296,1305],{"type":20,"tag":1215,"props":1216,"children":1217},"li",{},[1218],{"type":20,"tag":58,"props":1219,"children":1221},{"href":60,"rel":1220},[62],[1222],{"type":25,"value":1223},"Docker Desktop on Mac vs. Docker Toolbox",{"type":20,"tag":1215,"props":1225,"children":1226},{},[1227],{"type":20,"tag":58,"props":1228,"children":1230},{"href":70,"rel":1229},[62],[1231],{"type":25,"value":1232},"GitHub - HyperKit",{"type":20,"tag":1215,"props":1234,"children":1235},{},[1236],{"type":20,"tag":58,"props":1237,"children":1239},{"href":78,"rel":1238},[62],[1240],{"type":25,"value":1241},"GitHub - Docker for Mac - Issue #900",{"type":20,"tag":1215,"props":1243,"children":1244},{},[1245],{"type":20,"tag":58,"props":1246,"children":1248},{"href":108,"rel":1247},[62],[1249],{"type":25,"value":1250},"Vagrant Cloud - Arch Linux",{"type":20,"tag":1215,"props":1252,"children":1253},{},[1254],{"type":20,"tag":58,"props":1255,"children":1257},{"href":216,"rel":1256},[62],[1258],{"type":25,"value":1259},"Attaching USB Devices to VirtualBox Guests using VBoxManage",{"type":20,"tag":1215,"props":1261,"children":1262},{},[1263],{"type":20,"tag":58,"props":1264,"children":1266},{"href":224,"rel":1265},[62],[1267],{"type":25,"value":1268},"GitHub Gist - Vagrant USB Filter",{"type":20,"tag":1215,"props":1270,"children":1271},{},[1272],{"type":20,"tag":58,"props":1273,"children":1275},{"href":841,"rel":1274},[62],[1276],{"type":25,"value":1277},"Arch Linux Wiki - EFI System Partition - Format Partitions",{"type":20,"tag":1215,"props":1279,"children":1280},{},[1281],{"type":20,"tag":58,"props":1282,"children":1284},{"href":903,"rel":1283},[62],[1285],{"type":25,"value":1286},"Arch Linux Wiki - Arch Linux on USB - Installation Tweaks",{"type":20,"tag":1215,"props":1288,"children":1289},{},[1290],{"type":20,"tag":58,"props":1291,"children":1293},{"href":667,"rel":1292},[62],[1294],{"type":25,"value":1295},"Arch Linux Wiki - Installation Guide",{"type":20,"tag":1215,"props":1297,"children":1298},{},[1299],{"type":20,"tag":58,"props":1300,"children":1302},{"href":1115,"rel":1301},[62],[1303],{"type":25,"value":1304},"Arch Linux Wiki - GRUB - UEFI Systems",{"type":20,"tag":1215,"props":1306,"children":1307},{},[1308],{"type":20,"tag":58,"props":1309,"children":1311},{"href":1169,"rel":1310},[62],[1312],{"type":25,"value":1313},"Vagrant VBoxManage Customizations ",{"type":20,"tag":1315,"props":1316,"children":1317},"style",{},[1318],{"type":25,"value":1319},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":265,"depth":265,"links":1321},[1322,1323,1329,1330],{"id":94,"depth":265,"text":97},{"id":656,"depth":265,"text":659,"children":1324},[1325,1326,1327,1328],{"id":677,"depth":274,"text":680},{"id":827,"depth":274,"text":830},{"id":943,"depth":274,"text":946},{"id":1069,"depth":274,"text":1072},{"id":1140,"depth":265,"text":1143},{"id":1206,"depth":265,"text":1209},"markdown","content:articles:persistent-archlinux-usb.md","content","articles/persistent-archlinux-usb.md","md",1718891181773] \ No newline at end of file +[{"data":1,"prerenderedAt":1337},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":26,"_type":1331,"_id":1332,"_source":1333,"_file":1334,"_stem":1335,"_extension":1336},"/articles/persistent-archlinux-usb","articles",false,"","Create a Persistent Arch Linux Bootable USB with Vagrant","When installing a linux distribution, it is common for the instructions to have\nthe user create a bootable USB, boot from the device, and proceed with the\ninstallation procedure from that live medium. However, this blog post will\noutline an alternative approach where a virtual machine created with Vagrant\nwill be used in favor of the live medium.","2020-01-09",[12,13],"vagrant","archlinux",[15],"linux",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":1320},[28,32,39,85,91,98,115,152,165,190,246,354,367,388,654,660,674,681,705,825,831,846,885,908,941,947,1002,1067,1073,1081,1089,1097,1120,1128,1133,1138,1144,1174,1204,1210,1314],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":33,"props":34,"children":36},"h1",{"id":35},"preface",[37],{"type":25,"value":38},"Preface",{"type":20,"tag":21,"props":40,"children":41},{},[42,44,51,53,83],{"type":25,"value":43},"The original intention was to use Docker for this process -- leveraging the\n",{"type":20,"tag":45,"props":46,"children":48},"code",{"className":47},[],[49],{"type":25,"value":50},"--device",{"type":25,"value":52}," flag and mounting the target USB device in the Docker container,\nbut the underlying hypervisor in Docker Desktop for Mac does not support this.\n",{"type":20,"tag":54,"props":55,"children":56},"sup",{},[57,66,68,75,76],{"type":20,"tag":58,"props":59,"children":63},"a",{"href":60,"rel":61},"https://docs.docker.com/docker-for-mac/docker-toolbox/",[62],"nofollow",[64],{"type":25,"value":65},"1",{"type":25,"value":67}," ",{"type":20,"tag":58,"props":69,"children":72},{"href":70,"rel":71},"https://github.com/moby/hyperkit",[62],[73],{"type":25,"value":74},"2",{"type":25,"value":67},{"type":20,"tag":58,"props":77,"children":80},{"href":78,"rel":79},"https://github.com/docker/for-mac/issues/900",[62],[81],{"type":25,"value":82},"3",{"type":25,"value":84}," While there are workarounds using Docker\nMachine, Vagrant felt like the path of least resistance.",{"type":20,"tag":33,"props":86,"children":88},{"id":87},"instructions",[89],{"type":25,"value":90},"Instructions",{"type":20,"tag":92,"props":93,"children":95},"h2",{"id":94},"create-an-arch-linux-virtual-machine-with-vagrant",[96],{"type":25,"value":97},"Create an Arch Linux Virtual Machine with Vagrant",{"type":20,"tag":21,"props":99,"children":100},{},[101,103,113],{"type":25,"value":102},"Get the latest Arch Linux image ",{"type":20,"tag":54,"props":104,"children":105},{},[106],{"type":20,"tag":58,"props":107,"children":110},{"href":108,"rel":109},"https://app.vagrantup.com/archlinux/boxes/archlinux",[62],[111],{"type":25,"value":112},"4",{"type":25,"value":114}," from the Vagrant Cloud Box\nCatalog.",{"type":20,"tag":116,"props":117,"children":121},"pre",{"code":118,"language":119,"meta":7,"className":120,"style":7},"vagrant box add archlinux/archlinux\n","bash","language-bash shiki shiki-themes github-light",[122],{"type":20,"tag":45,"props":123,"children":124},{"__ignoreMap":7},[125],{"type":20,"tag":126,"props":127,"children":130},"span",{"class":128,"line":129},"line",1,[131,136,142,147],{"type":20,"tag":126,"props":132,"children":134},{"style":133},"--shiki-default:#6F42C1",[135],{"type":25,"value":12},{"type":20,"tag":126,"props":137,"children":139},{"style":138},"--shiki-default:#032F62",[140],{"type":25,"value":141}," box",{"type":20,"tag":126,"props":143,"children":144},{"style":138},[145],{"type":25,"value":146}," add",{"type":20,"tag":126,"props":148,"children":149},{"style":138},[150],{"type":25,"value":151}," archlinux/archlinux\n",{"type":20,"tag":21,"props":153,"children":154},{},[155,157,163],{"type":25,"value":156},"Determine the USB vendor information for the thumb-drive that we will\npass-through to the virtual machine. Using the ",{"type":20,"tag":45,"props":158,"children":160},{"className":159},[],[161],{"type":25,"value":162},"VBoxManage",{"type":25,"value":164}," utility that comes\nwith Virtual Box, list the devices, and make note of the Vendor and Product ID.",{"type":20,"tag":116,"props":166,"children":168},{"code":167,"language":119,"meta":7,"className":120,"style":7}," VBoxManage list usbhost\n",[169],{"type":20,"tag":45,"props":170,"children":171},{"__ignoreMap":7},[172],{"type":20,"tag":126,"props":173,"children":174},{"class":128,"line":129},[175,180,185],{"type":20,"tag":126,"props":176,"children":177},{"style":133},[178],{"type":25,"value":179}," VBoxManage",{"type":20,"tag":126,"props":181,"children":182},{"style":138},[183],{"type":25,"value":184}," list",{"type":20,"tag":126,"props":186,"children":187},{"style":138},[188],{"type":25,"value":189}," usbhost\n",{"type":20,"tag":21,"props":191,"children":192},{},[193,195,201,203,209,211,229,231,237,239,244],{"type":25,"value":194},"Create a ",{"type":20,"tag":45,"props":196,"children":198},{"className":197},[],[199],{"type":25,"value":200},"Vagrantfile",{"type":25,"value":202}," with ",{"type":20,"tag":45,"props":204,"children":206},{"className":205},[],[207],{"type":25,"value":208},"archlinx/archlinux",{"type":25,"value":210}," as the target box, and the USB\ndevice information that is passed through. ",{"type":20,"tag":54,"props":212,"children":213},{},[214,221,222],{"type":20,"tag":58,"props":215,"children":218},{"href":216,"rel":217},"https://antonyjepson.wordpress.com/2012/01/26/quickly-attaching-usb-devices-to-virtualbox-guests-using-vboxmanage/",[62],[219],{"type":25,"value":220},"5",{"type":25,"value":67},{"type":20,"tag":58,"props":223,"children":226},{"href":224,"rel":225},"https://gist.github.com/dscape/7d829c0c116ef419f963",[62],[227],{"type":25,"value":228},"6",{"type":25,"value":230}," Vagrant\noffers a handy customization parameter ",{"type":20,"tag":45,"props":232,"children":234},{"className":233},[],[235],{"type":25,"value":236},"vb.customize",{"type":25,"value":238}," that calls the\n",{"type":20,"tag":45,"props":240,"children":242},{"className":241},[],[243],{"type":25,"value":162},{"type":25,"value":245}," command under-the-hood, allowing one to enable the guest machine\nto access the host machine's USB devices.",{"type":20,"tag":116,"props":247,"children":251},{"code":248,"language":249,"meta":7,"className":250,"style":7},"# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\nVagrant.configure(\"2\") do |config|\n config.vm.box = \"archlinux/archlinux\"\n config.vm.provider \"virtualbox\" do |vb|\n vb.name = \"archlinux\"\n vb.customize ['modifyvm', :id, '--usb', 'on']\n vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n end\nend\n","txt","language-txt shiki shiki-themes github-light",[252],{"type":20,"tag":45,"props":253,"children":254},{"__ignoreMap":7},[255,263,272,282,291,300,309,318,327,336,345],{"type":20,"tag":126,"props":256,"children":257},{"class":128,"line":129},[258],{"type":20,"tag":126,"props":259,"children":260},{},[261],{"type":25,"value":262},"# -*- mode: ruby -*-\n",{"type":20,"tag":126,"props":264,"children":266},{"class":128,"line":265},2,[267],{"type":20,"tag":126,"props":268,"children":269},{},[270],{"type":25,"value":271},"# vi: set ft=ruby :\n",{"type":20,"tag":126,"props":273,"children":275},{"class":128,"line":274},3,[276],{"type":20,"tag":126,"props":277,"children":279},{"emptyLinePlaceholder":278},true,[280],{"type":25,"value":281},"\n",{"type":20,"tag":126,"props":283,"children":285},{"class":128,"line":284},4,[286],{"type":20,"tag":126,"props":287,"children":288},{},[289],{"type":25,"value":290},"Vagrant.configure(\"2\") do |config|\n",{"type":20,"tag":126,"props":292,"children":294},{"class":128,"line":293},5,[295],{"type":20,"tag":126,"props":296,"children":297},{},[298],{"type":25,"value":299}," config.vm.box = \"archlinux/archlinux\"\n",{"type":20,"tag":126,"props":301,"children":303},{"class":128,"line":302},6,[304],{"type":20,"tag":126,"props":305,"children":306},{},[307],{"type":25,"value":308}," config.vm.provider \"virtualbox\" do |vb|\n",{"type":20,"tag":126,"props":310,"children":312},{"class":128,"line":311},7,[313],{"type":20,"tag":126,"props":314,"children":315},{},[316],{"type":25,"value":317}," vb.name = \"archlinux\"\n",{"type":20,"tag":126,"props":319,"children":321},{"class":128,"line":320},8,[322],{"type":20,"tag":126,"props":323,"children":324},{},[325],{"type":25,"value":326}," vb.customize ['modifyvm', :id, '--usb', 'on']\n",{"type":20,"tag":126,"props":328,"children":330},{"class":128,"line":329},9,[331],{"type":20,"tag":126,"props":332,"children":333},{},[334],{"type":25,"value":335}," vb.customize ['usbfilter', 'add', '1', '--target', :id, '--name', 'SanDisk Ultra Fit', '--vendorid', '0x0781', '--productid', '0x5583']\n",{"type":20,"tag":126,"props":337,"children":339},{"class":128,"line":338},10,[340],{"type":20,"tag":126,"props":341,"children":342},{},[343],{"type":25,"value":344}," end\n",{"type":20,"tag":126,"props":346,"children":348},{"class":128,"line":347},11,[349],{"type":20,"tag":126,"props":350,"children":351},{},[352],{"type":25,"value":353},"end\n",{"type":20,"tag":21,"props":355,"children":356},{},[357,359,365],{"type":25,"value":358},"When virtual machine is brought up, the ",{"type":20,"tag":45,"props":360,"children":362},{"className":361},[],[363],{"type":25,"value":364},"usbfilter",{"type":25,"value":366}," is applied, and the guest\nis able to access to the host machine's USB device that was specified in the\nfilter.",{"type":20,"tag":21,"props":368,"children":369},{},[370,372,378,380,386],{"type":25,"value":371},"Start the machine, ",{"type":20,"tag":45,"props":373,"children":375},{"className":374},[],[376],{"type":25,"value":377},"ssh",{"type":25,"value":379}," into the guest, and list the devices to confirm that\nthe USB device is available (see: ",{"type":20,"tag":45,"props":381,"children":383},{"className":382},[],[384],{"type":25,"value":385},"/dev/sdb",{"type":25,"value":387},").",{"type":20,"tag":116,"props":389,"children":391},{"code":390,"language":119,"meta":7,"className":120,"style":7},"$ vagrant up\n$ vagrant ssh\n[vagrant@archlinux ~]$ lsblk\nNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nsda 8:0 0 20G 0 disk\n├─sda1 8:1 0 1.9G 0 part [SWAP]\n└─sda2 8:2 0 18.1G 0 part /\nsdb 8:16 1 28.7G 0 disk\n└─sdb1 8:17 1 8G 0 part\n",[392],{"type":20,"tag":45,"props":393,"children":394},{"__ignoreMap":7},[395,413,429,449,487,521,557,592,623],{"type":20,"tag":126,"props":396,"children":397},{"class":128,"line":129},[398,403,408],{"type":20,"tag":126,"props":399,"children":400},{"style":133},[401],{"type":25,"value":402},"$",{"type":20,"tag":126,"props":404,"children":405},{"style":138},[406],{"type":25,"value":407}," vagrant",{"type":20,"tag":126,"props":409,"children":410},{"style":138},[411],{"type":25,"value":412}," up\n",{"type":20,"tag":126,"props":414,"children":415},{"class":128,"line":265},[416,420,424],{"type":20,"tag":126,"props":417,"children":418},{"style":133},[419],{"type":25,"value":402},{"type":20,"tag":126,"props":421,"children":422},{"style":138},[423],{"type":25,"value":407},{"type":20,"tag":126,"props":425,"children":426},{"style":138},[427],{"type":25,"value":428}," ssh\n",{"type":20,"tag":126,"props":430,"children":431},{"class":128,"line":274},[432,438,444],{"type":20,"tag":126,"props":433,"children":435},{"style":434},"--shiki-default:#24292E",[436],{"type":25,"value":437},"[vagrant@archlinux ",{"type":20,"tag":126,"props":439,"children":441},{"style":440},"--shiki-default:#D73A49",[442],{"type":25,"value":443},"~",{"type":20,"tag":126,"props":445,"children":446},{"style":434},[447],{"type":25,"value":448},"]$ lsblk\n",{"type":20,"tag":126,"props":450,"children":451},{"class":128,"line":284},[452,457,462,467,472,477,482],{"type":20,"tag":126,"props":453,"children":454},{"style":133},[455],{"type":25,"value":456},"NAME",{"type":20,"tag":126,"props":458,"children":459},{"style":138},[460],{"type":25,"value":461}," MAJ:MIN",{"type":20,"tag":126,"props":463,"children":464},{"style":138},[465],{"type":25,"value":466}," RM",{"type":20,"tag":126,"props":468,"children":469},{"style":138},[470],{"type":25,"value":471}," SIZE",{"type":20,"tag":126,"props":473,"children":474},{"style":138},[475],{"type":25,"value":476}," RO",{"type":20,"tag":126,"props":478,"children":479},{"style":138},[480],{"type":25,"value":481}," TYPE",{"type":20,"tag":126,"props":483,"children":484},{"style":138},[485],{"type":25,"value":486}," MOUNTPOINT\n",{"type":20,"tag":126,"props":488,"children":489},{"class":128,"line":293},[490,495,500,506,511,516],{"type":20,"tag":126,"props":491,"children":492},{"style":133},[493],{"type":25,"value":494},"sda",{"type":20,"tag":126,"props":496,"children":497},{"style":138},[498],{"type":25,"value":499}," 8:0",{"type":20,"tag":126,"props":501,"children":503},{"style":502},"--shiki-default:#005CC5",[504],{"type":25,"value":505}," 0",{"type":20,"tag":126,"props":507,"children":508},{"style":138},[509],{"type":25,"value":510}," 20G",{"type":20,"tag":126,"props":512,"children":513},{"style":502},[514],{"type":25,"value":515}," 0",{"type":20,"tag":126,"props":517,"children":518},{"style":138},[519],{"type":25,"value":520}," disk\n",{"type":20,"tag":126,"props":522,"children":523},{"class":128,"line":302},[524,529,534,538,543,547,552],{"type":20,"tag":126,"props":525,"children":526},{"style":133},[527],{"type":25,"value":528},"├─sda1",{"type":20,"tag":126,"props":530,"children":531},{"style":138},[532],{"type":25,"value":533}," 8:1",{"type":20,"tag":126,"props":535,"children":536},{"style":502},[537],{"type":25,"value":505},{"type":20,"tag":126,"props":539,"children":540},{"style":138},[541],{"type":25,"value":542}," 1.9G",{"type":20,"tag":126,"props":544,"children":545},{"style":502},[546],{"type":25,"value":515},{"type":20,"tag":126,"props":548,"children":549},{"style":138},[550],{"type":25,"value":551}," part",{"type":20,"tag":126,"props":553,"children":554},{"style":434},[555],{"type":25,"value":556}," [SWAP]\n",{"type":20,"tag":126,"props":558,"children":559},{"class":128,"line":311},[560,565,570,574,579,583,587],{"type":20,"tag":126,"props":561,"children":562},{"style":133},[563],{"type":25,"value":564},"└─sda2",{"type":20,"tag":126,"props":566,"children":567},{"style":138},[568],{"type":25,"value":569}," 8:2",{"type":20,"tag":126,"props":571,"children":572},{"style":502},[573],{"type":25,"value":505},{"type":20,"tag":126,"props":575,"children":576},{"style":138},[577],{"type":25,"value":578}," 18.1G",{"type":20,"tag":126,"props":580,"children":581},{"style":502},[582],{"type":25,"value":515},{"type":20,"tag":126,"props":584,"children":585},{"style":138},[586],{"type":25,"value":551},{"type":20,"tag":126,"props":588,"children":589},{"style":138},[590],{"type":25,"value":591}," /\n",{"type":20,"tag":126,"props":593,"children":594},{"class":128,"line":320},[595,600,605,610,615,619],{"type":20,"tag":126,"props":596,"children":597},{"style":133},[598],{"type":25,"value":599},"sdb",{"type":20,"tag":126,"props":601,"children":602},{"style":138},[603],{"type":25,"value":604}," 8:16",{"type":20,"tag":126,"props":606,"children":607},{"style":502},[608],{"type":25,"value":609}," 1",{"type":20,"tag":126,"props":611,"children":612},{"style":138},[613],{"type":25,"value":614}," 28.7G",{"type":20,"tag":126,"props":616,"children":617},{"style":502},[618],{"type":25,"value":515},{"type":20,"tag":126,"props":620,"children":621},{"style":138},[622],{"type":25,"value":520},{"type":20,"tag":126,"props":624,"children":625},{"class":128,"line":329},[626,631,636,640,645,649],{"type":20,"tag":126,"props":627,"children":628},{"style":133},[629],{"type":25,"value":630},"└─sdb1",{"type":20,"tag":126,"props":632,"children":633},{"style":138},[634],{"type":25,"value":635}," 8:17",{"type":20,"tag":126,"props":637,"children":638},{"style":502},[639],{"type":25,"value":609},{"type":20,"tag":126,"props":641,"children":642},{"style":138},[643],{"type":25,"value":644}," 8G",{"type":20,"tag":126,"props":646,"children":647},{"style":502},[648],{"type":25,"value":515},{"type":20,"tag":126,"props":650,"children":651},{"style":138},[652],{"type":25,"value":653}," part\n",{"type":20,"tag":92,"props":655,"children":657},{"id":656},"install-arch-linux-on-the-usb-drive",[658],{"type":25,"value":659},"Install Arch Linux on the USB Drive",{"type":20,"tag":21,"props":661,"children":662},{},[663,665,672],{"type":25,"value":664},"The ",{"type":20,"tag":58,"props":666,"children":669},{"href":667,"rel":668},"https://wiki.archlinux.org/index.php/Installation_guide",[62],[670],{"type":25,"value":671},"Arch Linux Installation Guide",{"type":25,"value":673}," outlines the installation procedure in\ngreat detail -- the following steps follow this closely with a few alteration\ndue to installing onto removable media.",{"type":20,"tag":675,"props":676,"children":678},"h3",{"id":677},"partition-the-disk-uefi-with-gpt",[679],{"type":25,"value":680},"Partition the Disk (UEFI with GPT)",{"type":20,"tag":116,"props":682,"children":684},{"code":683,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# fdisk /dev/sdb\n",[685],{"type":20,"tag":45,"props":686,"children":687},{"__ignoreMap":7},[688],{"type":20,"tag":126,"props":689,"children":690},{"class":128,"line":129},[691,696,700],{"type":20,"tag":126,"props":692,"children":693},{"style":434},[694],{"type":25,"value":695},"[root@archlinux ",{"type":20,"tag":126,"props":697,"children":698},{"style":440},[699],{"type":25,"value":443},{"type":20,"tag":126,"props":701,"children":702},{"style":434},[703],{"type":25,"value":704},"]# fdisk /dev/sdb\n",{"type":20,"tag":116,"props":706,"children":708},{"code":707,"language":249,"meta":7,"className":250,"style":7},"Command (m for help): p\nDisk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\nDisk model: Ultra Fit\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 1050623 1048576 512M EFI System\n/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n\nFilesystem/RAID signature on partition 1 will be wiped.\n",[709],{"type":20,"tag":45,"props":710,"children":711},{"__ignoreMap":7},[712,720,728,736,744,752,760,768,776,783,791,799,808,816],{"type":20,"tag":126,"props":713,"children":714},{"class":128,"line":129},[715],{"type":20,"tag":126,"props":716,"children":717},{},[718],{"type":25,"value":719},"Command (m for help): p\n",{"type":20,"tag":126,"props":721,"children":722},{"class":128,"line":265},[723],{"type":20,"tag":126,"props":724,"children":725},{},[726],{"type":25,"value":727},"Disk /dev/sdb: 28.66 GiB, 30752636928 bytes, 60063744 sectors\n",{"type":20,"tag":126,"props":729,"children":730},{"class":128,"line":274},[731],{"type":20,"tag":126,"props":732,"children":733},{},[734],{"type":25,"value":735},"Disk model: Ultra Fit\n",{"type":20,"tag":126,"props":737,"children":738},{"class":128,"line":284},[739],{"type":20,"tag":126,"props":740,"children":741},{},[742],{"type":25,"value":743},"Units: sectors of 1 * 512 = 512 bytes\n",{"type":20,"tag":126,"props":745,"children":746},{"class":128,"line":293},[747],{"type":20,"tag":126,"props":748,"children":749},{},[750],{"type":25,"value":751},"Sector size (logical/physical): 512 bytes / 512 bytes\n",{"type":20,"tag":126,"props":753,"children":754},{"class":128,"line":302},[755],{"type":20,"tag":126,"props":756,"children":757},{},[758],{"type":25,"value":759},"I/O size (minimum/optimal): 512 bytes / 512 bytes\n",{"type":20,"tag":126,"props":761,"children":762},{"class":128,"line":311},[763],{"type":20,"tag":126,"props":764,"children":765},{},[766],{"type":25,"value":767},"Disklabel type: gpt\n",{"type":20,"tag":126,"props":769,"children":770},{"class":128,"line":320},[771],{"type":20,"tag":126,"props":772,"children":773},{},[774],{"type":25,"value":775},"Disk identifier: E1D6C445-1B79-AB4D-A442-FA4AD6DF4ECC\n",{"type":20,"tag":126,"props":777,"children":778},{"class":128,"line":329},[779],{"type":20,"tag":126,"props":780,"children":781},{"emptyLinePlaceholder":278},[782],{"type":25,"value":281},{"type":20,"tag":126,"props":784,"children":785},{"class":128,"line":338},[786],{"type":20,"tag":126,"props":787,"children":788},{},[789],{"type":25,"value":790},"Device Start End Sectors Size Type\n",{"type":20,"tag":126,"props":792,"children":793},{"class":128,"line":347},[794],{"type":20,"tag":126,"props":795,"children":796},{},[797],{"type":25,"value":798},"/dev/sdb1 2048 1050623 1048576 512M EFI System\n",{"type":20,"tag":126,"props":800,"children":802},{"class":128,"line":801},12,[803],{"type":20,"tag":126,"props":804,"children":805},{},[806],{"type":25,"value":807},"/dev/sdb2 1050624 60063710 59013087 28.1G Linux filesystem\n",{"type":20,"tag":126,"props":809,"children":811},{"class":128,"line":810},13,[812],{"type":20,"tag":126,"props":813,"children":814},{"emptyLinePlaceholder":278},[815],{"type":25,"value":281},{"type":20,"tag":126,"props":817,"children":819},{"class":128,"line":818},14,[820],{"type":20,"tag":126,"props":821,"children":822},{},[823],{"type":25,"value":824},"Filesystem/RAID signature on partition 1 will be wiped.\n",{"type":20,"tag":675,"props":826,"children":828},{"id":827},"format-the-partitions",[829],{"type":25,"value":830},"Format the Partitions",{"type":20,"tag":21,"props":832,"children":833},{},[834,836],{"type":25,"value":835},"The UEFI specification mandates support for FAT file-systems, and FAT32 is\nrecommended for removable media. ",{"type":20,"tag":54,"props":837,"children":838},{},[839],{"type":20,"tag":58,"props":840,"children":843},{"href":841,"rel":842},"https://wiki.archlinux.org/index.php/EFI_system_partition#Format_the_partition",[62],[844],{"type":25,"value":845},"7",{"type":20,"tag":116,"props":847,"children":849},{"code":848,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# pacman -Sy dosfstools\n[root@archlinux ~]# mkfs.fat -F32 /dev/sdb1\n",[850],{"type":20,"tag":45,"props":851,"children":852},{"__ignoreMap":7},[853,869],{"type":20,"tag":126,"props":854,"children":855},{"class":128,"line":129},[856,860,864],{"type":20,"tag":126,"props":857,"children":858},{"style":434},[859],{"type":25,"value":695},{"type":20,"tag":126,"props":861,"children":862},{"style":440},[863],{"type":25,"value":443},{"type":20,"tag":126,"props":865,"children":866},{"style":434},[867],{"type":25,"value":868},"]# pacman -Sy dosfstools\n",{"type":20,"tag":126,"props":870,"children":871},{"class":128,"line":265},[872,876,880],{"type":20,"tag":126,"props":873,"children":874},{"style":434},[875],{"type":25,"value":695},{"type":20,"tag":126,"props":877,"children":878},{"style":440},[879],{"type":25,"value":443},{"type":20,"tag":126,"props":881,"children":882},{"style":434},[883],{"type":25,"value":884},"]# mkfs.fat -F32 /dev/sdb1\n",{"type":20,"tag":21,"props":886,"children":887},{},[888,890,896,898],{"type":25,"value":889},"As for the root partition, it is recommended to use ",{"type":20,"tag":45,"props":891,"children":893},{"className":892},[],[894],{"type":25,"value":895},"ext4",{"type":25,"value":897}," without a journal to\nreduce the reads and writes to the file-system as this is detrimental to the\nflash-based USB drive. ",{"type":20,"tag":54,"props":899,"children":900},{},[901],{"type":20,"tag":58,"props":902,"children":905},{"href":903,"rel":904},"https://wiki.archlinux.org/index.php/Install_Arch_Linux_on_a_USB_key#Installation_tweaks",[62],[906],{"type":25,"value":907},"8",{"type":20,"tag":116,"props":909,"children":911},{"code":910,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# mkfs.ext4 -O \"^has_journal\" /dev/sdb2\n",[912],{"type":20,"tag":45,"props":913,"children":914},{"__ignoreMap":7},[915],{"type":20,"tag":126,"props":916,"children":917},{"class":128,"line":129},[918,922,926,931,936],{"type":20,"tag":126,"props":919,"children":920},{"style":434},[921],{"type":25,"value":695},{"type":20,"tag":126,"props":923,"children":924},{"style":440},[925],{"type":25,"value":443},{"type":20,"tag":126,"props":927,"children":928},{"style":434},[929],{"type":25,"value":930},"]# mkfs.ext4 -O ",{"type":20,"tag":126,"props":932,"children":933},{"style":138},[934],{"type":25,"value":935},"\"^has_journal\"",{"type":20,"tag":126,"props":937,"children":938},{"style":434},[939],{"type":25,"value":940}," /dev/sdb2\n",{"type":20,"tag":675,"props":942,"children":944},{"id":943},"mount-the-partitions-and-bootstrap-the-environment",[945],{"type":25,"value":946},"Mount the Partitions and Bootstrap the Environment",{"type":20,"tag":116,"props":948,"children":950},{"code":949,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# mount /dev/sdb2 /mnt\n[root@archlinux ~]# mkdir -p /mnt/boot/efi\n[root@archlinux ~]# mount /dev/sdb1 /mnt/boot/efi\n",[951],{"type":20,"tag":45,"props":952,"children":953},{"__ignoreMap":7},[954,970,986],{"type":20,"tag":126,"props":955,"children":956},{"class":128,"line":129},[957,961,965],{"type":20,"tag":126,"props":958,"children":959},{"style":434},[960],{"type":25,"value":695},{"type":20,"tag":126,"props":962,"children":963},{"style":440},[964],{"type":25,"value":443},{"type":20,"tag":126,"props":966,"children":967},{"style":434},[968],{"type":25,"value":969},"]# mount /dev/sdb2 /mnt\n",{"type":20,"tag":126,"props":971,"children":972},{"class":128,"line":265},[973,977,981],{"type":20,"tag":126,"props":974,"children":975},{"style":434},[976],{"type":25,"value":695},{"type":20,"tag":126,"props":978,"children":979},{"style":440},[980],{"type":25,"value":443},{"type":20,"tag":126,"props":982,"children":983},{"style":434},[984],{"type":25,"value":985},"]# mkdir -p /mnt/boot/efi\n",{"type":20,"tag":126,"props":987,"children":988},{"class":128,"line":274},[989,993,997],{"type":20,"tag":126,"props":990,"children":991},{"style":434},[992],{"type":25,"value":695},{"type":20,"tag":126,"props":994,"children":995},{"style":440},[996],{"type":25,"value":443},{"type":20,"tag":126,"props":998,"children":999},{"style":434},[1000],{"type":25,"value":1001},"]# mount /dev/sdb1 /mnt/boot/efi\n",{"type":20,"tag":116,"props":1003,"children":1005},{"code":1004,"language":119,"meta":7,"className":120,"style":7},"[root@archlinux ~]# pacman -S arch-install-scripts\n[root@archlinux ~]# pacstrap /mnt base linux linux-firmware\n[root@archlinux ~]# genfstab -U /mnt >> /mnt/etc/fstab\n",[1006],{"type":20,"tag":45,"props":1007,"children":1008},{"__ignoreMap":7},[1009,1025,1041],{"type":20,"tag":126,"props":1010,"children":1011},{"class":128,"line":129},[1012,1016,1020],{"type":20,"tag":126,"props":1013,"children":1014},{"style":434},[1015],{"type":25,"value":695},{"type":20,"tag":126,"props":1017,"children":1018},{"style":440},[1019],{"type":25,"value":443},{"type":20,"tag":126,"props":1021,"children":1022},{"style":434},[1023],{"type":25,"value":1024},"]# pacman -S arch-install-scripts\n",{"type":20,"tag":126,"props":1026,"children":1027},{"class":128,"line":265},[1028,1032,1036],{"type":20,"tag":126,"props":1029,"children":1030},{"style":434},[1031],{"type":25,"value":695},{"type":20,"tag":126,"props":1033,"children":1034},{"style":440},[1035],{"type":25,"value":443},{"type":20,"tag":126,"props":1037,"children":1038},{"style":434},[1039],{"type":25,"value":1040},"]# pacstrap /mnt base linux linux-firmware\n",{"type":20,"tag":126,"props":1042,"children":1043},{"class":128,"line":274},[1044,1048,1052,1057,1062],{"type":20,"tag":126,"props":1045,"children":1046},{"style":434},[1047],{"type":25,"value":695},{"type":20,"tag":126,"props":1049,"children":1050},{"style":440},[1051],{"type":25,"value":443},{"type":20,"tag":126,"props":1053,"children":1054},{"style":434},[1055],{"type":25,"value":1056},"]# genfstab -U /mnt ",{"type":20,"tag":126,"props":1058,"children":1059},{"style":440},[1060],{"type":25,"value":1061},">>",{"type":20,"tag":126,"props":1063,"children":1064},{"style":434},[1065],{"type":25,"value":1066}," /mnt/etc/fstab\n",{"type":20,"tag":675,"props":1068,"children":1070},{"id":1069},"configure-the-new-environment",[1071],{"type":25,"value":1072},"Configure the New Environment",{"type":20,"tag":116,"props":1074,"children":1076},{"code":1075},"[root@archlinux ~]# arch-chroot /mnt\n",[1077],{"type":20,"tag":45,"props":1078,"children":1079},{"__ignoreMap":7},[1080],{"type":25,"value":1075},{"type":20,"tag":116,"props":1082,"children":1084},{"code":1083},"[root@archlinux /]# ln -sf /usr/share/zoneinfo/US/Eastern /etc/localtime\n[root@archlinux /]# hwclock --systohc\n[root@archlinux /]# sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen\n[root@archlinux /]# locale-gen\n[root@archlinux /]# echo \"LANG=en_US.UTF-8\" > /etc/locale.conf\n",[1085],{"type":20,"tag":45,"props":1086,"children":1087},{"__ignoreMap":7},[1088],{"type":25,"value":1083},{"type":20,"tag":116,"props":1090,"children":1092},{"code":1091},"[root@archlinux /]# hostnamectl set-hostname usb\n[root@archlinux /]# echo \"127.0.0.1 localhost\" >> /etc/hosts\n[root@archlinux /]# echo \"::1 localhost\" >> /etc/hosts\n",[1093],{"type":20,"tag":45,"props":1094,"children":1095},{"__ignoreMap":7},[1096],{"type":25,"value":1091},{"type":20,"tag":21,"props":1098,"children":1099},{},[1100,1102,1108,1110],{"type":25,"value":1101},"Note, one difference here from a standard installation is that the\n",{"type":20,"tag":45,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":25,"value":1107},"--removable",{"type":25,"value":1109}," flag is specified when installing the GRUB bootloader.\n",{"type":20,"tag":54,"props":1111,"children":1112},{},[1113],{"type":20,"tag":58,"props":1114,"children":1117},{"href":1115,"rel":1116},"https://wiki.archlinux.org/index.php/GRUB#UEFI_systems",[62],[1118],{"type":25,"value":1119},"10",{"type":20,"tag":116,"props":1121,"children":1123},{"code":1122},"[root@archlinux /]# pacman -S grub\n[root@archlinux /]# grub-install --target=x86_64-efi --efi-directory=/boot/efi --removable --recheck\n[root@usb /]# grub-mkconfig -o /boot/grub/grub.cfg\n",[1124],{"type":20,"tag":45,"props":1125,"children":1126},{"__ignoreMap":7},[1127],{"type":25,"value":1122},{"type":20,"tag":21,"props":1129,"children":1130},{},[1131],{"type":25,"value":1132},"Shutdown the virtual machine, restart the host machine, and boot the newly\ncreated Arch Linux thumb-drive!",{"type":20,"tag":21,"props":1134,"children":1135},{},[1136],{"type":25,"value":1137},"🎉",{"type":20,"tag":92,"props":1139,"children":1141},{"id":1140},"side-note",[1142],{"type":25,"value":1143},"Side-note",{"type":20,"tag":21,"props":1145,"children":1146},{},[1147,1149,1155,1157,1162,1164],{"type":25,"value":1148},"It was attempted to use the ",{"type":20,"tag":45,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":25,"value":1154},"controlvm usbattach",{"type":25,"value":1156}," command to pass the USB\ndevice to the guest machine, but this did not work as it expects the virtual\nmachine to already be running, and the ",{"type":20,"tag":45,"props":1158,"children":1160},{"className":1159},[],[1161],{"type":25,"value":236},{"type":25,"value":1163}," option runs prior to\nbooting the machine. ",{"type":20,"tag":54,"props":1165,"children":1166},{},[1167],{"type":20,"tag":58,"props":1168,"children":1171},{"href":1169,"rel":1170},"https://www.vagrantup.com/docs/virtualbox/configuration.html#vboxmanage-customizations",[62],[1172],{"type":25,"value":1173},"11",{"type":20,"tag":116,"props":1175,"children":1177},{"code":1176,"language":249,"meta":7,"className":250,"style":7},"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n\nStderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n",[1178],{"type":20,"tag":45,"props":1179,"children":1180},{"__ignoreMap":7},[1181,1189,1196],{"type":20,"tag":126,"props":1182,"children":1183},{"class":128,"line":129},[1184],{"type":20,"tag":126,"props":1185,"children":1186},{},[1187],{"type":25,"value":1188},"Command: [\"controlvm\", \"060a716b-1965-49e2-bc56-12beed5df716\", \"usbattach36fc9e60-c465-11cf-8056-444553540000\"]\n",{"type":20,"tag":126,"props":1190,"children":1191},{"class":128,"line":265},[1192],{"type":20,"tag":126,"props":1193,"children":1194},{"emptyLinePlaceholder":278},[1195],{"type":25,"value":281},{"type":20,"tag":126,"props":1197,"children":1198},{"class":128,"line":274},[1199],{"type":20,"tag":126,"props":1200,"children":1201},{},[1202],{"type":25,"value":1203},"Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.\n",{"type":20,"tag":92,"props":1205,"children":1207},{"id":1206},"references",[1208],{"type":25,"value":1209},"References",{"type":20,"tag":1211,"props":1212,"children":1213},"ol",{},[1214,1224,1233,1242,1251,1260,1269,1278,1287,1296,1305],{"type":20,"tag":1215,"props":1216,"children":1217},"li",{},[1218],{"type":20,"tag":58,"props":1219,"children":1221},{"href":60,"rel":1220},[62],[1222],{"type":25,"value":1223},"Docker Desktop on Mac vs. Docker Toolbox",{"type":20,"tag":1215,"props":1225,"children":1226},{},[1227],{"type":20,"tag":58,"props":1228,"children":1230},{"href":70,"rel":1229},[62],[1231],{"type":25,"value":1232},"GitHub - HyperKit",{"type":20,"tag":1215,"props":1234,"children":1235},{},[1236],{"type":20,"tag":58,"props":1237,"children":1239},{"href":78,"rel":1238},[62],[1240],{"type":25,"value":1241},"GitHub - Docker for Mac - Issue #900",{"type":20,"tag":1215,"props":1243,"children":1244},{},[1245],{"type":20,"tag":58,"props":1246,"children":1248},{"href":108,"rel":1247},[62],[1249],{"type":25,"value":1250},"Vagrant Cloud - Arch Linux",{"type":20,"tag":1215,"props":1252,"children":1253},{},[1254],{"type":20,"tag":58,"props":1255,"children":1257},{"href":216,"rel":1256},[62],[1258],{"type":25,"value":1259},"Attaching USB Devices to VirtualBox Guests using VBoxManage",{"type":20,"tag":1215,"props":1261,"children":1262},{},[1263],{"type":20,"tag":58,"props":1264,"children":1266},{"href":224,"rel":1265},[62],[1267],{"type":25,"value":1268},"GitHub Gist - Vagrant USB Filter",{"type":20,"tag":1215,"props":1270,"children":1271},{},[1272],{"type":20,"tag":58,"props":1273,"children":1275},{"href":841,"rel":1274},[62],[1276],{"type":25,"value":1277},"Arch Linux Wiki - EFI System Partition - Format Partitions",{"type":20,"tag":1215,"props":1279,"children":1280},{},[1281],{"type":20,"tag":58,"props":1282,"children":1284},{"href":903,"rel":1283},[62],[1285],{"type":25,"value":1286},"Arch Linux Wiki - Arch Linux on USB - Installation Tweaks",{"type":20,"tag":1215,"props":1288,"children":1289},{},[1290],{"type":20,"tag":58,"props":1291,"children":1293},{"href":667,"rel":1292},[62],[1294],{"type":25,"value":1295},"Arch Linux Wiki - Installation Guide",{"type":20,"tag":1215,"props":1297,"children":1298},{},[1299],{"type":20,"tag":58,"props":1300,"children":1302},{"href":1115,"rel":1301},[62],[1303],{"type":25,"value":1304},"Arch Linux Wiki - GRUB - UEFI Systems",{"type":20,"tag":1215,"props":1306,"children":1307},{},[1308],{"type":20,"tag":58,"props":1309,"children":1311},{"href":1169,"rel":1310},[62],[1312],{"type":25,"value":1313},"Vagrant VBoxManage Customizations ",{"type":20,"tag":1315,"props":1316,"children":1317},"style",{},[1318],{"type":25,"value":1319},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":265,"depth":265,"links":1321},[1322,1323,1329,1330],{"id":94,"depth":265,"text":97},{"id":656,"depth":265,"text":659,"children":1324},[1325,1326,1327,1328],{"id":677,"depth":274,"text":680},{"id":827,"depth":274,"text":830},{"id":943,"depth":274,"text":946},{"id":1069,"depth":274,"text":1072},{"id":1140,"depth":265,"text":1143},{"id":1206,"depth":265,"text":1209},"markdown","content:articles:persistent-archlinux-usb.md","content","articles/persistent-archlinux-usb.md","articles/persistent-archlinux-usb","md",1720229315500] \ No newline at end of file diff --git a/articles/persistent-archlinux-usb/index.html b/articles/persistent-archlinux-usb/index.html index 9d66c30e..7e34f619 100644 --- a/articles/persistent-archlinux-usb/index.html +++ b/articles/persistent-archlinux-usb/index.html @@ -4,36 +4,37 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - - - - - -

            Create a Persistent Arch Linux Bootable USB with Vagrant

            2020-01-09

            When installing a linux distribution, it is common for the instructions to have + + + + + + + + + + + + + + + + + +

            Create a Persistent Arch Linux Bootable USB with Vagrant

            When installing a linux distribution, it is common for the instructions to have the user create a bootable USB, boot from the device, and proceed with the installation procedure from that live medium. However, this blog post will outline an alternative approach where a virtual machine created with Vagrant @@ -123,5 +124,5 @@ booting the machine. 11

            Command: ["controlvm", "060a716b-1965-49e2-bc56-12beed5df716", "usbattach36fc9e60-c465-11cf-8056-444553540000"]
             
             Stderr: VBoxManage.exe: error: Machine '060a716b-1965-49e2-bc56-12beed5df716' is not currently running.
            -

            References

            1. Docker Desktop on Mac vs. Docker Toolbox
            2. GitHub - HyperKit
            3. GitHub - Docker for Mac - Issue #900
            4. Vagrant Cloud - Arch Linux
            5. Attaching USB Devices to VirtualBox Guests using VBoxManage
            6. GitHub Gist - Vagrant USB Filter
            7. Arch Linux Wiki - EFI System Partition - Format Partitions
            8. Arch Linux Wiki - Arch Linux on USB - Installation Tweaks
            9. Arch Linux Wiki - Installation Guide
            10. Arch Linux Wiki - GRUB - UEFI Systems
            11. Vagrant VBoxManage Customizations
            - \ No newline at end of file +

            References

            1. Docker Desktop on Mac vs. Docker Toolbox
            2. GitHub - HyperKit
            3. GitHub - Docker for Mac - Issue #900
            4. Vagrant Cloud - Arch Linux
            5. Attaching USB Devices to VirtualBox Guests using VBoxManage
            6. GitHub Gist - Vagrant USB Filter
            7. Arch Linux Wiki - EFI System Partition - Format Partitions
            8. Arch Linux Wiki - Arch Linux on USB - Installation Tweaks
            9. Arch Linux Wiki - Installation Guide
            10. Arch Linux Wiki - GRUB - UEFI Systems
            11. Vagrant VBoxManage Customizations
            + \ No newline at end of file diff --git a/articles/podcast-transcription-whispercpp/_payload.json b/articles/podcast-transcription-whispercpp/_payload.json index d45ec7c1..ab827c28 100644 --- a/articles/podcast-transcription-whispercpp/_payload.json +++ b/articles/podcast-transcription-whispercpp/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":749},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"excerpt":16,"body":55,"_type":744,"_id":745,"_source":746,"_file":747,"_extension":748},"/articles/podcast-transcription-whispercpp","articles",false,"","Easily Transcribe Podcasts with Whisper.cpp","If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","2024-01-08",[12,13],"whisper.cpp","ml",[15],"programming",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,35,37,44,46,53],{"type":25,"value":26},"text","If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive ",{"type":20,"tag":28,"props":29,"children":33},"a",{"href":30,"rel":31},"https://github.com/ggerganov/whisper.cpp",[32],"nofollow",[34],{"type":25,"value":12},{"type":25,"value":36}," project. This high-performance fork of ",{"type":20,"tag":28,"props":38,"children":41},{"href":39,"rel":40},"https://github.com/openai/whisper",[32],[42],{"type":25,"value":43},"OpenAI's Whisper",{"type":25,"value":45}," can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the ",{"type":20,"tag":28,"props":47,"children":50},{"href":48,"rel":49},"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854",[32],[51],{"type":25,"value":52},"Alter Everything",{"type":25,"value":54}," podcast.",{"type":17,"children":56,"toc":739},[57,79,86,130,222,234,399,412,424,550,555,720,725,733],{"type":20,"tag":21,"props":58,"children":59},{},[60,61,66,67,72,73,78],{"type":25,"value":26},{"type":20,"tag":28,"props":62,"children":64},{"href":30,"rel":63},[32],[65],{"type":25,"value":12},{"type":25,"value":36},{"type":20,"tag":28,"props":68,"children":70},{"href":39,"rel":69},[32],[71],{"type":25,"value":43},{"type":25,"value":45},{"type":20,"tag":28,"props":74,"children":76},{"href":48,"rel":75},[32],[77],{"type":25,"value":52},{"type":25,"value":54},{"type":20,"tag":80,"props":81,"children":83},"h2",{"id":82},"obtain-audio-files",[84],{"type":25,"value":85},"Obtain Audio File(s)",{"type":20,"tag":21,"props":87,"children":88},{},[89,91,98,100,106,108,113,115,120,122,128],{"type":25,"value":90},"First, let's get the ",{"type":20,"tag":92,"props":93,"children":95},"code",{"className":94},[],[96],{"type":25,"value":97},"wav",{"type":25,"value":99}," file from YouTube using the ",{"type":20,"tag":92,"props":101,"children":103},{"className":102},[],[104],{"type":25,"value":105},"youtube-dl",{"type":25,"value":107}," utility. It should be noted that ",{"type":20,"tag":92,"props":109,"children":111},{"className":110},[],[112],{"type":25,"value":12},{"type":25,"value":114}," expects ",{"type":20,"tag":92,"props":116,"children":118},{"className":117},[],[119],{"type":25,"value":97},{"type":25,"value":121}," filetypes, and this utility defaults to ",{"type":20,"tag":92,"props":123,"children":125},{"className":124},[],[126],{"type":25,"value":127},"mp3",{"type":25,"value":129},".",{"type":20,"tag":131,"props":132,"children":136},"pre",{"code":133,"language":134,"meta":7,"className":135,"style":7}," $ youtube-dl \\\n --extract-audio \\\n --audio-format wav \\\n --output podcast.wav \\\n \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n","sh","language-sh shiki shiki-themes github-light",[137],{"type":20,"tag":92,"props":138,"children":139},{"__ignoreMap":7},[140,164,177,195,213],{"type":20,"tag":141,"props":142,"children":145},"span",{"class":143,"line":144},"line",1,[146,152,158],{"type":20,"tag":141,"props":147,"children":149},{"style":148},"--shiki-default:#6F42C1",[150],{"type":25,"value":151}," $",{"type":20,"tag":141,"props":153,"children":155},{"style":154},"--shiki-default:#032F62",[156],{"type":25,"value":157}," youtube-dl",{"type":20,"tag":141,"props":159,"children":161},{"style":160},"--shiki-default:#005CC5",[162],{"type":25,"value":163}," \\\n",{"type":20,"tag":141,"props":165,"children":167},{"class":143,"line":166},2,[168,173],{"type":20,"tag":141,"props":169,"children":170},{"style":160},[171],{"type":25,"value":172}," --extract-audio",{"type":20,"tag":141,"props":174,"children":175},{"style":160},[176],{"type":25,"value":163},{"type":20,"tag":141,"props":178,"children":180},{"class":143,"line":179},3,[181,186,191],{"type":20,"tag":141,"props":182,"children":183},{"style":160},[184],{"type":25,"value":185}," --audio-format",{"type":20,"tag":141,"props":187,"children":188},{"style":154},[189],{"type":25,"value":190}," wav",{"type":20,"tag":141,"props":192,"children":193},{"style":160},[194],{"type":25,"value":163},{"type":20,"tag":141,"props":196,"children":198},{"class":143,"line":197},4,[199,204,209],{"type":20,"tag":141,"props":200,"children":201},{"style":160},[202],{"type":25,"value":203}," --output",{"type":20,"tag":141,"props":205,"children":206},{"style":154},[207],{"type":25,"value":208}," podcast.wav",{"type":20,"tag":141,"props":210,"children":211},{"style":160},[212],{"type":25,"value":163},{"type":20,"tag":141,"props":214,"children":216},{"class":143,"line":215},5,[217],{"type":20,"tag":141,"props":218,"children":219},{"style":154},[220],{"type":25,"value":221}," \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n",{"type":20,"tag":21,"props":223,"children":224},{},[225,227,232],{"type":25,"value":226},"This file has a 44.1 kHz sample rate, and ",{"type":20,"tag":92,"props":228,"children":230},{"className":229},[],[231],{"type":25,"value":12},{"type":25,"value":233}," expects 16 kHz, so let's go ahead and convert that.",{"type":20,"tag":131,"props":235,"children":237},{"code":236,"language":134,"meta":7,"className":135,"style":7}," $ file podcast.wav\npodcast.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n\n $ ffmpeg -i podcast.wav -ar 16000 podcast-16khz.wav\n\n $ file podcast-16khz.wav\npodcast-16khz.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n\n# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n# flag to the `youtube-dl` command -- I will explore this further next time...\n# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n",[238],{"type":20,"tag":92,"props":239,"children":240},{"__ignoreMap":7},[241,258,277,286,322,329,345,363,371,381,390],{"type":20,"tag":141,"props":242,"children":243},{"class":143,"line":144},[244,248,253],{"type":20,"tag":141,"props":245,"children":246},{"style":148},[247],{"type":25,"value":151},{"type":20,"tag":141,"props":249,"children":250},{"style":154},[251],{"type":25,"value":252}," file",{"type":20,"tag":141,"props":254,"children":255},{"style":154},[256],{"type":25,"value":257}," podcast.wav\n",{"type":20,"tag":141,"props":259,"children":260},{"class":143,"line":166},[261,266,271],{"type":20,"tag":141,"props":262,"children":263},{"style":148},[264],{"type":25,"value":265},"podcast.wav:",{"type":20,"tag":141,"props":267,"children":268},{"style":154},[269],{"type":25,"value":270}," RIFF",{"type":20,"tag":141,"props":272,"children":274},{"style":273},"--shiki-default:#24292E",[275],{"type":25,"value":276}," (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n",{"type":20,"tag":141,"props":278,"children":279},{"class":143,"line":179},[280],{"type":20,"tag":141,"props":281,"children":283},{"emptyLinePlaceholder":282},true,[284],{"type":25,"value":285},"\n",{"type":20,"tag":141,"props":287,"children":288},{"class":143,"line":197},[289,293,298,303,307,312,317],{"type":20,"tag":141,"props":290,"children":291},{"style":148},[292],{"type":25,"value":151},{"type":20,"tag":141,"props":294,"children":295},{"style":154},[296],{"type":25,"value":297}," ffmpeg",{"type":20,"tag":141,"props":299,"children":300},{"style":160},[301],{"type":25,"value":302}," -i",{"type":20,"tag":141,"props":304,"children":305},{"style":154},[306],{"type":25,"value":208},{"type":20,"tag":141,"props":308,"children":309},{"style":160},[310],{"type":25,"value":311}," -ar",{"type":20,"tag":141,"props":313,"children":314},{"style":160},[315],{"type":25,"value":316}," 16000",{"type":20,"tag":141,"props":318,"children":319},{"style":154},[320],{"type":25,"value":321}," podcast-16khz.wav\n",{"type":20,"tag":141,"props":323,"children":324},{"class":143,"line":215},[325],{"type":20,"tag":141,"props":326,"children":327},{"emptyLinePlaceholder":282},[328],{"type":25,"value":285},{"type":20,"tag":141,"props":330,"children":332},{"class":143,"line":331},6,[333,337,341],{"type":20,"tag":141,"props":334,"children":335},{"style":148},[336],{"type":25,"value":151},{"type":20,"tag":141,"props":338,"children":339},{"style":154},[340],{"type":25,"value":252},{"type":20,"tag":141,"props":342,"children":343},{"style":154},[344],{"type":25,"value":321},{"type":20,"tag":141,"props":346,"children":348},{"class":143,"line":347},7,[349,354,358],{"type":20,"tag":141,"props":350,"children":351},{"style":148},[352],{"type":25,"value":353},"podcast-16khz.wav:",{"type":20,"tag":141,"props":355,"children":356},{"style":154},[357],{"type":25,"value":270},{"type":20,"tag":141,"props":359,"children":360},{"style":273},[361],{"type":25,"value":362}," (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n",{"type":20,"tag":141,"props":364,"children":366},{"class":143,"line":365},8,[367],{"type":20,"tag":141,"props":368,"children":369},{"emptyLinePlaceholder":282},[370],{"type":25,"value":285},{"type":20,"tag":141,"props":372,"children":374},{"class":143,"line":373},9,[375],{"type":20,"tag":141,"props":376,"children":378},{"style":377},"--shiki-default:#6A737D",[379],{"type":25,"value":380},"# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n",{"type":20,"tag":141,"props":382,"children":384},{"class":143,"line":383},10,[385],{"type":20,"tag":141,"props":386,"children":387},{"style":377},[388],{"type":25,"value":389},"# flag to the `youtube-dl` command -- I will explore this further next time...\n",{"type":20,"tag":141,"props":391,"children":393},{"class":143,"line":392},11,[394],{"type":20,"tag":141,"props":395,"children":396},{"style":377},[397],{"type":25,"value":398},"# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n",{"type":20,"tag":80,"props":400,"children":402},{"id":401},"build-whispercpp-transcribe-audio",[403,405,410],{"type":25,"value":404},"Build ",{"type":20,"tag":92,"props":406,"children":408},{"className":407},[],[409],{"type":25,"value":12},{"type":25,"value":411}," & Transcribe Audio",{"type":20,"tag":21,"props":413,"children":414},{},[415,417,422],{"type":25,"value":416},"Then, let's get the latest version of ",{"type":20,"tag":92,"props":418,"children":420},{"className":419},[],[421],{"type":25,"value":12},{"type":25,"value":423},", download the English Whisper model, and build the example.",{"type":20,"tag":131,"props":425,"children":427},{"code":426,"language":134,"meta":7,"className":135,"style":7},"# Clone the `whisper.cpp` repository\n $ git clone --depth 1 git@github.com:ggerganov/whisper.cpp && cd whisper.cpp\n\n# Download the English Whisper model in `ggml` format\n $ bash ./models/download-ggml-model.sh base.en\n\n# Build the main example\n $ make\n",[428],{"type":20,"tag":92,"props":429,"children":430},{"__ignoreMap":7},[431,439,486,493,501,523,530,538],{"type":20,"tag":141,"props":432,"children":433},{"class":143,"line":144},[434],{"type":20,"tag":141,"props":435,"children":436},{"style":377},[437],{"type":25,"value":438},"# Clone the `whisper.cpp` repository\n",{"type":20,"tag":141,"props":440,"children":441},{"class":143,"line":166},[442,446,451,456,461,466,471,476,481],{"type":20,"tag":141,"props":443,"children":444},{"style":148},[445],{"type":25,"value":151},{"type":20,"tag":141,"props":447,"children":448},{"style":154},[449],{"type":25,"value":450}," git",{"type":20,"tag":141,"props":452,"children":453},{"style":154},[454],{"type":25,"value":455}," clone",{"type":20,"tag":141,"props":457,"children":458},{"style":160},[459],{"type":25,"value":460}," --depth",{"type":20,"tag":141,"props":462,"children":463},{"style":160},[464],{"type":25,"value":465}," 1",{"type":20,"tag":141,"props":467,"children":468},{"style":154},[469],{"type":25,"value":470}," git@github.com:ggerganov/whisper.cpp",{"type":20,"tag":141,"props":472,"children":473},{"style":273},[474],{"type":25,"value":475}," && ",{"type":20,"tag":141,"props":477,"children":478},{"style":160},[479],{"type":25,"value":480},"cd",{"type":20,"tag":141,"props":482,"children":483},{"style":154},[484],{"type":25,"value":485}," whisper.cpp\n",{"type":20,"tag":141,"props":487,"children":488},{"class":143,"line":179},[489],{"type":20,"tag":141,"props":490,"children":491},{"emptyLinePlaceholder":282},[492],{"type":25,"value":285},{"type":20,"tag":141,"props":494,"children":495},{"class":143,"line":197},[496],{"type":20,"tag":141,"props":497,"children":498},{"style":377},[499],{"type":25,"value":500},"# Download the English Whisper model in `ggml` format\n",{"type":20,"tag":141,"props":502,"children":503},{"class":143,"line":215},[504,508,513,518],{"type":20,"tag":141,"props":505,"children":506},{"style":148},[507],{"type":25,"value":151},{"type":20,"tag":141,"props":509,"children":510},{"style":154},[511],{"type":25,"value":512}," bash",{"type":20,"tag":141,"props":514,"children":515},{"style":154},[516],{"type":25,"value":517}," ./models/download-ggml-model.sh",{"type":20,"tag":141,"props":519,"children":520},{"style":154},[521],{"type":25,"value":522}," base.en\n",{"type":20,"tag":141,"props":524,"children":525},{"class":143,"line":331},[526],{"type":20,"tag":141,"props":527,"children":528},{"emptyLinePlaceholder":282},[529],{"type":25,"value":285},{"type":20,"tag":141,"props":531,"children":532},{"class":143,"line":347},[533],{"type":20,"tag":141,"props":534,"children":535},{"style":377},[536],{"type":25,"value":537},"# Build the main example\n",{"type":20,"tag":141,"props":539,"children":540},{"class":143,"line":365},[541,545],{"type":20,"tag":141,"props":542,"children":543},{"style":148},[544],{"type":25,"value":151},{"type":20,"tag":141,"props":546,"children":547},{"style":154},[548],{"type":25,"value":549}," make\n",{"type":20,"tag":21,"props":551,"children":552},{},[553],{"type":25,"value":554},"And finally, let's transcribe that podcast!",{"type":20,"tag":131,"props":556,"children":558},{"code":557,"language":134,"meta":7,"className":135,"style":7}," $ ./main \\\n -m ~/workspace/whisper.cpp/models/ggml-base.en.bin \\\n -f ~/Downloads/podcast-16khz.wav \\\n --output-vtt \\\n --output-file out\n\n# whisper_print_timings: load time = 114.71 ms\n# whisper_print_timings: fallbacks = 0 p / 0 h\n# whisper_print_timings: mel time = 692.20 ms\n# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n# whisper_print_timings: total time = 80709.54 ms\n",[559],{"type":20,"tag":92,"props":560,"children":561},{"__ignoreMap":7},[562,578,595,612,624,637,644,652,660,668,676,684,693,702,711],{"type":20,"tag":141,"props":563,"children":564},{"class":143,"line":144},[565,569,574],{"type":20,"tag":141,"props":566,"children":567},{"style":148},[568],{"type":25,"value":151},{"type":20,"tag":141,"props":570,"children":571},{"style":154},[572],{"type":25,"value":573}," ./main",{"type":20,"tag":141,"props":575,"children":576},{"style":160},[577],{"type":25,"value":163},{"type":20,"tag":141,"props":579,"children":580},{"class":143,"line":166},[581,586,591],{"type":20,"tag":141,"props":582,"children":583},{"style":160},[584],{"type":25,"value":585}," -m",{"type":20,"tag":141,"props":587,"children":588},{"style":154},[589],{"type":25,"value":590}," ~/workspace/whisper.cpp/models/ggml-base.en.bin",{"type":20,"tag":141,"props":592,"children":593},{"style":160},[594],{"type":25,"value":163},{"type":20,"tag":141,"props":596,"children":597},{"class":143,"line":179},[598,603,608],{"type":20,"tag":141,"props":599,"children":600},{"style":160},[601],{"type":25,"value":602}," -f",{"type":20,"tag":141,"props":604,"children":605},{"style":154},[606],{"type":25,"value":607}," ~/Downloads/podcast-16khz.wav",{"type":20,"tag":141,"props":609,"children":610},{"style":160},[611],{"type":25,"value":163},{"type":20,"tag":141,"props":613,"children":614},{"class":143,"line":197},[615,620],{"type":20,"tag":141,"props":616,"children":617},{"style":160},[618],{"type":25,"value":619}," --output-vtt",{"type":20,"tag":141,"props":621,"children":622},{"style":160},[623],{"type":25,"value":163},{"type":20,"tag":141,"props":625,"children":626},{"class":143,"line":215},[627,632],{"type":20,"tag":141,"props":628,"children":629},{"style":160},[630],{"type":25,"value":631}," --output-file",{"type":20,"tag":141,"props":633,"children":634},{"style":154},[635],{"type":25,"value":636}," out\n",{"type":20,"tag":141,"props":638,"children":639},{"class":143,"line":331},[640],{"type":20,"tag":141,"props":641,"children":642},{"emptyLinePlaceholder":282},[643],{"type":25,"value":285},{"type":20,"tag":141,"props":645,"children":646},{"class":143,"line":347},[647],{"type":20,"tag":141,"props":648,"children":649},{"style":377},[650],{"type":25,"value":651},"# whisper_print_timings: load time = 114.71 ms\n",{"type":20,"tag":141,"props":653,"children":654},{"class":143,"line":365},[655],{"type":20,"tag":141,"props":656,"children":657},{"style":377},[658],{"type":25,"value":659},"# whisper_print_timings: fallbacks = 0 p / 0 h\n",{"type":20,"tag":141,"props":661,"children":662},{"class":143,"line":373},[663],{"type":20,"tag":141,"props":664,"children":665},{"style":377},[666],{"type":25,"value":667},"# whisper_print_timings: mel time = 692.20 ms\n",{"type":20,"tag":141,"props":669,"children":670},{"class":143,"line":383},[671],{"type":20,"tag":141,"props":672,"children":673},{"style":377},[674],{"type":25,"value":675},"# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n",{"type":20,"tag":141,"props":677,"children":678},{"class":143,"line":392},[679],{"type":20,"tag":141,"props":680,"children":681},{"style":377},[682],{"type":25,"value":683},"# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n",{"type":20,"tag":141,"props":685,"children":687},{"class":143,"line":686},12,[688],{"type":20,"tag":141,"props":689,"children":690},{"style":377},[691],{"type":25,"value":692},"# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n",{"type":20,"tag":141,"props":694,"children":696},{"class":143,"line":695},13,[697],{"type":20,"tag":141,"props":698,"children":699},{"style":377},[700],{"type":25,"value":701},"# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n",{"type":20,"tag":141,"props":703,"children":705},{"class":143,"line":704},14,[706],{"type":20,"tag":141,"props":707,"children":708},{"style":377},[709],{"type":25,"value":710},"# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n",{"type":20,"tag":141,"props":712,"children":714},{"class":143,"line":713},15,[715],{"type":20,"tag":141,"props":716,"children":717},{"style":377},[718],{"type":25,"value":719},"# whisper_print_timings: total time = 80709.54 ms\n",{"type":20,"tag":21,"props":721,"children":722},{},[723],{"type":25,"value":724},"A full podcast transcribed in ~80 seconds on an M1 Mac Mini -- not too bad!",{"type":20,"tag":131,"props":726,"children":728},{"code":727},"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n",[729],{"type":20,"tag":92,"props":730,"children":731},{"__ignoreMap":7},[732],{"type":25,"value":727},{"type":20,"tag":734,"props":735,"children":736},"style",{},[737],{"type":25,"value":738},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":166,"depth":166,"links":740},[741,742],{"id":82,"depth":166,"text":85},{"id":401,"depth":166,"text":743},"Build whisper.cpp & Transcribe Audio","markdown","content:articles:podcast-transcription-whispercpp.md","content","articles/podcast-transcription-whispercpp.md","md",1718891181717] \ No newline at end of file +[{"data":1,"prerenderedAt":750},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"excerpt":16,"body":55,"_type":744,"_id":745,"_source":746,"_file":747,"_stem":748,"_extension":749},"/articles/podcast-transcription-whispercpp","articles",false,"","Easily Transcribe Podcasts with Whisper.cpp","If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.","2024-01-08",[12,13],"whisper.cpp","ml",[15],"programming",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,35,37,44,46,53],{"type":25,"value":26},"text","If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive ",{"type":20,"tag":28,"props":29,"children":33},"a",{"href":30,"rel":31},"https://github.com/ggerganov/whisper.cpp",[32],"nofollow",[34],{"type":25,"value":12},{"type":25,"value":36}," project. This high-performance fork of ",{"type":20,"tag":28,"props":38,"children":41},{"href":39,"rel":40},"https://github.com/openai/whisper",[32],[42],{"type":25,"value":43},"OpenAI's Whisper",{"type":25,"value":45}," can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the ",{"type":20,"tag":28,"props":47,"children":50},{"href":48,"rel":49},"https://podcasts.apple.com/us/podcast/alter-everything/id1356137854",[32],[51],{"type":25,"value":52},"Alter Everything",{"type":25,"value":54}," podcast.",{"type":17,"children":56,"toc":739},[57,79,86,130,222,234,399,412,424,550,555,720,725,733],{"type":20,"tag":21,"props":58,"children":59},{},[60,61,66,67,72,73,78],{"type":25,"value":26},{"type":20,"tag":28,"props":62,"children":64},{"href":30,"rel":63},[32],[65],{"type":25,"value":12},{"type":25,"value":36},{"type":20,"tag":28,"props":68,"children":70},{"href":39,"rel":69},[32],[71],{"type":25,"value":43},{"type":25,"value":45},{"type":20,"tag":28,"props":74,"children":76},{"href":48,"rel":75},[32],[77],{"type":25,"value":52},{"type":25,"value":54},{"type":20,"tag":80,"props":81,"children":83},"h2",{"id":82},"obtain-audio-files",[84],{"type":25,"value":85},"Obtain Audio File(s)",{"type":20,"tag":21,"props":87,"children":88},{},[89,91,98,100,106,108,113,115,120,122,128],{"type":25,"value":90},"First, let's get the ",{"type":20,"tag":92,"props":93,"children":95},"code",{"className":94},[],[96],{"type":25,"value":97},"wav",{"type":25,"value":99}," file from YouTube using the ",{"type":20,"tag":92,"props":101,"children":103},{"className":102},[],[104],{"type":25,"value":105},"youtube-dl",{"type":25,"value":107}," utility. It should be noted that ",{"type":20,"tag":92,"props":109,"children":111},{"className":110},[],[112],{"type":25,"value":12},{"type":25,"value":114}," expects ",{"type":20,"tag":92,"props":116,"children":118},{"className":117},[],[119],{"type":25,"value":97},{"type":25,"value":121}," filetypes, and this utility defaults to ",{"type":20,"tag":92,"props":123,"children":125},{"className":124},[],[126],{"type":25,"value":127},"mp3",{"type":25,"value":129},".",{"type":20,"tag":131,"props":132,"children":136},"pre",{"code":133,"language":134,"meta":7,"className":135,"style":7}," $ youtube-dl \\\n --extract-audio \\\n --audio-format wav \\\n --output podcast.wav \\\n \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n","sh","language-sh shiki shiki-themes github-light",[137],{"type":20,"tag":92,"props":138,"children":139},{"__ignoreMap":7},[140,164,177,195,213],{"type":20,"tag":141,"props":142,"children":145},"span",{"class":143,"line":144},"line",1,[146,152,158],{"type":20,"tag":141,"props":147,"children":149},{"style":148},"--shiki-default:#6F42C1",[150],{"type":25,"value":151}," $",{"type":20,"tag":141,"props":153,"children":155},{"style":154},"--shiki-default:#032F62",[156],{"type":25,"value":157}," youtube-dl",{"type":20,"tag":141,"props":159,"children":161},{"style":160},"--shiki-default:#005CC5",[162],{"type":25,"value":163}," \\\n",{"type":20,"tag":141,"props":165,"children":167},{"class":143,"line":166},2,[168,173],{"type":20,"tag":141,"props":169,"children":170},{"style":160},[171],{"type":25,"value":172}," --extract-audio",{"type":20,"tag":141,"props":174,"children":175},{"style":160},[176],{"type":25,"value":163},{"type":20,"tag":141,"props":178,"children":180},{"class":143,"line":179},3,[181,186,191],{"type":20,"tag":141,"props":182,"children":183},{"style":160},[184],{"type":25,"value":185}," --audio-format",{"type":20,"tag":141,"props":187,"children":188},{"style":154},[189],{"type":25,"value":190}," wav",{"type":20,"tag":141,"props":192,"children":193},{"style":160},[194],{"type":25,"value":163},{"type":20,"tag":141,"props":196,"children":198},{"class":143,"line":197},4,[199,204,209],{"type":20,"tag":141,"props":200,"children":201},{"style":160},[202],{"type":25,"value":203}," --output",{"type":20,"tag":141,"props":205,"children":206},{"style":154},[207],{"type":25,"value":208}," podcast.wav",{"type":20,"tag":141,"props":210,"children":211},{"style":160},[212],{"type":25,"value":163},{"type":20,"tag":141,"props":214,"children":216},{"class":143,"line":215},5,[217],{"type":20,"tag":141,"props":218,"children":219},{"style":154},[220],{"type":25,"value":221}," \"https://www.youtube.com/watch?v=CoUN690wSYQ\"\n",{"type":20,"tag":21,"props":223,"children":224},{},[225,227,232],{"type":25,"value":226},"This file has a 44.1 kHz sample rate, and ",{"type":20,"tag":92,"props":228,"children":230},{"className":229},[],[231],{"type":25,"value":12},{"type":25,"value":233}," expects 16 kHz, so let's go ahead and convert that.",{"type":20,"tag":131,"props":235,"children":237},{"code":236,"language":134,"meta":7,"className":135,"style":7}," $ file podcast.wav\npodcast.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n\n $ ffmpeg -i podcast.wav -ar 16000 podcast-16khz.wav\n\n $ file podcast-16khz.wav\npodcast-16khz.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n\n# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n# flag to the `youtube-dl` command -- I will explore this further next time...\n# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n",[238],{"type":20,"tag":92,"props":239,"children":240},{"__ignoreMap":7},[241,258,277,286,322,329,345,363,371,381,390],{"type":20,"tag":141,"props":242,"children":243},{"class":143,"line":144},[244,248,253],{"type":20,"tag":141,"props":245,"children":246},{"style":148},[247],{"type":25,"value":151},{"type":20,"tag":141,"props":249,"children":250},{"style":154},[251],{"type":25,"value":252}," file",{"type":20,"tag":141,"props":254,"children":255},{"style":154},[256],{"type":25,"value":257}," podcast.wav\n",{"type":20,"tag":141,"props":259,"children":260},{"class":143,"line":166},[261,266,271],{"type":20,"tag":141,"props":262,"children":263},{"style":148},[264],{"type":25,"value":265},"podcast.wav:",{"type":20,"tag":141,"props":267,"children":268},{"style":154},[269],{"type":25,"value":270}," RIFF",{"type":20,"tag":141,"props":272,"children":274},{"style":273},"--shiki-default:#24292E",[275],{"type":25,"value":276}," (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz\n",{"type":20,"tag":141,"props":278,"children":279},{"class":143,"line":179},[280],{"type":20,"tag":141,"props":281,"children":283},{"emptyLinePlaceholder":282},true,[284],{"type":25,"value":285},"\n",{"type":20,"tag":141,"props":287,"children":288},{"class":143,"line":197},[289,293,298,303,307,312,317],{"type":20,"tag":141,"props":290,"children":291},{"style":148},[292],{"type":25,"value":151},{"type":20,"tag":141,"props":294,"children":295},{"style":154},[296],{"type":25,"value":297}," ffmpeg",{"type":20,"tag":141,"props":299,"children":300},{"style":160},[301],{"type":25,"value":302}," -i",{"type":20,"tag":141,"props":304,"children":305},{"style":154},[306],{"type":25,"value":208},{"type":20,"tag":141,"props":308,"children":309},{"style":160},[310],{"type":25,"value":311}," -ar",{"type":20,"tag":141,"props":313,"children":314},{"style":160},[315],{"type":25,"value":316}," 16000",{"type":20,"tag":141,"props":318,"children":319},{"style":154},[320],{"type":25,"value":321}," podcast-16khz.wav\n",{"type":20,"tag":141,"props":323,"children":324},{"class":143,"line":215},[325],{"type":20,"tag":141,"props":326,"children":327},{"emptyLinePlaceholder":282},[328],{"type":25,"value":285},{"type":20,"tag":141,"props":330,"children":332},{"class":143,"line":331},6,[333,337,341],{"type":20,"tag":141,"props":334,"children":335},{"style":148},[336],{"type":25,"value":151},{"type":20,"tag":141,"props":338,"children":339},{"style":154},[340],{"type":25,"value":252},{"type":20,"tag":141,"props":342,"children":343},{"style":154},[344],{"type":25,"value":321},{"type":20,"tag":141,"props":346,"children":348},{"class":143,"line":347},7,[349,354,358],{"type":20,"tag":141,"props":350,"children":351},{"style":148},[352],{"type":25,"value":353},"podcast-16khz.wav:",{"type":20,"tag":141,"props":355,"children":356},{"style":154},[357],{"type":25,"value":270},{"type":20,"tag":141,"props":359,"children":360},{"style":273},[361],{"type":25,"value":362}," (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 16000 Hz\n",{"type":20,"tag":141,"props":364,"children":366},{"class":143,"line":365},8,[367],{"type":20,"tag":141,"props":368,"children":369},{"emptyLinePlaceholder":282},[370],{"type":25,"value":285},{"type":20,"tag":141,"props":372,"children":374},{"class":143,"line":373},9,[375],{"type":20,"tag":141,"props":376,"children":378},{"style":377},"--shiki-default:#6A737D",[379],{"type":25,"value":380},"# NOTE: it looks like it's possible to specify this conversion as a post-process as a\n",{"type":20,"tag":141,"props":382,"children":384},{"class":143,"line":383},10,[385],{"type":20,"tag":141,"props":386,"children":387},{"style":377},[388],{"type":25,"value":389},"# flag to the `youtube-dl` command -- I will explore this further next time...\n",{"type":20,"tag":141,"props":391,"children":393},{"class":143,"line":392},11,[394],{"type":20,"tag":141,"props":395,"children":396},{"style":377},[397],{"type":25,"value":398},"# youtube-dl --extract-audio --audio-quality 0 --audio-format mp3 --postprocessor-args \"-ar 44100\" %dl%\n",{"type":20,"tag":80,"props":400,"children":402},{"id":401},"build-whispercpp-transcribe-audio",[403,405,410],{"type":25,"value":404},"Build ",{"type":20,"tag":92,"props":406,"children":408},{"className":407},[],[409],{"type":25,"value":12},{"type":25,"value":411}," & Transcribe Audio",{"type":20,"tag":21,"props":413,"children":414},{},[415,417,422],{"type":25,"value":416},"Then, let's get the latest version of ",{"type":20,"tag":92,"props":418,"children":420},{"className":419},[],[421],{"type":25,"value":12},{"type":25,"value":423},", download the English Whisper model, and build the example.",{"type":20,"tag":131,"props":425,"children":427},{"code":426,"language":134,"meta":7,"className":135,"style":7},"# Clone the `whisper.cpp` repository\n $ git clone --depth 1 git@github.com:ggerganov/whisper.cpp && cd whisper.cpp\n\n# Download the English Whisper model in `ggml` format\n $ bash ./models/download-ggml-model.sh base.en\n\n# Build the main example\n $ make\n",[428],{"type":20,"tag":92,"props":429,"children":430},{"__ignoreMap":7},[431,439,486,493,501,523,530,538],{"type":20,"tag":141,"props":432,"children":433},{"class":143,"line":144},[434],{"type":20,"tag":141,"props":435,"children":436},{"style":377},[437],{"type":25,"value":438},"# Clone the `whisper.cpp` repository\n",{"type":20,"tag":141,"props":440,"children":441},{"class":143,"line":166},[442,446,451,456,461,466,471,476,481],{"type":20,"tag":141,"props":443,"children":444},{"style":148},[445],{"type":25,"value":151},{"type":20,"tag":141,"props":447,"children":448},{"style":154},[449],{"type":25,"value":450}," git",{"type":20,"tag":141,"props":452,"children":453},{"style":154},[454],{"type":25,"value":455}," clone",{"type":20,"tag":141,"props":457,"children":458},{"style":160},[459],{"type":25,"value":460}," --depth",{"type":20,"tag":141,"props":462,"children":463},{"style":160},[464],{"type":25,"value":465}," 1",{"type":20,"tag":141,"props":467,"children":468},{"style":154},[469],{"type":25,"value":470}," git@github.com:ggerganov/whisper.cpp",{"type":20,"tag":141,"props":472,"children":473},{"style":273},[474],{"type":25,"value":475}," && ",{"type":20,"tag":141,"props":477,"children":478},{"style":160},[479],{"type":25,"value":480},"cd",{"type":20,"tag":141,"props":482,"children":483},{"style":154},[484],{"type":25,"value":485}," whisper.cpp\n",{"type":20,"tag":141,"props":487,"children":488},{"class":143,"line":179},[489],{"type":20,"tag":141,"props":490,"children":491},{"emptyLinePlaceholder":282},[492],{"type":25,"value":285},{"type":20,"tag":141,"props":494,"children":495},{"class":143,"line":197},[496],{"type":20,"tag":141,"props":497,"children":498},{"style":377},[499],{"type":25,"value":500},"# Download the English Whisper model in `ggml` format\n",{"type":20,"tag":141,"props":502,"children":503},{"class":143,"line":215},[504,508,513,518],{"type":20,"tag":141,"props":505,"children":506},{"style":148},[507],{"type":25,"value":151},{"type":20,"tag":141,"props":509,"children":510},{"style":154},[511],{"type":25,"value":512}," bash",{"type":20,"tag":141,"props":514,"children":515},{"style":154},[516],{"type":25,"value":517}," ./models/download-ggml-model.sh",{"type":20,"tag":141,"props":519,"children":520},{"style":154},[521],{"type":25,"value":522}," base.en\n",{"type":20,"tag":141,"props":524,"children":525},{"class":143,"line":331},[526],{"type":20,"tag":141,"props":527,"children":528},{"emptyLinePlaceholder":282},[529],{"type":25,"value":285},{"type":20,"tag":141,"props":531,"children":532},{"class":143,"line":347},[533],{"type":20,"tag":141,"props":534,"children":535},{"style":377},[536],{"type":25,"value":537},"# Build the main example\n",{"type":20,"tag":141,"props":539,"children":540},{"class":143,"line":365},[541,545],{"type":20,"tag":141,"props":542,"children":543},{"style":148},[544],{"type":25,"value":151},{"type":20,"tag":141,"props":546,"children":547},{"style":154},[548],{"type":25,"value":549}," make\n",{"type":20,"tag":21,"props":551,"children":552},{},[553],{"type":25,"value":554},"And finally, let's transcribe that podcast!",{"type":20,"tag":131,"props":556,"children":558},{"code":557,"language":134,"meta":7,"className":135,"style":7}," $ ./main \\\n -m ~/workspace/whisper.cpp/models/ggml-base.en.bin \\\n -f ~/Downloads/podcast-16khz.wav \\\n --output-vtt \\\n --output-file out\n\n# whisper_print_timings: load time = 114.71 ms\n# whisper_print_timings: fallbacks = 0 p / 0 h\n# whisper_print_timings: mel time = 692.20 ms\n# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n# whisper_print_timings: total time = 80709.54 ms\n",[559],{"type":20,"tag":92,"props":560,"children":561},{"__ignoreMap":7},[562,578,595,612,624,637,644,652,660,668,676,684,693,702,711],{"type":20,"tag":141,"props":563,"children":564},{"class":143,"line":144},[565,569,574],{"type":20,"tag":141,"props":566,"children":567},{"style":148},[568],{"type":25,"value":151},{"type":20,"tag":141,"props":570,"children":571},{"style":154},[572],{"type":25,"value":573}," ./main",{"type":20,"tag":141,"props":575,"children":576},{"style":160},[577],{"type":25,"value":163},{"type":20,"tag":141,"props":579,"children":580},{"class":143,"line":166},[581,586,591],{"type":20,"tag":141,"props":582,"children":583},{"style":160},[584],{"type":25,"value":585}," -m",{"type":20,"tag":141,"props":587,"children":588},{"style":154},[589],{"type":25,"value":590}," ~/workspace/whisper.cpp/models/ggml-base.en.bin",{"type":20,"tag":141,"props":592,"children":593},{"style":160},[594],{"type":25,"value":163},{"type":20,"tag":141,"props":596,"children":597},{"class":143,"line":179},[598,603,608],{"type":20,"tag":141,"props":599,"children":600},{"style":160},[601],{"type":25,"value":602}," -f",{"type":20,"tag":141,"props":604,"children":605},{"style":154},[606],{"type":25,"value":607}," ~/Downloads/podcast-16khz.wav",{"type":20,"tag":141,"props":609,"children":610},{"style":160},[611],{"type":25,"value":163},{"type":20,"tag":141,"props":613,"children":614},{"class":143,"line":197},[615,620],{"type":20,"tag":141,"props":616,"children":617},{"style":160},[618],{"type":25,"value":619}," --output-vtt",{"type":20,"tag":141,"props":621,"children":622},{"style":160},[623],{"type":25,"value":163},{"type":20,"tag":141,"props":625,"children":626},{"class":143,"line":215},[627,632],{"type":20,"tag":141,"props":628,"children":629},{"style":160},[630],{"type":25,"value":631}," --output-file",{"type":20,"tag":141,"props":633,"children":634},{"style":154},[635],{"type":25,"value":636}," out\n",{"type":20,"tag":141,"props":638,"children":639},{"class":143,"line":331},[640],{"type":20,"tag":141,"props":641,"children":642},{"emptyLinePlaceholder":282},[643],{"type":25,"value":285},{"type":20,"tag":141,"props":645,"children":646},{"class":143,"line":347},[647],{"type":20,"tag":141,"props":648,"children":649},{"style":377},[650],{"type":25,"value":651},"# whisper_print_timings: load time = 114.71 ms\n",{"type":20,"tag":141,"props":653,"children":654},{"class":143,"line":365},[655],{"type":20,"tag":141,"props":656,"children":657},{"style":377},[658],{"type":25,"value":659},"# whisper_print_timings: fallbacks = 0 p / 0 h\n",{"type":20,"tag":141,"props":661,"children":662},{"class":143,"line":373},[663],{"type":20,"tag":141,"props":664,"children":665},{"style":377},[666],{"type":25,"value":667},"# whisper_print_timings: mel time = 692.20 ms\n",{"type":20,"tag":141,"props":669,"children":670},{"class":143,"line":383},[671],{"type":20,"tag":141,"props":672,"children":673},{"style":377},[674],{"type":25,"value":675},"# whisper_print_timings: sample time = 22278.10 ms / 27893 runs ( 0.80 ms per run)\n",{"type":20,"tag":141,"props":677,"children":678},{"class":143,"line":392},[679],{"type":20,"tag":141,"props":680,"children":681},{"style":377},[682],{"type":25,"value":683},"# whisper_print_timings: encode time = 10000.75 ms / 55 runs ( 181.83 ms per run)\n",{"type":20,"tag":141,"props":685,"children":687},{"class":143,"line":686},12,[688],{"type":20,"tag":141,"props":689,"children":690},{"style":377},[691],{"type":25,"value":692},"# whisper_print_timings: decode time = 331.77 ms / 54 runs ( 6.14 ms per run)\n",{"type":20,"tag":141,"props":694,"children":696},{"class":143,"line":695},13,[697],{"type":20,"tag":141,"props":698,"children":699},{"style":377},[700],{"type":25,"value":701},"# whisper_print_timings: batchd time = 45236.73 ms / 27566 runs ( 1.64 ms per run)\n",{"type":20,"tag":141,"props":703,"children":705},{"class":143,"line":704},14,[706],{"type":20,"tag":141,"props":707,"children":708},{"style":377},[709],{"type":25,"value":710},"# whisper_print_timings: prompt time = 1921.90 ms / 11832 runs ( 0.16 ms per run)\n",{"type":20,"tag":141,"props":712,"children":714},{"class":143,"line":713},15,[715],{"type":20,"tag":141,"props":716,"children":717},{"style":377},[718],{"type":25,"value":719},"# whisper_print_timings: total time = 80709.54 ms\n",{"type":20,"tag":21,"props":721,"children":722},{},[723],{"type":25,"value":724},"A full podcast transcribed in ~80 seconds on an M1 Mac Mini -- not too bad!",{"type":20,"tag":131,"props":726,"children":728},{"code":727},"# out.vtt\n\n00:00:00.000 --> 00:00:06.480\n >> Hi everyone. We recently launched a short engagement feedback survey for the Alter Everything\n\n00:00:06.480 --> 00:00:11.360\n podcast. Click the link in the episode description wherever you're listening to let us know what\n\n00:00:11.360 --> 00:00:16.320\n you think and help us improve our show.\n\n00:00:16.320 --> 00:00:21.200\n Welcome to Alter Everything, a podcast about data science and analytics culture. I'm Megan\n\n00:00:21.200 --> 00:00:26.440\n Dibble and today I'm talking with Nick Schrock, CTO and founder of Dagster Labs. We discussed\n\n00:00:26.440 --> 00:00:31.560\n data engineering trends, challenges in the field, why he started his company, and what\n\n00:00:31.560 --> 00:00:38.960\n makes him excited about the future of data engineering. Let's get started.\n\n00:00:38.960 --> 00:00:42.720\n >> Hi, Nick. It's great to have you on our show today. Thanks for being here.\n\n00:00:42.720 --> 00:00:43.920\n >> Thanks for having me.\n\n00:00:43.920 --> 00:00:48.280\n >> Yeah. Could you start off by giving an introduction to yourself for our listeners?\n\n00:00:48.280 --> 00:00:52.920\n >> Sure. My name is Nick Schrock. I'm the CTO and founder of Dagster Labs. There's the\n\n00:00:52.920 --> 00:00:59.520\n company behind Dagster, which is a data orchestration framework. Prior to doing this, I was an engineer\n\n00:00:59.520 --> 00:01:05.960\n at Facebook from 2009, 2017. While I was there, I found a team called product infrastructure\n\n00:01:05.960 --> 00:01:09.800\n whose goal was to make our application developers more efficient and productive, and a bunch\n\n00:01:09.800 --> 00:01:13.840\n of open source work came out of that actually, one of which was React, which I had nothing\n\n00:01:13.840 --> 00:01:18.040\n to do with, but actually the CEO of Dagster Labs co-created and I personally co-created\n\n00:01:18.040 --> 00:01:22.640\n GraphQL. So as I like to say, Pete and I were present at the creation of the full hipster\n\n00:01:22.640 --> 00:01:28.680\n stack. I moved on to Facebook in 2017, figuring out what to do next, and this data engineering\n\n00:01:28.680 --> 00:01:32.960\n and data orchestration problem really got me hooked actually quite soon after I left,\n\n00:01:32.960 --> 00:01:36.280\n and the rest is history. I'm sure we'll get into that more.\n",[729],{"type":20,"tag":92,"props":730,"children":731},{"__ignoreMap":7},[732],{"type":25,"value":727},{"type":20,"tag":734,"props":735,"children":736},"style",{},[737],{"type":25,"value":738},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":166,"depth":166,"links":740},[741,742],{"id":82,"depth":166,"text":85},{"id":401,"depth":166,"text":743},"Build whisper.cpp & Transcribe Audio","markdown","content:articles:podcast-transcription-whispercpp.md","content","articles/podcast-transcription-whispercpp.md","articles/podcast-transcription-whispercpp","md",1720229315488] \ No newline at end of file diff --git a/articles/podcast-transcription-whispercpp/index.html b/articles/podcast-transcription-whispercpp/index.html index ceb6ddd1..73f3f421 100644 --- a/articles/podcast-transcription-whispercpp/index.html +++ b/articles/podcast-transcription-whispercpp/index.html @@ -4,32 +4,33 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - -

            Easily Transcribe Podcasts with Whisper.cpp

            2024-01-08

            If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.

            Obtain Audio File(s)

            First, let's get the wav file from YouTube using the youtube-dl utility. It should be noted that whisper.cpp expects wav filetypes, and this utility defaults to mp3.

             $ youtube-dl \
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Easily Transcribe Podcasts with Whisper.cpp

            If you've ever had the need to transcribe a podcast, lecture, or some other audio recording, it turns out it's surprisingly easy with the extremely impressive whisper.cpp project. This high-performance fork of OpenAI's Whisper can run on all sorts of hardware -- including my M1 Mac Mini. Let's walk through an example from start-to-finish of transcribing an episode of the Alter Everything podcast.

            Obtain Audio File(s)

            First, let's get the wav file from YouTube using the youtube-dl utility. It should be noted that whisper.cpp expects wav filetypes, and this utility defaults to mp3.

             $ youtube-dl \
                 --extract-audio \
                 --audio-format wav \
                 --output podcast.wav \
            @@ -129,5 +130,5 @@
             
             00:01:32.960 --> 00:01:36.280
              and the rest is history. I'm sure we'll get into that more.
            -
            - \ No newline at end of file +
            + \ No newline at end of file diff --git a/articles/quick-tip-rerunning-bash-commands/_payload.json b/articles/quick-tip-rerunning-bash-commands/_payload.json index bdd71681..1b390bba 100644 --- a/articles/quick-tip-rerunning-bash-commands/_payload.json +++ b/articles/quick-tip-rerunning-bash-commands/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":646},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":36,"_type":641,"_id":642,"_source":643,"_file":644,"_extension":645},"/articles/quick-tip-rerunning-bash-commands","articles",false,"","Tip: Re-running Bash Commands","Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","2021-09-22",[12,13],"tip","bash",[15],"tips",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,34],{"type":25,"value":26},"text","Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use ",{"type":20,"tag":28,"props":29,"children":31},"code",{"className":30},[],[32],{"type":25,"value":33},"sudo",{"type":25,"value":35}," for a command that requires\nroot privileges.",{"type":17,"children":37,"toc":639},[38,48,134,161,245,250,279,381,409,463,476,511,530,572,599,603,633],{"type":20,"tag":21,"props":39,"children":40},{},[41,42,47],{"type":25,"value":26},{"type":20,"tag":28,"props":43,"children":45},{"className":44},[],[46],{"type":25,"value":33},{"type":25,"value":35},{"type":20,"tag":49,"props":50,"children":53},"pre",{"className":51,"code":52,"language":13,"meta":7,"style":7},"language-bash shiki shiki-themes github-light","$ pacman -Syu\nerror: you cannot perform this operation unless you are root.\n",[54],{"type":20,"tag":28,"props":55,"children":56},{"__ignoreMap":7},[57,81],{"type":20,"tag":58,"props":59,"children":62},"span",{"class":60,"line":61},"line",1,[63,69,75],{"type":20,"tag":58,"props":64,"children":66},{"style":65},"--shiki-default:#6F42C1",[67],{"type":25,"value":68},"$",{"type":20,"tag":58,"props":70,"children":72},{"style":71},"--shiki-default:#032F62",[73],{"type":25,"value":74}," pacman",{"type":20,"tag":58,"props":76,"children":78},{"style":77},"--shiki-default:#005CC5",[79],{"type":25,"value":80}," -Syu\n",{"type":20,"tag":58,"props":82,"children":84},{"class":60,"line":83},2,[85,90,95,100,105,110,115,120,124,129],{"type":20,"tag":58,"props":86,"children":87},{"style":65},[88],{"type":25,"value":89},"error:",{"type":20,"tag":58,"props":91,"children":92},{"style":71},[93],{"type":25,"value":94}," you",{"type":20,"tag":58,"props":96,"children":97},{"style":71},[98],{"type":25,"value":99}," cannot",{"type":20,"tag":58,"props":101,"children":102},{"style":71},[103],{"type":25,"value":104}," perform",{"type":20,"tag":58,"props":106,"children":107},{"style":71},[108],{"type":25,"value":109}," this",{"type":20,"tag":58,"props":111,"children":112},{"style":71},[113],{"type":25,"value":114}," operation",{"type":20,"tag":58,"props":116,"children":117},{"style":71},[118],{"type":25,"value":119}," unless",{"type":20,"tag":58,"props":121,"children":122},{"style":71},[123],{"type":25,"value":94},{"type":20,"tag":58,"props":125,"children":126},{"style":71},[127],{"type":25,"value":128}," are",{"type":20,"tag":58,"props":130,"children":131},{"style":71},[132],{"type":25,"value":133}," root.\n",{"type":20,"tag":21,"props":135,"children":136},{},[137,139,145,147,152,154,159],{"type":25,"value":138},"Well, I have good news for you -- you can easily re-issue a command with the\n",{"type":20,"tag":28,"props":140,"children":142},{"className":141},[],[143],{"type":25,"value":144},"!!",{"type":25,"value":146}," designator! Simply type ",{"type":20,"tag":28,"props":148,"children":150},{"className":149},[],[151],{"type":25,"value":33},{"type":25,"value":153}," followed by ",{"type":20,"tag":28,"props":155,"children":157},{"className":156},[],[158],{"type":25,"value":144},{"type":25,"value":160}," and you're good to go.",{"type":20,"tag":49,"props":162,"children":164},{"className":51,"code":163,"language":13,"meta":7,"style":7},"$ sudo !!\nsudo pacman -Syu\n[sudo] password for colton:\n:: Synchronizing package databases...\n",[165],{"type":20,"tag":28,"props":166,"children":167},{"__ignoreMap":7},[168,185,200,221],{"type":20,"tag":58,"props":169,"children":170},{"class":60,"line":61},[171,175,180],{"type":20,"tag":58,"props":172,"children":173},{"style":65},[174],{"type":25,"value":68},{"type":20,"tag":58,"props":176,"children":177},{"style":71},[178],{"type":25,"value":179}," sudo",{"type":20,"tag":58,"props":181,"children":182},{"style":71},[183],{"type":25,"value":184}," !!\n",{"type":20,"tag":58,"props":186,"children":187},{"class":60,"line":83},[188,192,196],{"type":20,"tag":58,"props":189,"children":190},{"style":65},[191],{"type":25,"value":33},{"type":20,"tag":58,"props":193,"children":194},{"style":71},[195],{"type":25,"value":74},{"type":20,"tag":58,"props":197,"children":198},{"style":77},[199],{"type":25,"value":80},{"type":20,"tag":58,"props":201,"children":203},{"class":60,"line":202},3,[204,210,216],{"type":20,"tag":58,"props":205,"children":207},{"style":206},"--shiki-default:#24292E",[208],{"type":25,"value":209},"[sudo] password ",{"type":20,"tag":58,"props":211,"children":213},{"style":212},"--shiki-default:#D73A49",[214],{"type":25,"value":215},"for",{"type":20,"tag":58,"props":217,"children":218},{"style":206},[219],{"type":25,"value":220}," colton:\n",{"type":20,"tag":58,"props":222,"children":224},{"class":60,"line":223},4,[225,230,235,240],{"type":20,"tag":58,"props":226,"children":227},{"style":77},[228],{"type":25,"value":229},"::",{"type":20,"tag":58,"props":231,"children":232},{"style":71},[233],{"type":25,"value":234}," Synchronizing",{"type":20,"tag":58,"props":236,"children":237},{"style":71},[238],{"type":25,"value":239}," package",{"type":20,"tag":58,"props":241,"children":242},{"style":71},[243],{"type":25,"value":244}," databases...\n",{"type":20,"tag":21,"props":246,"children":247},{},[248],{"type":25,"value":249},"--",{"type":20,"tag":21,"props":251,"children":252},{},[253,255,261,263,269,271,277],{"type":25,"value":254},"Commands that are prefixed with a bang, ",{"type":20,"tag":28,"props":256,"children":258},{"className":257},[],[259],{"type":25,"value":260},"!",{"type":25,"value":262},", are considered ",{"type":20,"tag":264,"props":265,"children":266},"em",{},[267],{"type":25,"value":268},"Event\nDesignators,",{"type":25,"value":270}," and are references to your command-line history. You can take a\nlook at your history with the ",{"type":20,"tag":28,"props":272,"children":274},{"className":273},[],[275],{"type":25,"value":276},"history",{"type":25,"value":278}," command.",{"type":20,"tag":49,"props":280,"children":282},{"className":51,"code":281,"language":13,"meta":7,"style":7},"$ history\n 1021 touch hello_world.txt\n 1022 ls\n 1023 echo \"Here we go again!\"\n 1024 find . -name *.py\n",[283],{"type":20,"tag":28,"props":284,"children":285},{"__ignoreMap":7},[286,298,316,329,347],{"type":20,"tag":58,"props":287,"children":288},{"class":60,"line":61},[289,293],{"type":20,"tag":58,"props":290,"children":291},{"style":65},[292],{"type":25,"value":68},{"type":20,"tag":58,"props":294,"children":295},{"style":71},[296],{"type":25,"value":297}," history\n",{"type":20,"tag":58,"props":299,"children":300},{"class":60,"line":83},[301,306,311],{"type":20,"tag":58,"props":302,"children":303},{"style":65},[304],{"type":25,"value":305}," 1021",{"type":20,"tag":58,"props":307,"children":308},{"style":71},[309],{"type":25,"value":310}," touch",{"type":20,"tag":58,"props":312,"children":313},{"style":71},[314],{"type":25,"value":315}," hello_world.txt\n",{"type":20,"tag":58,"props":317,"children":318},{"class":60,"line":202},[319,324],{"type":20,"tag":58,"props":320,"children":321},{"style":65},[322],{"type":25,"value":323}," 1022",{"type":20,"tag":58,"props":325,"children":326},{"style":71},[327],{"type":25,"value":328}," ls\n",{"type":20,"tag":58,"props":330,"children":331},{"class":60,"line":223},[332,337,342],{"type":20,"tag":58,"props":333,"children":334},{"style":65},[335],{"type":25,"value":336}," 1023",{"type":20,"tag":58,"props":338,"children":339},{"style":71},[340],{"type":25,"value":341}," echo",{"type":20,"tag":58,"props":343,"children":344},{"style":71},[345],{"type":25,"value":346}," \"Here we go again!\"\n",{"type":20,"tag":58,"props":348,"children":350},{"class":60,"line":349},5,[351,356,361,366,371,376],{"type":20,"tag":58,"props":352,"children":353},{"style":65},[354],{"type":25,"value":355}," 1024",{"type":20,"tag":58,"props":357,"children":358},{"style":71},[359],{"type":25,"value":360}," find",{"type":20,"tag":58,"props":362,"children":363},{"style":71},[364],{"type":25,"value":365}," .",{"type":20,"tag":58,"props":367,"children":368},{"style":77},[369],{"type":25,"value":370}," -name",{"type":20,"tag":58,"props":372,"children":373},{"style":77},[374],{"type":25,"value":375}," *",{"type":20,"tag":58,"props":377,"children":378},{"style":71},[379],{"type":25,"value":380},".py\n",{"type":20,"tag":21,"props":382,"children":383},{},[384,386,391,393,399,401,407],{"type":25,"value":385},"There are many ways to use ",{"type":20,"tag":28,"props":387,"children":389},{"className":388},[],[390],{"type":25,"value":260},{"type":25,"value":392}," in your shell. For example, if you wanted to\nre-issue a specific command in your history, you could use ",{"type":20,"tag":28,"props":394,"children":396},{"className":395},[],[397],{"type":25,"value":398},"!n",{"type":25,"value":400}," where ",{"type":20,"tag":28,"props":402,"children":404},{"className":403},[],[405],{"type":25,"value":406},"n",{"type":25,"value":408}," is\nthe number next to the command in your history.",{"type":20,"tag":49,"props":410,"children":412},{"className":51,"code":411,"language":13,"meta":7,"style":7},"$ !1023\necho \"Here we go again!\"\nHere we go again!\n",[413],{"type":20,"tag":28,"props":414,"children":415},{"__ignoreMap":7},[416,428,440],{"type":20,"tag":58,"props":417,"children":418},{"class":60,"line":61},[419,423],{"type":20,"tag":58,"props":420,"children":421},{"style":65},[422],{"type":25,"value":68},{"type":20,"tag":58,"props":424,"children":425},{"style":71},[426],{"type":25,"value":427}," !1023\n",{"type":20,"tag":58,"props":429,"children":430},{"class":60,"line":83},[431,436],{"type":20,"tag":58,"props":432,"children":433},{"style":77},[434],{"type":25,"value":435},"echo",{"type":20,"tag":58,"props":437,"children":438},{"style":71},[439],{"type":25,"value":346},{"type":20,"tag":58,"props":441,"children":442},{"class":60,"line":202},[443,448,453,458],{"type":20,"tag":58,"props":444,"children":445},{"style":65},[446],{"type":25,"value":447},"Here",{"type":20,"tag":58,"props":449,"children":450},{"style":71},[451],{"type":25,"value":452}," we",{"type":20,"tag":58,"props":454,"children":455},{"style":71},[456],{"type":25,"value":457}," go",{"type":20,"tag":58,"props":459,"children":460},{"style":71},[461],{"type":25,"value":462}," again!\n",{"type":20,"tag":21,"props":464,"children":465},{},[466,468,474],{"type":25,"value":467},"Or... if you wanted to run the command you issued 4-commands ago, you can use\n",{"type":20,"tag":28,"props":469,"children":471},{"className":470},[],[472],{"type":25,"value":473},"!-4",{"type":25,"value":475},".",{"type":20,"tag":49,"props":477,"children":479},{"className":51,"code":478,"language":13,"meta":7,"style":7},"$ !-4\nls\nhello_world.txt\n",[480],{"type":20,"tag":28,"props":481,"children":482},{"__ignoreMap":7},[483,495,503],{"type":20,"tag":58,"props":484,"children":485},{"class":60,"line":61},[486,490],{"type":20,"tag":58,"props":487,"children":488},{"style":65},[489],{"type":25,"value":68},{"type":20,"tag":58,"props":491,"children":492},{"style":71},[493],{"type":25,"value":494}," !-4\n",{"type":20,"tag":58,"props":496,"children":497},{"class":60,"line":83},[498],{"type":20,"tag":58,"props":499,"children":500},{"style":65},[501],{"type":25,"value":502},"ls\n",{"type":20,"tag":58,"props":504,"children":505},{"class":60,"line":202},[506],{"type":20,"tag":58,"props":507,"children":508},{"style":65},[509],{"type":25,"value":510},"hello_world.txt\n",{"type":20,"tag":21,"props":512,"children":513},{},[514,516,521,523,529],{"type":25,"value":515},"Or... if you wanted to run the last command that started with the string\n",{"type":20,"tag":264,"props":517,"children":518},{},[519],{"type":25,"value":520},"find",{"type":25,"value":522},", you can use ",{"type":20,"tag":28,"props":524,"children":526},{"className":525},[],[527],{"type":25,"value":528},"!find",{"type":25,"value":475},{"type":20,"tag":49,"props":531,"children":533},{"className":51,"code":532,"language":13,"meta":7,"style":7},"$ !find\nfind . -name *.py\n",[534],{"type":20,"tag":28,"props":535,"children":536},{"__ignoreMap":7},[537,549],{"type":20,"tag":58,"props":538,"children":539},{"class":60,"line":61},[540,544],{"type":20,"tag":58,"props":541,"children":542},{"style":65},[543],{"type":25,"value":68},{"type":20,"tag":58,"props":545,"children":546},{"style":71},[547],{"type":25,"value":548}," !find\n",{"type":20,"tag":58,"props":550,"children":551},{"class":60,"line":83},[552,556,560,564,568],{"type":20,"tag":58,"props":553,"children":554},{"style":65},[555],{"type":25,"value":520},{"type":20,"tag":58,"props":557,"children":558},{"style":71},[559],{"type":25,"value":365},{"type":20,"tag":58,"props":561,"children":562},{"style":77},[563],{"type":25,"value":370},{"type":20,"tag":58,"props":565,"children":566},{"style":77},[567],{"type":25,"value":375},{"type":20,"tag":58,"props":569,"children":570},{"style":71},[571],{"type":25,"value":380},{"type":20,"tag":21,"props":573,"children":574},{},[575,577,582,584,589,591,597],{"type":25,"value":576},"Be sure to check out the ",{"type":20,"tag":264,"props":578,"children":579},{},[580],{"type":25,"value":581},"Event Designators",{"type":25,"value":583}," section of the ",{"type":20,"tag":28,"props":585,"children":587},{"className":586},[],[588],{"type":25,"value":13},{"type":25,"value":590}," ",{"type":20,"tag":28,"props":592,"children":594},{"className":593},[],[595],{"type":25,"value":596},"man",{"type":25,"value":598}," pages\nfor more information!",{"type":20,"tag":21,"props":600,"children":601},{},[602],{"type":25,"value":249},{"type":20,"tag":21,"props":604,"children":605},{},[606,608,617,619,624,626,631],{"type":25,"value":607},"As an aside, for even faster command-line history navigation, be sure to check\nout the excellent ",{"type":20,"tag":609,"props":610,"children":614},"a",{"href":611,"rel":612},"https://github.com/junegunn/fzf",[613],"nofollow",[615],{"type":25,"value":616},"fzf",{"type":25,"value":618}," utility by ",{"type":20,"tag":264,"props":620,"children":621},{},[622],{"type":25,"value":623},"junegunn.",{"type":25,"value":625},"\nOne of the many features of ",{"type":20,"tag":28,"props":627,"children":629},{"className":628},[],[630],{"type":25,"value":616},{"type":25,"value":632}," is browsing and re-issuing commands from your\ncommand-line history with a fuzzy-finder!",{"type":20,"tag":634,"props":635,"children":636},"style",{},[637],{"type":25,"value":638},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":83,"depth":83,"links":640},[],"markdown","content:articles:quick-tip-rerunning-bash-commands.md","content","articles/quick-tip-rerunning-bash-commands.md","md",1718891181767] \ No newline at end of file +[{"data":1,"prerenderedAt":647},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":14,"excerpt":16,"body":36,"_type":641,"_id":642,"_source":643,"_file":644,"_stem":645,"_extension":646},"/articles/quick-tip-rerunning-bash-commands","articles",false,"","Tip: Re-running Bash Commands","Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use sudo for a command that requires\nroot privileges.","2021-09-22",[12,13],"tip","bash",[15],"tips",{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,27,34],{"type":25,"value":26},"text","Do you ever find yourself having to re-run a Bash command? I often find this\nhappening to myself when I neglect to use ",{"type":20,"tag":28,"props":29,"children":31},"code",{"className":30},[],[32],{"type":25,"value":33},"sudo",{"type":25,"value":35}," for a command that requires\nroot privileges.",{"type":17,"children":37,"toc":639},[38,48,134,161,245,250,279,381,409,463,476,511,530,572,599,603,633],{"type":20,"tag":21,"props":39,"children":40},{},[41,42,47],{"type":25,"value":26},{"type":20,"tag":28,"props":43,"children":45},{"className":44},[],[46],{"type":25,"value":33},{"type":25,"value":35},{"type":20,"tag":49,"props":50,"children":53},"pre",{"className":51,"code":52,"language":13,"meta":7,"style":7},"language-bash shiki shiki-themes github-light","$ pacman -Syu\nerror: you cannot perform this operation unless you are root.\n",[54],{"type":20,"tag":28,"props":55,"children":56},{"__ignoreMap":7},[57,81],{"type":20,"tag":58,"props":59,"children":62},"span",{"class":60,"line":61},"line",1,[63,69,75],{"type":20,"tag":58,"props":64,"children":66},{"style":65},"--shiki-default:#6F42C1",[67],{"type":25,"value":68},"$",{"type":20,"tag":58,"props":70,"children":72},{"style":71},"--shiki-default:#032F62",[73],{"type":25,"value":74}," pacman",{"type":20,"tag":58,"props":76,"children":78},{"style":77},"--shiki-default:#005CC5",[79],{"type":25,"value":80}," -Syu\n",{"type":20,"tag":58,"props":82,"children":84},{"class":60,"line":83},2,[85,90,95,100,105,110,115,120,124,129],{"type":20,"tag":58,"props":86,"children":87},{"style":65},[88],{"type":25,"value":89},"error:",{"type":20,"tag":58,"props":91,"children":92},{"style":71},[93],{"type":25,"value":94}," you",{"type":20,"tag":58,"props":96,"children":97},{"style":71},[98],{"type":25,"value":99}," cannot",{"type":20,"tag":58,"props":101,"children":102},{"style":71},[103],{"type":25,"value":104}," perform",{"type":20,"tag":58,"props":106,"children":107},{"style":71},[108],{"type":25,"value":109}," this",{"type":20,"tag":58,"props":111,"children":112},{"style":71},[113],{"type":25,"value":114}," operation",{"type":20,"tag":58,"props":116,"children":117},{"style":71},[118],{"type":25,"value":119}," unless",{"type":20,"tag":58,"props":121,"children":122},{"style":71},[123],{"type":25,"value":94},{"type":20,"tag":58,"props":125,"children":126},{"style":71},[127],{"type":25,"value":128}," are",{"type":20,"tag":58,"props":130,"children":131},{"style":71},[132],{"type":25,"value":133}," root.\n",{"type":20,"tag":21,"props":135,"children":136},{},[137,139,145,147,152,154,159],{"type":25,"value":138},"Well, I have good news for you -- you can easily re-issue a command with the\n",{"type":20,"tag":28,"props":140,"children":142},{"className":141},[],[143],{"type":25,"value":144},"!!",{"type":25,"value":146}," designator! Simply type ",{"type":20,"tag":28,"props":148,"children":150},{"className":149},[],[151],{"type":25,"value":33},{"type":25,"value":153}," followed by ",{"type":20,"tag":28,"props":155,"children":157},{"className":156},[],[158],{"type":25,"value":144},{"type":25,"value":160}," and you're good to go.",{"type":20,"tag":49,"props":162,"children":164},{"className":51,"code":163,"language":13,"meta":7,"style":7},"$ sudo !!\nsudo pacman -Syu\n[sudo] password for colton:\n:: Synchronizing package databases...\n",[165],{"type":20,"tag":28,"props":166,"children":167},{"__ignoreMap":7},[168,185,200,221],{"type":20,"tag":58,"props":169,"children":170},{"class":60,"line":61},[171,175,180],{"type":20,"tag":58,"props":172,"children":173},{"style":65},[174],{"type":25,"value":68},{"type":20,"tag":58,"props":176,"children":177},{"style":71},[178],{"type":25,"value":179}," sudo",{"type":20,"tag":58,"props":181,"children":182},{"style":71},[183],{"type":25,"value":184}," !!\n",{"type":20,"tag":58,"props":186,"children":187},{"class":60,"line":83},[188,192,196],{"type":20,"tag":58,"props":189,"children":190},{"style":65},[191],{"type":25,"value":33},{"type":20,"tag":58,"props":193,"children":194},{"style":71},[195],{"type":25,"value":74},{"type":20,"tag":58,"props":197,"children":198},{"style":77},[199],{"type":25,"value":80},{"type":20,"tag":58,"props":201,"children":203},{"class":60,"line":202},3,[204,210,216],{"type":20,"tag":58,"props":205,"children":207},{"style":206},"--shiki-default:#24292E",[208],{"type":25,"value":209},"[sudo] password ",{"type":20,"tag":58,"props":211,"children":213},{"style":212},"--shiki-default:#D73A49",[214],{"type":25,"value":215},"for",{"type":20,"tag":58,"props":217,"children":218},{"style":206},[219],{"type":25,"value":220}," colton:\n",{"type":20,"tag":58,"props":222,"children":224},{"class":60,"line":223},4,[225,230,235,240],{"type":20,"tag":58,"props":226,"children":227},{"style":77},[228],{"type":25,"value":229},"::",{"type":20,"tag":58,"props":231,"children":232},{"style":71},[233],{"type":25,"value":234}," Synchronizing",{"type":20,"tag":58,"props":236,"children":237},{"style":71},[238],{"type":25,"value":239}," package",{"type":20,"tag":58,"props":241,"children":242},{"style":71},[243],{"type":25,"value":244}," databases...\n",{"type":20,"tag":21,"props":246,"children":247},{},[248],{"type":25,"value":249},"--",{"type":20,"tag":21,"props":251,"children":252},{},[253,255,261,263,269,271,277],{"type":25,"value":254},"Commands that are prefixed with a bang, ",{"type":20,"tag":28,"props":256,"children":258},{"className":257},[],[259],{"type":25,"value":260},"!",{"type":25,"value":262},", are considered ",{"type":20,"tag":264,"props":265,"children":266},"em",{},[267],{"type":25,"value":268},"Event\nDesignators,",{"type":25,"value":270}," and are references to your command-line history. You can take a\nlook at your history with the ",{"type":20,"tag":28,"props":272,"children":274},{"className":273},[],[275],{"type":25,"value":276},"history",{"type":25,"value":278}," command.",{"type":20,"tag":49,"props":280,"children":282},{"className":51,"code":281,"language":13,"meta":7,"style":7},"$ history\n 1021 touch hello_world.txt\n 1022 ls\n 1023 echo \"Here we go again!\"\n 1024 find . -name *.py\n",[283],{"type":20,"tag":28,"props":284,"children":285},{"__ignoreMap":7},[286,298,316,329,347],{"type":20,"tag":58,"props":287,"children":288},{"class":60,"line":61},[289,293],{"type":20,"tag":58,"props":290,"children":291},{"style":65},[292],{"type":25,"value":68},{"type":20,"tag":58,"props":294,"children":295},{"style":71},[296],{"type":25,"value":297}," history\n",{"type":20,"tag":58,"props":299,"children":300},{"class":60,"line":83},[301,306,311],{"type":20,"tag":58,"props":302,"children":303},{"style":65},[304],{"type":25,"value":305}," 1021",{"type":20,"tag":58,"props":307,"children":308},{"style":71},[309],{"type":25,"value":310}," touch",{"type":20,"tag":58,"props":312,"children":313},{"style":71},[314],{"type":25,"value":315}," hello_world.txt\n",{"type":20,"tag":58,"props":317,"children":318},{"class":60,"line":202},[319,324],{"type":20,"tag":58,"props":320,"children":321},{"style":65},[322],{"type":25,"value":323}," 1022",{"type":20,"tag":58,"props":325,"children":326},{"style":71},[327],{"type":25,"value":328}," ls\n",{"type":20,"tag":58,"props":330,"children":331},{"class":60,"line":223},[332,337,342],{"type":20,"tag":58,"props":333,"children":334},{"style":65},[335],{"type":25,"value":336}," 1023",{"type":20,"tag":58,"props":338,"children":339},{"style":71},[340],{"type":25,"value":341}," echo",{"type":20,"tag":58,"props":343,"children":344},{"style":71},[345],{"type":25,"value":346}," \"Here we go again!\"\n",{"type":20,"tag":58,"props":348,"children":350},{"class":60,"line":349},5,[351,356,361,366,371,376],{"type":20,"tag":58,"props":352,"children":353},{"style":65},[354],{"type":25,"value":355}," 1024",{"type":20,"tag":58,"props":357,"children":358},{"style":71},[359],{"type":25,"value":360}," find",{"type":20,"tag":58,"props":362,"children":363},{"style":71},[364],{"type":25,"value":365}," .",{"type":20,"tag":58,"props":367,"children":368},{"style":77},[369],{"type":25,"value":370}," -name",{"type":20,"tag":58,"props":372,"children":373},{"style":77},[374],{"type":25,"value":375}," *",{"type":20,"tag":58,"props":377,"children":378},{"style":71},[379],{"type":25,"value":380},".py\n",{"type":20,"tag":21,"props":382,"children":383},{},[384,386,391,393,399,401,407],{"type":25,"value":385},"There are many ways to use ",{"type":20,"tag":28,"props":387,"children":389},{"className":388},[],[390],{"type":25,"value":260},{"type":25,"value":392}," in your shell. For example, if you wanted to\nre-issue a specific command in your history, you could use ",{"type":20,"tag":28,"props":394,"children":396},{"className":395},[],[397],{"type":25,"value":398},"!n",{"type":25,"value":400}," where ",{"type":20,"tag":28,"props":402,"children":404},{"className":403},[],[405],{"type":25,"value":406},"n",{"type":25,"value":408}," is\nthe number next to the command in your history.",{"type":20,"tag":49,"props":410,"children":412},{"className":51,"code":411,"language":13,"meta":7,"style":7},"$ !1023\necho \"Here we go again!\"\nHere we go again!\n",[413],{"type":20,"tag":28,"props":414,"children":415},{"__ignoreMap":7},[416,428,440],{"type":20,"tag":58,"props":417,"children":418},{"class":60,"line":61},[419,423],{"type":20,"tag":58,"props":420,"children":421},{"style":65},[422],{"type":25,"value":68},{"type":20,"tag":58,"props":424,"children":425},{"style":71},[426],{"type":25,"value":427}," !1023\n",{"type":20,"tag":58,"props":429,"children":430},{"class":60,"line":83},[431,436],{"type":20,"tag":58,"props":432,"children":433},{"style":77},[434],{"type":25,"value":435},"echo",{"type":20,"tag":58,"props":437,"children":438},{"style":71},[439],{"type":25,"value":346},{"type":20,"tag":58,"props":441,"children":442},{"class":60,"line":202},[443,448,453,458],{"type":20,"tag":58,"props":444,"children":445},{"style":65},[446],{"type":25,"value":447},"Here",{"type":20,"tag":58,"props":449,"children":450},{"style":71},[451],{"type":25,"value":452}," we",{"type":20,"tag":58,"props":454,"children":455},{"style":71},[456],{"type":25,"value":457}," go",{"type":20,"tag":58,"props":459,"children":460},{"style":71},[461],{"type":25,"value":462}," again!\n",{"type":20,"tag":21,"props":464,"children":465},{},[466,468,474],{"type":25,"value":467},"Or... if you wanted to run the command you issued 4-commands ago, you can use\n",{"type":20,"tag":28,"props":469,"children":471},{"className":470},[],[472],{"type":25,"value":473},"!-4",{"type":25,"value":475},".",{"type":20,"tag":49,"props":477,"children":479},{"className":51,"code":478,"language":13,"meta":7,"style":7},"$ !-4\nls\nhello_world.txt\n",[480],{"type":20,"tag":28,"props":481,"children":482},{"__ignoreMap":7},[483,495,503],{"type":20,"tag":58,"props":484,"children":485},{"class":60,"line":61},[486,490],{"type":20,"tag":58,"props":487,"children":488},{"style":65},[489],{"type":25,"value":68},{"type":20,"tag":58,"props":491,"children":492},{"style":71},[493],{"type":25,"value":494}," !-4\n",{"type":20,"tag":58,"props":496,"children":497},{"class":60,"line":83},[498],{"type":20,"tag":58,"props":499,"children":500},{"style":65},[501],{"type":25,"value":502},"ls\n",{"type":20,"tag":58,"props":504,"children":505},{"class":60,"line":202},[506],{"type":20,"tag":58,"props":507,"children":508},{"style":65},[509],{"type":25,"value":510},"hello_world.txt\n",{"type":20,"tag":21,"props":512,"children":513},{},[514,516,521,523,529],{"type":25,"value":515},"Or... if you wanted to run the last command that started with the string\n",{"type":20,"tag":264,"props":517,"children":518},{},[519],{"type":25,"value":520},"find",{"type":25,"value":522},", you can use ",{"type":20,"tag":28,"props":524,"children":526},{"className":525},[],[527],{"type":25,"value":528},"!find",{"type":25,"value":475},{"type":20,"tag":49,"props":531,"children":533},{"className":51,"code":532,"language":13,"meta":7,"style":7},"$ !find\nfind . -name *.py\n",[534],{"type":20,"tag":28,"props":535,"children":536},{"__ignoreMap":7},[537,549],{"type":20,"tag":58,"props":538,"children":539},{"class":60,"line":61},[540,544],{"type":20,"tag":58,"props":541,"children":542},{"style":65},[543],{"type":25,"value":68},{"type":20,"tag":58,"props":545,"children":546},{"style":71},[547],{"type":25,"value":548}," !find\n",{"type":20,"tag":58,"props":550,"children":551},{"class":60,"line":83},[552,556,560,564,568],{"type":20,"tag":58,"props":553,"children":554},{"style":65},[555],{"type":25,"value":520},{"type":20,"tag":58,"props":557,"children":558},{"style":71},[559],{"type":25,"value":365},{"type":20,"tag":58,"props":561,"children":562},{"style":77},[563],{"type":25,"value":370},{"type":20,"tag":58,"props":565,"children":566},{"style":77},[567],{"type":25,"value":375},{"type":20,"tag":58,"props":569,"children":570},{"style":71},[571],{"type":25,"value":380},{"type":20,"tag":21,"props":573,"children":574},{},[575,577,582,584,589,591,597],{"type":25,"value":576},"Be sure to check out the ",{"type":20,"tag":264,"props":578,"children":579},{},[580],{"type":25,"value":581},"Event Designators",{"type":25,"value":583}," section of the ",{"type":20,"tag":28,"props":585,"children":587},{"className":586},[],[588],{"type":25,"value":13},{"type":25,"value":590}," ",{"type":20,"tag":28,"props":592,"children":594},{"className":593},[],[595],{"type":25,"value":596},"man",{"type":25,"value":598}," pages\nfor more information!",{"type":20,"tag":21,"props":600,"children":601},{},[602],{"type":25,"value":249},{"type":20,"tag":21,"props":604,"children":605},{},[606,608,617,619,624,626,631],{"type":25,"value":607},"As an aside, for even faster command-line history navigation, be sure to check\nout the excellent ",{"type":20,"tag":609,"props":610,"children":614},"a",{"href":611,"rel":612},"https://github.com/junegunn/fzf",[613],"nofollow",[615],{"type":25,"value":616},"fzf",{"type":25,"value":618}," utility by ",{"type":20,"tag":264,"props":620,"children":621},{},[622],{"type":25,"value":623},"junegunn.",{"type":25,"value":625},"\nOne of the many features of ",{"type":20,"tag":28,"props":627,"children":629},{"className":628},[],[630],{"type":25,"value":616},{"type":25,"value":632}," is browsing and re-issuing commands from your\ncommand-line history with a fuzzy-finder!",{"type":20,"tag":634,"props":635,"children":636},"style",{},[637],{"type":25,"value":638},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":83,"depth":83,"links":640},[],"markdown","content:articles:quick-tip-rerunning-bash-commands.md","content","articles/quick-tip-rerunning-bash-commands.md","articles/quick-tip-rerunning-bash-commands","md",1720229315498] \ No newline at end of file diff --git a/articles/quick-tip-rerunning-bash-commands/index.html b/articles/quick-tip-rerunning-bash-commands/index.html index 5a50dde1..35131b0b 100644 --- a/articles/quick-tip-rerunning-bash-commands/index.html +++ b/articles/quick-tip-rerunning-bash-commands/index.html @@ -4,32 +4,33 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - -

            Tip: Re-running Bash Commands

            2021-09-22

            Do you ever find yourself having to re-run a Bash command? I often find this + + + + + + + + + + + + + +

            Tip: Re-running Bash Commands

            Do you ever find yourself having to re-run a Bash command? I often find this happening to myself when I neglect to use sudo for a command that requires root privileges.

            $ pacman -Syu
             error: you cannot perform this operation unless you are root.
            @@ -61,5 +62,5 @@
             for more information!

            --

            As an aside, for even faster command-line history navigation, be sure to check out the excellent fzf utility by junegunn. One of the many features of fzf is browsing and re-issuing commands from your -command-line history with a fuzzy-finder!

            - \ No newline at end of file +command-line history with a fuzzy-finder!

            + \ No newline at end of file diff --git a/articles/reset-ipmi-password-from-host-os/_payload.json b/articles/reset-ipmi-password-from-host-os/_payload.json index 9bbb1b9e..dc5b3616 100644 --- a/articles/reset-ipmi-password-from-host-os/_payload.json +++ b/articles/reset-ipmi-password-from-host-os/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":202},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":15,"excerpt":16,"body":26,"_type":197,"_id":198,"_source":199,"_file":200,"_extension":201},"/articles/reset-ipmi-password-from-host-os","articles",false,"","Reset IPMI Credentials from the Host OS","If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","2021-12-27",[12,13,14],"homelab","supermicro","truenas",[12],{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":194},[28,32,54,67,72,81,100,108,113,118,123,131],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":21,"props":33,"children":34},{},[35,37,44,46,52],{"type":25,"value":36},"If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from\nthe web interface. This is done by navigating to ",{"type":20,"tag":38,"props":39,"children":41},"code",{"className":40},[],[42],{"type":25,"value":43},"Network > IPMI",{"type":25,"value":45},", and simply entering a new value in the ",{"type":20,"tag":47,"props":48,"children":49},"em",{},[50],{"type":25,"value":51},"IPMI\nPassword Reset",{"type":25,"value":53}," field.",{"type":20,"tag":21,"props":55,"children":56},{},[57,59,65],{"type":25,"value":58},"If you are using some other OS that doesn't have this feature, you can achieve similar results by using the ",{"type":20,"tag":38,"props":60,"children":62},{"className":61},[],[63],{"type":25,"value":64},"ipmitool",{"type":25,"value":66},"\ncommand-line utility.",{"type":20,"tag":21,"props":68,"children":69},{},[70],{"type":25,"value":71},"First, you'll want to determine the user ID associated with the user for whom you'd like to reset the password.",{"type":20,"tag":73,"props":74,"children":76},"pre",{"code":75},"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n",[77],{"type":20,"tag":38,"props":78,"children":79},{"__ignoreMap":7},[80],{"type":25,"value":75},{"type":20,"tag":21,"props":82,"children":83},{},[84,86,91,93,98],{"type":25,"value":85},"In this case, we will be resetting the password for ",{"type":20,"tag":47,"props":87,"children":88},{},[89],{"type":25,"value":90},"ADMIN",{"type":25,"value":92}," who has a user ID of ",{"type":20,"tag":47,"props":94,"children":95},{},[96],{"type":25,"value":97},"2",{"type":25,"value":99},". Then we'll assign the new\npassword like so:",{"type":20,"tag":73,"props":101,"children":103},{"code":102},"# ipmitool user set password 2 \u003Cpassword>\n",[104],{"type":20,"tag":38,"props":105,"children":106},{"__ignoreMap":7},[107],{"type":25,"value":102},{"type":20,"tag":21,"props":109,"children":110},{},[111],{"type":25,"value":112},"And you should be good to go!",{"type":20,"tag":21,"props":114,"children":115},{},[116],{"type":25,"value":117},"...",{"type":20,"tag":21,"props":119,"children":120},{},[121],{"type":25,"value":122},"Alternatively, if you'd like to factory reset the baseboard management controller (BMC), which will reset the IPMI\ncredentials to their default value, you can issue the following command.",{"type":20,"tag":73,"props":124,"children":126},{"code":125},"# ipmitool raw 0x3c 0x40\n",[127],{"type":20,"tag":38,"props":128,"children":129},{"__ignoreMap":7},[130],{"type":25,"value":125},{"type":20,"tag":21,"props":132,"children":133},{},[134,136,142,144,150,152,158,159,165,167,176,178,183,185,192],{"type":25,"value":135},"Where ",{"type":20,"tag":38,"props":137,"children":139},{"className":138},[],[140],{"type":25,"value":141},"0x3c",{"type":25,"value":143}," is the ",{"type":20,"tag":38,"props":145,"children":147},{"className":146},[],[148],{"type":25,"value":149},"\u003Cnetfn>",{"type":25,"value":151}," argument, a.k.a. the network function code that defines the functional routing for\nmessages, and ",{"type":20,"tag":38,"props":153,"children":155},{"className":154},[],[156],{"type":25,"value":157},"0x40",{"type":25,"value":143},{"type":20,"tag":38,"props":160,"children":162},{"className":161},[],[163],{"type":25,"value":164},"\u003Ccmd>",{"type":25,"value":166},". According to section 5.1 of the ",{"type":20,"tag":168,"props":169,"children":173},"a",{"href":170,"rel":171},"https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf",[172],"nofollow",[174],{"type":25,"value":175},"IPMI interface\nspecification",{"type":25,"value":177},",\n",{"type":20,"tag":47,"props":179,"children":180},{},[181],{"type":25,"value":182},"netfn",{"type":25,"value":184}," codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some\nSupermicro references on these vendor specific network functions without much luck other than various ",{"type":20,"tag":168,"props":186,"children":189},{"href":187,"rel":188},"https://www.supermicro.com/support/faqs/faq.cfm?faq=15448",[172],[190],{"type":25,"value":191},"support\nresponses",{"type":25,"value":193}," on how to reset a device. Bummer!",{"title":7,"searchDepth":195,"depth":195,"links":196},2,[],"markdown","content:articles:reset-ipmi-password-from-host-os.md","content","articles/reset-ipmi-password-from-host-os.md","md",1718891181764] \ No newline at end of file +[{"data":1,"prerenderedAt":203},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"categories":15,"excerpt":16,"body":26,"_type":197,"_id":198,"_source":199,"_file":200,"_stem":201,"_extension":202},"/articles/reset-ipmi-password-from-host-os","articles",false,"","Reset IPMI Credentials from the Host OS","If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these\ninstructions will guide your through the process of resetting the credentials to their default values from the host\noperating system.","2021-12-27",[12,13,14],"homelab","supermicro","truenas",[12],{"type":17,"children":18},"root",[19],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24],{"type":25,"value":9},"text",{"type":17,"children":27,"toc":194},[28,32,54,67,72,81,100,108,113,118,123,131],{"type":20,"tag":21,"props":29,"children":30},{},[31],{"type":25,"value":9},{"type":20,"tag":21,"props":33,"children":34},{},[35,37,44,46,52],{"type":25,"value":36},"If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from\nthe web interface. This is done by navigating to ",{"type":20,"tag":38,"props":39,"children":41},"code",{"className":40},[],[42],{"type":25,"value":43},"Network > IPMI",{"type":25,"value":45},", and simply entering a new value in the ",{"type":20,"tag":47,"props":48,"children":49},"em",{},[50],{"type":25,"value":51},"IPMI\nPassword Reset",{"type":25,"value":53}," field.",{"type":20,"tag":21,"props":55,"children":56},{},[57,59,65],{"type":25,"value":58},"If you are using some other OS that doesn't have this feature, you can achieve similar results by using the ",{"type":20,"tag":38,"props":60,"children":62},{"className":61},[],[63],{"type":25,"value":64},"ipmitool",{"type":25,"value":66},"\ncommand-line utility.",{"type":20,"tag":21,"props":68,"children":69},{},[70],{"type":25,"value":71},"First, you'll want to determine the user ID associated with the user for whom you'd like to reset the password.",{"type":20,"tag":73,"props":74,"children":76},"pre",{"code":75},"# ipmitool user list\nID Name Callin Link Auth IPMI Msg Channel Priv Limit\n1 true false false Unknown (0x00)\n2 ADMIN true false false Unknown (0x00)\n",[77],{"type":20,"tag":38,"props":78,"children":79},{"__ignoreMap":7},[80],{"type":25,"value":75},{"type":20,"tag":21,"props":82,"children":83},{},[84,86,91,93,98],{"type":25,"value":85},"In this case, we will be resetting the password for ",{"type":20,"tag":47,"props":87,"children":88},{},[89],{"type":25,"value":90},"ADMIN",{"type":25,"value":92}," who has a user ID of ",{"type":20,"tag":47,"props":94,"children":95},{},[96],{"type":25,"value":97},"2",{"type":25,"value":99},". Then we'll assign the new\npassword like so:",{"type":20,"tag":73,"props":101,"children":103},{"code":102},"# ipmitool user set password 2 \u003Cpassword>\n",[104],{"type":20,"tag":38,"props":105,"children":106},{"__ignoreMap":7},[107],{"type":25,"value":102},{"type":20,"tag":21,"props":109,"children":110},{},[111],{"type":25,"value":112},"And you should be good to go!",{"type":20,"tag":21,"props":114,"children":115},{},[116],{"type":25,"value":117},"...",{"type":20,"tag":21,"props":119,"children":120},{},[121],{"type":25,"value":122},"Alternatively, if you'd like to factory reset the baseboard management controller (BMC), which will reset the IPMI\ncredentials to their default value, you can issue the following command.",{"type":20,"tag":73,"props":124,"children":126},{"code":125},"# ipmitool raw 0x3c 0x40\n",[127],{"type":20,"tag":38,"props":128,"children":129},{"__ignoreMap":7},[130],{"type":25,"value":125},{"type":20,"tag":21,"props":132,"children":133},{},[134,136,142,144,150,152,158,159,165,167,176,178,183,185,192],{"type":25,"value":135},"Where ",{"type":20,"tag":38,"props":137,"children":139},{"className":138},[],[140],{"type":25,"value":141},"0x3c",{"type":25,"value":143}," is the ",{"type":20,"tag":38,"props":145,"children":147},{"className":146},[],[148],{"type":25,"value":149},"\u003Cnetfn>",{"type":25,"value":151}," argument, a.k.a. the network function code that defines the functional routing for\nmessages, and ",{"type":20,"tag":38,"props":153,"children":155},{"className":154},[],[156],{"type":25,"value":157},"0x40",{"type":25,"value":143},{"type":20,"tag":38,"props":160,"children":162},{"className":161},[],[163],{"type":25,"value":164},"\u003Ccmd>",{"type":25,"value":166},". According to section 5.1 of the ",{"type":20,"tag":168,"props":169,"children":173},"a",{"href":170,"rel":171},"https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf",[172],"nofollow",[174],{"type":25,"value":175},"IPMI interface\nspecification",{"type":25,"value":177},",\n",{"type":20,"tag":47,"props":179,"children":180},{},[181],{"type":25,"value":182},"netfn",{"type":25,"value":184}," codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some\nSupermicro references on these vendor specific network functions without much luck other than various ",{"type":20,"tag":168,"props":186,"children":189},{"href":187,"rel":188},"https://www.supermicro.com/support/faqs/faq.cfm?faq=15448",[172],[190],{"type":25,"value":191},"support\nresponses",{"type":25,"value":193}," on how to reset a device. Bummer!",{"title":7,"searchDepth":195,"depth":195,"links":196},2,[],"markdown","content:articles:reset-ipmi-password-from-host-os.md","content","articles/reset-ipmi-password-from-host-os.md","articles/reset-ipmi-password-from-host-os","md",1720229315497] \ No newline at end of file diff --git a/articles/reset-ipmi-password-from-host-os/index.html b/articles/reset-ipmi-password-from-host-os/index.html index 6f98ef9d..7bb6252d 100644 --- a/articles/reset-ipmi-password-from-host-os/index.html +++ b/articles/reset-ipmi-password-from-host-os/index.html @@ -4,32 +4,33 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - -

            Reset IPMI Credentials from the Host OS

            2021-12-27

            If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these + + + + + + + + + + + + + +

            Reset IPMI Credentials from the Host OS

            If you ever find yourself locked out of the Intelligent Platform Management Interface (IPMI) of a server, these instructions will guide your through the process of resetting the credentials to their default values from the host operating system.

            If you are using an operating system like TrueNAS -- good news! It's possible to reset the IPMI password directly from the web interface. This is done by navigating to Network > IPMI, and simply entering a new value in the IPMI @@ -47,5 +48,5 @@ specification, netfn codes ranging from 0x30 to 0x3F are reserved for vendor specific functions. I searched around for some Supermicro references on these vendor specific network functions without much luck other than various support -responses on how to reset a device. Bummer!

            - \ No newline at end of file +responses on how to reset a device. Bummer!

            + \ No newline at end of file diff --git a/articles/ssh-ed25519-sk-yubikey/_payload.json b/articles/ssh-ed25519-sk-yubikey/_payload.json index 6b5e3c64..d6f2b240 100644 --- a/articles/ssh-ed25519-sk-yubikey/_payload.json +++ b/articles/ssh-ed25519-sk-yubikey/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":516},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"excerpt":17,"body":46,"_type":511,"_id":512,"_source":513,"_file":514,"_extension":515},"/articles/ssh-ed25519-sk-yubikey","articles",false,"","Configuring a YubiKey for use with OpenSSH","YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","2024-06-09",[12,13],"unix","configurations",[15,16],"tooling","tips",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,35,37,44],{"type":21,"tag":26,"props":27,"children":31},"a",{"href":28,"rel":29},"https://www.yubico.com/",[30],"nofollow",[32],{"type":33,"value":34},"text","YubiKey's",{"type":33,"value":36}," are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ",{"type":21,"tag":38,"props":39,"children":41},"code",{"className":40},[],[42],{"type":33,"value":43},"ed25519-sk",{"type":33,"value":45}," key type that supports FIDO compliant hardware keys.",{"type":18,"children":47,"toc":509},[48,63,77,86,100,143,148,192,205,238,243,376,389,484,503],{"type":21,"tag":22,"props":49,"children":50},{},[51,56,57,62],{"type":21,"tag":26,"props":52,"children":54},{"href":28,"rel":53},[30],[55],{"type":33,"value":34},{"type":33,"value":36},{"type":21,"tag":38,"props":58,"children":60},{"className":59},[],[61],{"type":33,"value":43},{"type":33,"value":45},{"type":21,"tag":22,"props":64,"children":65},{},[66,68,75],{"type":33,"value":67},"In ",{"type":21,"tag":26,"props":69,"children":72},{"href":70,"rel":71},"https://www.openssh.com/txt/release-8.2",[30],[73],{"type":33,"value":74},"release 8.2 of OpenSSH",{"type":33,"value":76}," support for FIDO devices was added with public key types \"ecdsa-sk\" and \"ed25519-sk\" (-sk standing for \"security key\"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher.",{"type":21,"tag":78,"props":79,"children":80},"blockquote",{},[81],{"type":21,"tag":22,"props":82,"children":83},{},[84],{"type":33,"value":85},"This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types \"ecdsa-sk\" and \"ed25519-sk\", along with corresponding certificate types.",{"type":21,"tag":22,"props":87,"children":88},{},[89,91,98],{"type":33,"value":90},"Let's get started by installing the latest version of OpenSSH via ",{"type":21,"tag":26,"props":92,"children":95},{"href":93,"rel":94},"https://brew.sh/",[30],[96],{"type":33,"value":97},"Homebrew",{"type":33,"value":99},", along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible.",{"type":21,"tag":101,"props":102,"children":106},"pre",{"className":103,"code":104,"language":105,"meta":7,"style":7},"language-sh shiki shiki-themes github-light","$ brew install openssh ykman\n","sh",[107],{"type":21,"tag":38,"props":108,"children":109},{"__ignoreMap":7},[110],{"type":21,"tag":111,"props":112,"children":115},"span",{"class":113,"line":114},"line",1,[116,122,128,133,138],{"type":21,"tag":111,"props":117,"children":119},{"style":118},"--shiki-default:#6F42C1",[120],{"type":33,"value":121},"$",{"type":21,"tag":111,"props":123,"children":125},{"style":124},"--shiki-default:#032F62",[126],{"type":33,"value":127}," brew",{"type":21,"tag":111,"props":129,"children":130},{"style":124},[131],{"type":33,"value":132}," install",{"type":21,"tag":111,"props":134,"children":135},{"style":124},[136],{"type":33,"value":137}," openssh",{"type":21,"tag":111,"props":139,"children":140},{"style":124},[141],{"type":33,"value":142}," ykman\n",{"type":21,"tag":22,"props":144,"children":145},{},[146],{"type":33,"value":147},"Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:",{"type":21,"tag":101,"props":149,"children":151},{"className":103,"code":150,"language":105,"meta":7,"style":7},"$ ykman list\nYubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]\n",[152],{"type":21,"tag":38,"props":153,"children":154},{"__ignoreMap":7},[155,172],{"type":21,"tag":111,"props":156,"children":157},{"class":113,"line":114},[158,162,167],{"type":21,"tag":111,"props":159,"children":160},{"style":118},[161],{"type":33,"value":121},{"type":21,"tag":111,"props":163,"children":164},{"style":124},[165],{"type":33,"value":166}," ykman",{"type":21,"tag":111,"props":168,"children":169},{"style":124},[170],{"type":33,"value":171}," list\n",{"type":21,"tag":111,"props":173,"children":175},{"class":113,"line":174},2,[176,181,186],{"type":21,"tag":111,"props":177,"children":178},{"style":118},[179],{"type":33,"value":180},"YubiKey",{"type":21,"tag":111,"props":182,"children":183},{"style":124},[184],{"type":33,"value":185}," 5Ci",{"type":21,"tag":111,"props":187,"children":189},{"style":188},"--shiki-default:#24292E",[190],{"type":33,"value":191}," (5.4.3) [OTP+FIDO+CCID]\n",{"type":21,"tag":22,"props":193,"children":194},{},[195,197,203],{"type":33,"value":196},"Next, we'll go ahead and enable a pin on our device via the ",{"type":21,"tag":38,"props":198,"children":200},{"className":199},[],[201],{"type":33,"value":202},"change-pin",{"type":33,"value":204}," command, as this a requirement for our use.",{"type":21,"tag":101,"props":206,"children":208},{"className":103,"code":207,"language":105,"meta":7,"style":7},"$ ykman fido access change-pin\n",[209],{"type":21,"tag":38,"props":210,"children":211},{"__ignoreMap":7},[212],{"type":21,"tag":111,"props":213,"children":214},{"class":113,"line":114},[215,219,223,228,233],{"type":21,"tag":111,"props":216,"children":217},{"style":118},[218],{"type":33,"value":121},{"type":21,"tag":111,"props":220,"children":221},{"style":124},[222],{"type":33,"value":166},{"type":21,"tag":111,"props":224,"children":225},{"style":124},[226],{"type":33,"value":227}," fido",{"type":21,"tag":111,"props":229,"children":230},{"style":124},[231],{"type":33,"value":232}," access",{"type":21,"tag":111,"props":234,"children":235},{"style":124},[236],{"type":33,"value":237}," change-pin\n",{"type":21,"tag":22,"props":239,"children":240},{},[241],{"type":33,"value":242},"And last, we'll generate the key on our device!",{"type":21,"tag":101,"props":244,"children":246},{"className":103,"code":245,"language":105,"meta":7,"style":7},"$ ssh-keygen -t ed25519-sk -O resident\nGenerating public/private ed25519-sk key pair.\nYou may need to touch your authenticator to authorize key generation.\n...\n",[247],{"type":21,"tag":38,"props":248,"children":249},{"__ignoreMap":7},[250,283,310,367],{"type":21,"tag":111,"props":251,"children":252},{"class":113,"line":114},[253,257,262,268,273,278],{"type":21,"tag":111,"props":254,"children":255},{"style":118},[256],{"type":33,"value":121},{"type":21,"tag":111,"props":258,"children":259},{"style":124},[260],{"type":33,"value":261}," ssh-keygen",{"type":21,"tag":111,"props":263,"children":265},{"style":264},"--shiki-default:#005CC5",[266],{"type":33,"value":267}," -t",{"type":21,"tag":111,"props":269,"children":270},{"style":124},[271],{"type":33,"value":272}," ed25519-sk",{"type":21,"tag":111,"props":274,"children":275},{"style":264},[276],{"type":33,"value":277}," -O",{"type":21,"tag":111,"props":279,"children":280},{"style":124},[281],{"type":33,"value":282}," resident\n",{"type":21,"tag":111,"props":284,"children":285},{"class":113,"line":174},[286,291,296,300,305],{"type":21,"tag":111,"props":287,"children":288},{"style":118},[289],{"type":33,"value":290},"Generating",{"type":21,"tag":111,"props":292,"children":293},{"style":124},[294],{"type":33,"value":295}," public/private",{"type":21,"tag":111,"props":297,"children":298},{"style":124},[299],{"type":33,"value":272},{"type":21,"tag":111,"props":301,"children":302},{"style":124},[303],{"type":33,"value":304}," key",{"type":21,"tag":111,"props":306,"children":307},{"style":124},[308],{"type":33,"value":309}," pair.\n",{"type":21,"tag":111,"props":311,"children":313},{"class":113,"line":312},3,[314,319,324,329,334,339,344,349,353,358,362],{"type":21,"tag":111,"props":315,"children":316},{"style":118},[317],{"type":33,"value":318},"You",{"type":21,"tag":111,"props":320,"children":321},{"style":124},[322],{"type":33,"value":323}," may",{"type":21,"tag":111,"props":325,"children":326},{"style":124},[327],{"type":33,"value":328}," need",{"type":21,"tag":111,"props":330,"children":331},{"style":124},[332],{"type":33,"value":333}," to",{"type":21,"tag":111,"props":335,"children":336},{"style":124},[337],{"type":33,"value":338}," touch",{"type":21,"tag":111,"props":340,"children":341},{"style":124},[342],{"type":33,"value":343}," your",{"type":21,"tag":111,"props":345,"children":346},{"style":124},[347],{"type":33,"value":348}," authenticator",{"type":21,"tag":111,"props":350,"children":351},{"style":124},[352],{"type":33,"value":333},{"type":21,"tag":111,"props":354,"children":355},{"style":124},[356],{"type":33,"value":357}," authorize",{"type":21,"tag":111,"props":359,"children":360},{"style":124},[361],{"type":33,"value":304},{"type":21,"tag":111,"props":363,"children":364},{"style":124},[365],{"type":33,"value":366}," generation.\n",{"type":21,"tag":111,"props":368,"children":370},{"class":113,"line":369},4,[371],{"type":21,"tag":111,"props":372,"children":373},{"style":264},[374],{"type":33,"value":375},"...\n",{"type":21,"tag":22,"props":377,"children":378},{},[379,381,387],{"type":33,"value":380},"We specify ",{"type":21,"tag":382,"props":383,"children":384},"em",{},[385],{"type":33,"value":386},"resident",{"type":33,"value":388}," to indicate that the key handle is to be stored on the YubiKey itself, since we will be using this device with multiple computers.",{"type":21,"tag":101,"props":390,"children":394},{"className":391,"code":392,"language":393,"meta":7,"style":7},"language-txt shiki shiki-themes github-light","resident\n Indicate that the key handle should be stored on the FIDO\n authenticator itself. This makes it easier to use the\n authenticator on multiple computers. Resident keys may be\n supported on FIDO2 authenticators and typically require that a PIN\n be set on the authenticator prior to generation. Resident keys\n may be loaded off the authenticator using ssh-add(1). Storing\n both parts of a key on a FIDO authenticator increases the\n likelihood of an attacker being able to use a stolen authenticator\n device.\n","txt",[395],{"type":21,"tag":38,"props":396,"children":397},{"__ignoreMap":7},[398,406,414,422,430,439,448,457,466,475],{"type":21,"tag":111,"props":399,"children":400},{"class":113,"line":114},[401],{"type":21,"tag":111,"props":402,"children":403},{},[404],{"type":33,"value":405},"resident\n",{"type":21,"tag":111,"props":407,"children":408},{"class":113,"line":174},[409],{"type":21,"tag":111,"props":410,"children":411},{},[412],{"type":33,"value":413}," Indicate that the key handle should be stored on the FIDO\n",{"type":21,"tag":111,"props":415,"children":416},{"class":113,"line":312},[417],{"type":21,"tag":111,"props":418,"children":419},{},[420],{"type":33,"value":421}," authenticator itself. This makes it easier to use the\n",{"type":21,"tag":111,"props":423,"children":424},{"class":113,"line":369},[425],{"type":21,"tag":111,"props":426,"children":427},{},[428],{"type":33,"value":429}," authenticator on multiple computers. Resident keys may be\n",{"type":21,"tag":111,"props":431,"children":433},{"class":113,"line":432},5,[434],{"type":21,"tag":111,"props":435,"children":436},{},[437],{"type":33,"value":438}," supported on FIDO2 authenticators and typically require that a PIN\n",{"type":21,"tag":111,"props":440,"children":442},{"class":113,"line":441},6,[443],{"type":21,"tag":111,"props":444,"children":445},{},[446],{"type":33,"value":447}," be set on the authenticator prior to generation. Resident keys\n",{"type":21,"tag":111,"props":449,"children":451},{"class":113,"line":450},7,[452],{"type":21,"tag":111,"props":453,"children":454},{},[455],{"type":33,"value":456}," may be loaded off the authenticator using ssh-add(1). Storing\n",{"type":21,"tag":111,"props":458,"children":460},{"class":113,"line":459},8,[461],{"type":21,"tag":111,"props":462,"children":463},{},[464],{"type":33,"value":465}," both parts of a key on a FIDO authenticator increases the\n",{"type":21,"tag":111,"props":467,"children":469},{"class":113,"line":468},9,[470],{"type":21,"tag":111,"props":471,"children":472},{},[473],{"type":33,"value":474}," likelihood of an attacker being able to use a stolen authenticator\n",{"type":21,"tag":111,"props":476,"children":478},{"class":113,"line":477},10,[479],{"type":21,"tag":111,"props":480,"children":481},{},[482],{"type":33,"value":483}," device.\n",{"type":21,"tag":22,"props":485,"children":486},{},[487,489,494,496,501],{"type":33,"value":488},"And that's all it takes -- simple enough. Now, when interacting with ",{"type":21,"tag":382,"props":490,"children":491},{},[492],{"type":33,"value":493},"ssh",{"type":33,"value":495}," or ",{"type":21,"tag":382,"props":497,"children":498},{},[499],{"type":33,"value":500},"git",{"type":33,"value":502}," you will be prompted to touch the YubiKey to bring that little bit of physical 2FA.",{"type":21,"tag":504,"props":505,"children":506},"style",{},[507],{"type":33,"value":508},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":174,"depth":174,"links":510},[],"markdown","content:articles:ssh-ed25519-sk-yubikey.md","content","articles/ssh-ed25519-sk-yubikey.md","md",1718891181713] \ No newline at end of file +[{"data":1,"prerenderedAt":517},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"excerpt":17,"body":46,"_type":511,"_id":512,"_source":513,"_file":514,"_stem":515,"_extension":516},"/articles/ssh-ed25519-sk-yubikey","articles",false,"","Configuring a YubiKey for use with OpenSSH","YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ed25519-sk key type that supports FIDO compliant hardware keys.","2024-06-09",[12,13],"unix","configurations",[15,16],"tooling","tips",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,35,37,44],{"type":21,"tag":26,"props":27,"children":31},"a",{"href":28,"rel":29},"https://www.yubico.com/",[30],"nofollow",[32],{"type":33,"value":34},"text","YubiKey's",{"type":33,"value":36}," are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the \"new\" ",{"type":21,"tag":38,"props":39,"children":41},"code",{"className":40},[],[42],{"type":33,"value":43},"ed25519-sk",{"type":33,"value":45}," key type that supports FIDO compliant hardware keys.",{"type":18,"children":47,"toc":509},[48,63,77,86,100,143,148,192,205,238,243,376,389,484,503],{"type":21,"tag":22,"props":49,"children":50},{},[51,56,57,62],{"type":21,"tag":26,"props":52,"children":54},{"href":28,"rel":53},[30],[55],{"type":33,"value":34},{"type":33,"value":36},{"type":21,"tag":38,"props":58,"children":60},{"className":59},[],[61],{"type":33,"value":43},{"type":33,"value":45},{"type":21,"tag":22,"props":64,"children":65},{},[66,68,75],{"type":33,"value":67},"In ",{"type":21,"tag":26,"props":69,"children":72},{"href":70,"rel":71},"https://www.openssh.com/txt/release-8.2",[30],[73],{"type":33,"value":74},"release 8.2 of OpenSSH",{"type":33,"value":76}," support for FIDO devices was added with public key types \"ecdsa-sk\" and \"ed25519-sk\" (-sk standing for \"security key\"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher.",{"type":21,"tag":78,"props":79,"children":80},"blockquote",{},[81],{"type":21,"tag":22,"props":82,"children":83},{},[84],{"type":33,"value":85},"This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types \"ecdsa-sk\" and \"ed25519-sk\", along with corresponding certificate types.",{"type":21,"tag":22,"props":87,"children":88},{},[89,91,98],{"type":33,"value":90},"Let's get started by installing the latest version of OpenSSH via ",{"type":21,"tag":26,"props":92,"children":95},{"href":93,"rel":94},"https://brew.sh/",[30],[96],{"type":33,"value":97},"Homebrew",{"type":33,"value":99},", along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible.",{"type":21,"tag":101,"props":102,"children":106},"pre",{"className":103,"code":104,"language":105,"meta":7,"style":7},"language-sh shiki shiki-themes github-light","$ brew install openssh ykman\n","sh",[107],{"type":21,"tag":38,"props":108,"children":109},{"__ignoreMap":7},[110],{"type":21,"tag":111,"props":112,"children":115},"span",{"class":113,"line":114},"line",1,[116,122,128,133,138],{"type":21,"tag":111,"props":117,"children":119},{"style":118},"--shiki-default:#6F42C1",[120],{"type":33,"value":121},"$",{"type":21,"tag":111,"props":123,"children":125},{"style":124},"--shiki-default:#032F62",[126],{"type":33,"value":127}," brew",{"type":21,"tag":111,"props":129,"children":130},{"style":124},[131],{"type":33,"value":132}," install",{"type":21,"tag":111,"props":134,"children":135},{"style":124},[136],{"type":33,"value":137}," openssh",{"type":21,"tag":111,"props":139,"children":140},{"style":124},[141],{"type":33,"value":142}," ykman\n",{"type":21,"tag":22,"props":144,"children":145},{},[146],{"type":33,"value":147},"Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:",{"type":21,"tag":101,"props":149,"children":151},{"className":103,"code":150,"language":105,"meta":7,"style":7},"$ ykman list\nYubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]\n",[152],{"type":21,"tag":38,"props":153,"children":154},{"__ignoreMap":7},[155,172],{"type":21,"tag":111,"props":156,"children":157},{"class":113,"line":114},[158,162,167],{"type":21,"tag":111,"props":159,"children":160},{"style":118},[161],{"type":33,"value":121},{"type":21,"tag":111,"props":163,"children":164},{"style":124},[165],{"type":33,"value":166}," ykman",{"type":21,"tag":111,"props":168,"children":169},{"style":124},[170],{"type":33,"value":171}," list\n",{"type":21,"tag":111,"props":173,"children":175},{"class":113,"line":174},2,[176,181,186],{"type":21,"tag":111,"props":177,"children":178},{"style":118},[179],{"type":33,"value":180},"YubiKey",{"type":21,"tag":111,"props":182,"children":183},{"style":124},[184],{"type":33,"value":185}," 5Ci",{"type":21,"tag":111,"props":187,"children":189},{"style":188},"--shiki-default:#24292E",[190],{"type":33,"value":191}," (5.4.3) [OTP+FIDO+CCID]\n",{"type":21,"tag":22,"props":193,"children":194},{},[195,197,203],{"type":33,"value":196},"Next, we'll go ahead and enable a pin on our device via the ",{"type":21,"tag":38,"props":198,"children":200},{"className":199},[],[201],{"type":33,"value":202},"change-pin",{"type":33,"value":204}," command, as this a requirement for our use.",{"type":21,"tag":101,"props":206,"children":208},{"className":103,"code":207,"language":105,"meta":7,"style":7},"$ ykman fido access change-pin\n",[209],{"type":21,"tag":38,"props":210,"children":211},{"__ignoreMap":7},[212],{"type":21,"tag":111,"props":213,"children":214},{"class":113,"line":114},[215,219,223,228,233],{"type":21,"tag":111,"props":216,"children":217},{"style":118},[218],{"type":33,"value":121},{"type":21,"tag":111,"props":220,"children":221},{"style":124},[222],{"type":33,"value":166},{"type":21,"tag":111,"props":224,"children":225},{"style":124},[226],{"type":33,"value":227}," fido",{"type":21,"tag":111,"props":229,"children":230},{"style":124},[231],{"type":33,"value":232}," access",{"type":21,"tag":111,"props":234,"children":235},{"style":124},[236],{"type":33,"value":237}," change-pin\n",{"type":21,"tag":22,"props":239,"children":240},{},[241],{"type":33,"value":242},"And last, we'll generate the key on our device!",{"type":21,"tag":101,"props":244,"children":246},{"className":103,"code":245,"language":105,"meta":7,"style":7},"$ ssh-keygen -t ed25519-sk -O resident\nGenerating public/private ed25519-sk key pair.\nYou may need to touch your authenticator to authorize key generation.\n...\n",[247],{"type":21,"tag":38,"props":248,"children":249},{"__ignoreMap":7},[250,283,310,367],{"type":21,"tag":111,"props":251,"children":252},{"class":113,"line":114},[253,257,262,268,273,278],{"type":21,"tag":111,"props":254,"children":255},{"style":118},[256],{"type":33,"value":121},{"type":21,"tag":111,"props":258,"children":259},{"style":124},[260],{"type":33,"value":261}," ssh-keygen",{"type":21,"tag":111,"props":263,"children":265},{"style":264},"--shiki-default:#005CC5",[266],{"type":33,"value":267}," -t",{"type":21,"tag":111,"props":269,"children":270},{"style":124},[271],{"type":33,"value":272}," ed25519-sk",{"type":21,"tag":111,"props":274,"children":275},{"style":264},[276],{"type":33,"value":277}," -O",{"type":21,"tag":111,"props":279,"children":280},{"style":124},[281],{"type":33,"value":282}," resident\n",{"type":21,"tag":111,"props":284,"children":285},{"class":113,"line":174},[286,291,296,300,305],{"type":21,"tag":111,"props":287,"children":288},{"style":118},[289],{"type":33,"value":290},"Generating",{"type":21,"tag":111,"props":292,"children":293},{"style":124},[294],{"type":33,"value":295}," public/private",{"type":21,"tag":111,"props":297,"children":298},{"style":124},[299],{"type":33,"value":272},{"type":21,"tag":111,"props":301,"children":302},{"style":124},[303],{"type":33,"value":304}," key",{"type":21,"tag":111,"props":306,"children":307},{"style":124},[308],{"type":33,"value":309}," pair.\n",{"type":21,"tag":111,"props":311,"children":313},{"class":113,"line":312},3,[314,319,324,329,334,339,344,349,353,358,362],{"type":21,"tag":111,"props":315,"children":316},{"style":118},[317],{"type":33,"value":318},"You",{"type":21,"tag":111,"props":320,"children":321},{"style":124},[322],{"type":33,"value":323}," may",{"type":21,"tag":111,"props":325,"children":326},{"style":124},[327],{"type":33,"value":328}," need",{"type":21,"tag":111,"props":330,"children":331},{"style":124},[332],{"type":33,"value":333}," to",{"type":21,"tag":111,"props":335,"children":336},{"style":124},[337],{"type":33,"value":338}," touch",{"type":21,"tag":111,"props":340,"children":341},{"style":124},[342],{"type":33,"value":343}," your",{"type":21,"tag":111,"props":345,"children":346},{"style":124},[347],{"type":33,"value":348}," authenticator",{"type":21,"tag":111,"props":350,"children":351},{"style":124},[352],{"type":33,"value":333},{"type":21,"tag":111,"props":354,"children":355},{"style":124},[356],{"type":33,"value":357}," authorize",{"type":21,"tag":111,"props":359,"children":360},{"style":124},[361],{"type":33,"value":304},{"type":21,"tag":111,"props":363,"children":364},{"style":124},[365],{"type":33,"value":366}," generation.\n",{"type":21,"tag":111,"props":368,"children":370},{"class":113,"line":369},4,[371],{"type":21,"tag":111,"props":372,"children":373},{"style":264},[374],{"type":33,"value":375},"...\n",{"type":21,"tag":22,"props":377,"children":378},{},[379,381,387],{"type":33,"value":380},"We specify ",{"type":21,"tag":382,"props":383,"children":384},"em",{},[385],{"type":33,"value":386},"resident",{"type":33,"value":388}," to indicate that the key handle is to be stored on the YubiKey itself, since we will be using this device with multiple computers.",{"type":21,"tag":101,"props":390,"children":394},{"className":391,"code":392,"language":393,"meta":7,"style":7},"language-txt shiki shiki-themes github-light","resident\n Indicate that the key handle should be stored on the FIDO\n authenticator itself. This makes it easier to use the\n authenticator on multiple computers. Resident keys may be\n supported on FIDO2 authenticators and typically require that a PIN\n be set on the authenticator prior to generation. Resident keys\n may be loaded off the authenticator using ssh-add(1). Storing\n both parts of a key on a FIDO authenticator increases the\n likelihood of an attacker being able to use a stolen authenticator\n device.\n","txt",[395],{"type":21,"tag":38,"props":396,"children":397},{"__ignoreMap":7},[398,406,414,422,430,439,448,457,466,475],{"type":21,"tag":111,"props":399,"children":400},{"class":113,"line":114},[401],{"type":21,"tag":111,"props":402,"children":403},{},[404],{"type":33,"value":405},"resident\n",{"type":21,"tag":111,"props":407,"children":408},{"class":113,"line":174},[409],{"type":21,"tag":111,"props":410,"children":411},{},[412],{"type":33,"value":413}," Indicate that the key handle should be stored on the FIDO\n",{"type":21,"tag":111,"props":415,"children":416},{"class":113,"line":312},[417],{"type":21,"tag":111,"props":418,"children":419},{},[420],{"type":33,"value":421}," authenticator itself. This makes it easier to use the\n",{"type":21,"tag":111,"props":423,"children":424},{"class":113,"line":369},[425],{"type":21,"tag":111,"props":426,"children":427},{},[428],{"type":33,"value":429}," authenticator on multiple computers. Resident keys may be\n",{"type":21,"tag":111,"props":431,"children":433},{"class":113,"line":432},5,[434],{"type":21,"tag":111,"props":435,"children":436},{},[437],{"type":33,"value":438}," supported on FIDO2 authenticators and typically require that a PIN\n",{"type":21,"tag":111,"props":440,"children":442},{"class":113,"line":441},6,[443],{"type":21,"tag":111,"props":444,"children":445},{},[446],{"type":33,"value":447}," be set on the authenticator prior to generation. Resident keys\n",{"type":21,"tag":111,"props":449,"children":451},{"class":113,"line":450},7,[452],{"type":21,"tag":111,"props":453,"children":454},{},[455],{"type":33,"value":456}," may be loaded off the authenticator using ssh-add(1). Storing\n",{"type":21,"tag":111,"props":458,"children":460},{"class":113,"line":459},8,[461],{"type":21,"tag":111,"props":462,"children":463},{},[464],{"type":33,"value":465}," both parts of a key on a FIDO authenticator increases the\n",{"type":21,"tag":111,"props":467,"children":469},{"class":113,"line":468},9,[470],{"type":21,"tag":111,"props":471,"children":472},{},[473],{"type":33,"value":474}," likelihood of an attacker being able to use a stolen authenticator\n",{"type":21,"tag":111,"props":476,"children":478},{"class":113,"line":477},10,[479],{"type":21,"tag":111,"props":480,"children":481},{},[482],{"type":33,"value":483}," device.\n",{"type":21,"tag":22,"props":485,"children":486},{},[487,489,494,496,501],{"type":33,"value":488},"And that's all it takes -- simple enough. Now, when interacting with ",{"type":21,"tag":382,"props":490,"children":491},{},[492],{"type":33,"value":493},"ssh",{"type":33,"value":495}," or ",{"type":21,"tag":382,"props":497,"children":498},{},[499],{"type":33,"value":500},"git",{"type":33,"value":502}," you will be prompted to touch the YubiKey to bring that little bit of physical 2FA.",{"type":21,"tag":504,"props":505,"children":506},"style",{},[507],{"type":33,"value":508},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":174,"depth":174,"links":510},[],"markdown","content:articles:ssh-ed25519-sk-yubikey.md","content","articles/ssh-ed25519-sk-yubikey.md","articles/ssh-ed25519-sk-yubikey","md",1720229315485] \ No newline at end of file diff --git a/articles/ssh-ed25519-sk-yubikey/index.html b/articles/ssh-ed25519-sk-yubikey/index.html index 03ec58b3..851f67cf 100644 --- a/articles/ssh-ed25519-sk-yubikey/index.html +++ b/articles/ssh-ed25519-sk-yubikey/index.html @@ -4,33 +4,34 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - - -

            Configuring a YubiKey for use with OpenSSH

            2024-06-09

            YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the "new" ed25519-sk key type that supports FIDO compliant hardware keys.

            In release 8.2 of OpenSSH support for FIDO devices was added with public key types "ecdsa-sk" and "ed25519-sk" (-sk standing for "security key"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher.

            This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types "ecdsa-sk" and "ed25519-sk", along with corresponding certificate types.

            Let's get started by installing the latest version of OpenSSH via Homebrew, along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible.

            $ brew install openssh ykman
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Configuring a YubiKey for use with OpenSSH

            YubiKey's are a convenient way to introduce a physical form of two factor authentication into ones workflow. They support a variety of protocols, but in this guide we will walk through how to configure a YubiKey for use with OpenSSH via the "new" ed25519-sk key type that supports FIDO compliant hardware keys.

            In release 8.2 of OpenSSH support for FIDO devices was added with public key types "ecdsa-sk" and "ed25519-sk" (-sk standing for "security key"). This key type is supported by YubiKey's with firmware version 5.2.3 or higher.

            This release adds support for FIDO/U2F hardware authenticators to OpenSSH. U2F/FIDO are open standards for inexpensive two-factor authentication hardware that are widely used for website authentication. In OpenSSH FIDO devices are supported by new public key types "ecdsa-sk" and "ed25519-sk", along with corresponding certificate types.

            Let's get started by installing the latest version of OpenSSH via Homebrew, along with the YubiKey Manager (ykman) CLI. The version of OpenSSH included with macOS is not compatible.

            $ brew install openssh ykman
             

            Then, let's confirm that our YubiKey has a firmware that is greater than 5.2.3:

            $ ykman list
             YubiKey 5Ci (5.4.3) [OTP+FIDO+CCID]
             

            Next, we'll go ahead and enable a pin on our device via the change-pin command, as this a requirement for our use.

            $ ykman fido access change-pin
            @@ -48,5 +49,5 @@
                     both parts of a key on a FIDO authenticator increases the
                     likelihood of an attacker being able to use a stolen authenticator
                     device.
            -

            And that's all it takes -- simple enough. Now, when interacting with ssh or git you will be prompted to touch the YubiKey to bring that little bit of physical 2FA.

            - \ No newline at end of file +

            And that's all it takes -- simple enough. Now, when interacting with ssh or git you will be prompted to touch the YubiKey to bring that little bit of physical 2FA.

            + \ No newline at end of file diff --git a/articles/unit-testing-micropython-with-mocks/_payload.json b/articles/unit-testing-micropython-with-mocks/_payload.json index d75fe5b3..5881b92c 100644 --- a/articles/unit-testing-micropython-with-mocks/_payload.json +++ b/articles/unit-testing-micropython-with-mocks/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":689},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":16,"excerpt":19,"body":29,"_type":684,"_id":685,"_source":686,"_file":687,"_extension":688},"/articles/unit-testing-micropython-with-mocks","articles",false,"","Unit Testing in MicroPython with Mocks","Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","2020-02-07",[12,13,14,15],"micropython","testing","mocks","tutorial",[17,18],"python","embedded",{"type":20,"children":21},"root",[22],{"type":23,"tag":24,"props":25,"children":26},"element","p",{},[27],{"type":28,"value":9},"text",{"type":20,"children":30,"toc":681},[31,35,42,47,53,75,252,278,398,419,618,646,653,675],{"type":23,"tag":24,"props":32,"children":33},{},[34],{"type":28,"value":9},{"type":23,"tag":36,"props":37,"children":39},"h1",{"id":38},"mocking",[40],{"type":28,"value":41},"Mocking",{"type":23,"tag":24,"props":43,"children":44},{},[45],{"type":28,"value":46},"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed.",{"type":23,"tag":36,"props":48,"children":50},{"id":49},"a-micropython-mocking-example",[51],{"type":28,"value":52},"A MicroPython Mocking Example",{"type":23,"tag":24,"props":54,"children":55},{},[56,58,65,67,73],{"type":28,"value":57},"In this example, we will be unit testing a module named ",{"type":23,"tag":59,"props":60,"children":62},"code",{"className":61},[],[63],{"type":28,"value":64},"time_logger",{"type":28,"value":66},", that\ndepends on the MicroPython library ",{"type":23,"tag":59,"props":68,"children":70},{"className":69},[],[71],{"type":28,"value":72},"utime",{"type":28,"value":74}," to log the most recent Epoch time to\na file.",{"type":23,"tag":76,"props":77,"children":80},"pre",{"className":78,"code":79,"language":17,"meta":7,"style":7},"language-python shiki shiki-themes github-light","# time_logger.py\n\nclass TimeLogger(object):\n\n def save_time(self):\n \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n \"\"\"\n with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n f.write(str(utime.time()))\n",[81],{"type":23,"tag":59,"props":82,"children":83},{"__ignoreMap":7},[84,96,106,139,147,166,176,185,233],{"type":23,"tag":85,"props":86,"children":89},"span",{"class":87,"line":88},"line",1,[90],{"type":23,"tag":85,"props":91,"children":93},{"style":92},"--shiki-default:#6A737D",[94],{"type":28,"value":95},"# time_logger.py\n",{"type":23,"tag":85,"props":97,"children":99},{"class":87,"line":98},2,[100],{"type":23,"tag":85,"props":101,"children":103},{"emptyLinePlaceholder":102},true,[104],{"type":28,"value":105},"\n",{"type":23,"tag":85,"props":107,"children":109},{"class":87,"line":108},3,[110,116,122,128,134],{"type":23,"tag":85,"props":111,"children":113},{"style":112},"--shiki-default:#D73A49",[114],{"type":28,"value":115},"class",{"type":23,"tag":85,"props":117,"children":119},{"style":118},"--shiki-default:#6F42C1",[120],{"type":28,"value":121}," TimeLogger",{"type":23,"tag":85,"props":123,"children":125},{"style":124},"--shiki-default:#24292E",[126],{"type":28,"value":127},"(",{"type":23,"tag":85,"props":129,"children":131},{"style":130},"--shiki-default:#005CC5",[132],{"type":28,"value":133},"object",{"type":23,"tag":85,"props":135,"children":136},{"style":124},[137],{"type":28,"value":138},"):\n",{"type":23,"tag":85,"props":140,"children":142},{"class":87,"line":141},4,[143],{"type":23,"tag":85,"props":144,"children":145},{"emptyLinePlaceholder":102},[146],{"type":28,"value":105},{"type":23,"tag":85,"props":148,"children":150},{"class":87,"line":149},5,[151,156,161],{"type":23,"tag":85,"props":152,"children":153},{"style":112},[154],{"type":28,"value":155}," def",{"type":23,"tag":85,"props":157,"children":158},{"style":118},[159],{"type":28,"value":160}," save_time",{"type":23,"tag":85,"props":162,"children":163},{"style":124},[164],{"type":28,"value":165},"(self):\n",{"type":23,"tag":85,"props":167,"children":169},{"class":87,"line":168},6,[170],{"type":23,"tag":85,"props":171,"children":173},{"style":172},"--shiki-default:#032F62",[174],{"type":28,"value":175}," \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n",{"type":23,"tag":85,"props":177,"children":179},{"class":87,"line":178},7,[180],{"type":23,"tag":85,"props":181,"children":182},{"style":172},[183],{"type":28,"value":184}," \"\"\"\n",{"type":23,"tag":85,"props":186,"children":188},{"class":87,"line":187},8,[189,194,199,203,208,213,218,223,228],{"type":23,"tag":85,"props":190,"children":191},{"style":112},[192],{"type":28,"value":193}," with",{"type":23,"tag":85,"props":195,"children":196},{"style":130},[197],{"type":28,"value":198}," open",{"type":23,"tag":85,"props":200,"children":201},{"style":124},[202],{"type":28,"value":127},{"type":23,"tag":85,"props":204,"children":205},{"style":172},[206],{"type":28,"value":207},"\"LAST_KNOWN_TIME\"",{"type":23,"tag":85,"props":209,"children":210},{"style":124},[211],{"type":28,"value":212},", ",{"type":23,"tag":85,"props":214,"children":215},{"style":172},[216],{"type":28,"value":217},"\"w+\"",{"type":23,"tag":85,"props":219,"children":220},{"style":124},[221],{"type":28,"value":222},") ",{"type":23,"tag":85,"props":224,"children":225},{"style":112},[226],{"type":28,"value":227},"as",{"type":23,"tag":85,"props":229,"children":230},{"style":124},[231],{"type":28,"value":232}," f:\n",{"type":23,"tag":85,"props":234,"children":236},{"class":87,"line":235},9,[237,242,247],{"type":23,"tag":85,"props":238,"children":239},{"style":124},[240],{"type":28,"value":241}," f.write(",{"type":23,"tag":85,"props":243,"children":244},{"style":130},[245],{"type":28,"value":246},"str",{"type":23,"tag":85,"props":248,"children":249},{"style":124},[250],{"type":28,"value":251},"(utime.time()))\n",{"type":23,"tag":24,"props":253,"children":254},{},[255,257,262,264,269,271,276],{"type":28,"value":256},"First, because the ",{"type":23,"tag":59,"props":258,"children":260},{"className":259},[],[261],{"type":28,"value":72},{"type":28,"value":263}," module is not installed on the machine that the unit\ntests on, we must mock ",{"type":23,"tag":59,"props":265,"children":267},{"className":266},[],[268],{"type":28,"value":72},{"type":28,"value":270}," module before importing ",{"type":23,"tag":59,"props":272,"children":274},{"className":273},[],[275],{"type":28,"value":64},{"type":28,"value":277}," in our\nunit test file.",{"type":23,"tag":76,"props":279,"children":281},{"className":78,"code":280,"language":17,"meta":7,"style":7},"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger\n",[282],{"type":23,"tag":59,"props":283,"children":284},{"__ignoreMap":7},[285,293,300,313,320,342,349,377],{"type":23,"tag":85,"props":286,"children":287},{"class":87,"line":88},[288],{"type":23,"tag":85,"props":289,"children":290},{"style":92},[291],{"type":28,"value":292},"# test_time_logger.py\n",{"type":23,"tag":85,"props":294,"children":295},{"class":87,"line":98},[296],{"type":23,"tag":85,"props":297,"children":298},{"emptyLinePlaceholder":102},[299],{"type":28,"value":105},{"type":23,"tag":85,"props":301,"children":302},{"class":87,"line":108},[303,308],{"type":23,"tag":85,"props":304,"children":305},{"style":112},[306],{"type":28,"value":307},"import",{"type":23,"tag":85,"props":309,"children":310},{"style":124},[311],{"type":28,"value":312}," unittest\n",{"type":23,"tag":85,"props":314,"children":315},{"class":87,"line":141},[316],{"type":23,"tag":85,"props":317,"children":318},{"emptyLinePlaceholder":102},[319],{"type":28,"value":105},{"type":23,"tag":85,"props":321,"children":322},{"class":87,"line":149},[323,328,333,337],{"type":23,"tag":85,"props":324,"children":325},{"style":112},[326],{"type":28,"value":327},"from",{"type":23,"tag":85,"props":329,"children":330},{"style":124},[331],{"type":28,"value":332}," unittest.mock ",{"type":23,"tag":85,"props":334,"children":335},{"style":112},[336],{"type":28,"value":307},{"type":23,"tag":85,"props":338,"children":339},{"style":124},[340],{"type":28,"value":341}," MagicMock\n",{"type":23,"tag":85,"props":343,"children":344},{"class":87,"line":168},[345],{"type":23,"tag":85,"props":346,"children":347},{"emptyLinePlaceholder":102},[348],{"type":28,"value":105},{"type":23,"tag":85,"props":350,"children":351},{"class":87,"line":178},[352,357,362,367,372],{"type":23,"tag":85,"props":353,"children":354},{"style":124},[355],{"type":28,"value":356},"sys.modules[",{"type":23,"tag":85,"props":358,"children":359},{"style":172},[360],{"type":28,"value":361},"'utime'",{"type":23,"tag":85,"props":363,"children":364},{"style":124},[365],{"type":28,"value":366},"] ",{"type":23,"tag":85,"props":368,"children":369},{"style":112},[370],{"type":28,"value":371},"=",{"type":23,"tag":85,"props":373,"children":374},{"style":124},[375],{"type":28,"value":376}," MagicMock()\n",{"type":23,"tag":85,"props":378,"children":379},{"class":87,"line":187},[380,384,389,393],{"type":23,"tag":85,"props":381,"children":382},{"style":112},[383],{"type":28,"value":327},{"type":23,"tag":85,"props":385,"children":386},{"style":124},[387],{"type":28,"value":388}," time_logger ",{"type":23,"tag":85,"props":390,"children":391},{"style":112},[392],{"type":28,"value":307},{"type":23,"tag":85,"props":394,"children":395},{"style":124},[396],{"type":28,"value":397}," TimeLogger\n",{"type":23,"tag":24,"props":399,"children":400},{},[401,403,409,411,417],{"type":28,"value":402},"Then, we can write a test that patches the ",{"type":23,"tag":59,"props":404,"children":406},{"className":405},[],[407],{"type":28,"value":408},"utime.time",{"type":28,"value":410}," functionality so that\nit returns a value of our choosing -- in this case, ",{"type":23,"tag":59,"props":412,"children":414},{"className":413},[],[415],{"type":28,"value":416},"1234",{"type":28,"value":418},".",{"type":23,"tag":76,"props":420,"children":422},{"className":78,"code":421,"language":17,"meta":7,"style":7},"class TestTimeLogger(unittest.TestCase):\n\n def test_save_time(self):\n \"\"\" Verify that the Epoch time is written to file\n \"\"\"\n with unittest.mock.patch(\"utime.time\", return_value=1234):\n t = TimeLogger()\n t.save_time()\n with open(\"LAST_KNOWN_TIME\") as f:\n self.assertEqual(\"1234\", f.read())\n",[423],{"type":23,"tag":59,"props":424,"children":425},{"__ignoreMap":7},[426,460,467,483,491,498,537,554,562,594],{"type":23,"tag":85,"props":427,"children":428},{"class":87,"line":88},[429,433,438,442,447,451,456],{"type":23,"tag":85,"props":430,"children":431},{"style":112},[432],{"type":28,"value":115},{"type":23,"tag":85,"props":434,"children":435},{"style":118},[436],{"type":28,"value":437}," TestTimeLogger",{"type":23,"tag":85,"props":439,"children":440},{"style":124},[441],{"type":28,"value":127},{"type":23,"tag":85,"props":443,"children":444},{"style":118},[445],{"type":28,"value":446},"unittest",{"type":23,"tag":85,"props":448,"children":449},{"style":124},[450],{"type":28,"value":418},{"type":23,"tag":85,"props":452,"children":453},{"style":118},[454],{"type":28,"value":455},"TestCase",{"type":23,"tag":85,"props":457,"children":458},{"style":124},[459],{"type":28,"value":138},{"type":23,"tag":85,"props":461,"children":462},{"class":87,"line":98},[463],{"type":23,"tag":85,"props":464,"children":465},{"emptyLinePlaceholder":102},[466],{"type":28,"value":105},{"type":23,"tag":85,"props":468,"children":469},{"class":87,"line":108},[470,474,479],{"type":23,"tag":85,"props":471,"children":472},{"style":112},[473],{"type":28,"value":155},{"type":23,"tag":85,"props":475,"children":476},{"style":118},[477],{"type":28,"value":478}," test_save_time",{"type":23,"tag":85,"props":480,"children":481},{"style":124},[482],{"type":28,"value":165},{"type":23,"tag":85,"props":484,"children":485},{"class":87,"line":141},[486],{"type":23,"tag":85,"props":487,"children":488},{"style":172},[489],{"type":28,"value":490}," \"\"\" Verify that the Epoch time is written to file\n",{"type":23,"tag":85,"props":492,"children":493},{"class":87,"line":149},[494],{"type":23,"tag":85,"props":495,"children":496},{"style":172},[497],{"type":28,"value":184},{"type":23,"tag":85,"props":499,"children":500},{"class":87,"line":168},[501,505,510,515,519,525,529,533],{"type":23,"tag":85,"props":502,"children":503},{"style":112},[504],{"type":28,"value":193},{"type":23,"tag":85,"props":506,"children":507},{"style":124},[508],{"type":28,"value":509}," unittest.mock.patch(",{"type":23,"tag":85,"props":511,"children":512},{"style":172},[513],{"type":28,"value":514},"\"utime.time\"",{"type":23,"tag":85,"props":516,"children":517},{"style":124},[518],{"type":28,"value":212},{"type":23,"tag":85,"props":520,"children":522},{"style":521},"--shiki-default:#E36209",[523],{"type":28,"value":524},"return_value",{"type":23,"tag":85,"props":526,"children":527},{"style":112},[528],{"type":28,"value":371},{"type":23,"tag":85,"props":530,"children":531},{"style":130},[532],{"type":28,"value":416},{"type":23,"tag":85,"props":534,"children":535},{"style":124},[536],{"type":28,"value":138},{"type":23,"tag":85,"props":538,"children":539},{"class":87,"line":178},[540,545,549],{"type":23,"tag":85,"props":541,"children":542},{"style":124},[543],{"type":28,"value":544}," t ",{"type":23,"tag":85,"props":546,"children":547},{"style":112},[548],{"type":28,"value":371},{"type":23,"tag":85,"props":550,"children":551},{"style":124},[552],{"type":28,"value":553}," TimeLogger()\n",{"type":23,"tag":85,"props":555,"children":556},{"class":87,"line":187},[557],{"type":23,"tag":85,"props":558,"children":559},{"style":124},[560],{"type":28,"value":561}," t.save_time()\n",{"type":23,"tag":85,"props":563,"children":564},{"class":87,"line":235},[565,570,574,578,582,586,590],{"type":23,"tag":85,"props":566,"children":567},{"style":112},[568],{"type":28,"value":569}," with",{"type":23,"tag":85,"props":571,"children":572},{"style":130},[573],{"type":28,"value":198},{"type":23,"tag":85,"props":575,"children":576},{"style":124},[577],{"type":28,"value":127},{"type":23,"tag":85,"props":579,"children":580},{"style":172},[581],{"type":28,"value":207},{"type":23,"tag":85,"props":583,"children":584},{"style":124},[585],{"type":28,"value":222},{"type":23,"tag":85,"props":587,"children":588},{"style":112},[589],{"type":28,"value":227},{"type":23,"tag":85,"props":591,"children":592},{"style":124},[593],{"type":28,"value":232},{"type":23,"tag":85,"props":595,"children":597},{"class":87,"line":596},10,[598,603,608,613],{"type":23,"tag":85,"props":599,"children":600},{"style":130},[601],{"type":28,"value":602}," self",{"type":23,"tag":85,"props":604,"children":605},{"style":124},[606],{"type":28,"value":607},".assertEqual(",{"type":23,"tag":85,"props":609,"children":610},{"style":172},[611],{"type":28,"value":612},"\"1234\"",{"type":23,"tag":85,"props":614,"children":615},{"style":124},[616],{"type":28,"value":617},", f.read())\n",{"type":23,"tag":24,"props":619,"children":620},{},[621,623,629,631,637,639,644],{"type":28,"value":622},"Now, when the ",{"type":23,"tag":59,"props":624,"children":626},{"className":625},[],[627],{"type":28,"value":628},"save_time",{"type":28,"value":630}," method gets the latest time from ",{"type":23,"tag":59,"props":632,"children":634},{"className":633},[],[635],{"type":28,"value":636},"utime.time()",{"type":28,"value":638},", the\nvalue will be patched to return ",{"type":23,"tag":59,"props":640,"children":642},{"className":641},[],[643],{"type":28,"value":416},{"type":28,"value":645},". That value will be written to a file,\nand our unit test will pass!",{"type":23,"tag":647,"props":648,"children":650},"h2",{"id":649},"references",[651],{"type":28,"value":652},"References",{"type":23,"tag":654,"props":655,"children":656},"ol",{},[657],{"type":23,"tag":658,"props":659,"children":660},"li",{},[661],{"type":23,"tag":662,"props":663,"children":667},"a",{"href":664,"rel":665},"https://docs.python.org/3/library/unittest.html",[666],"nofollow",[668,673],{"type":23,"tag":59,"props":669,"children":671},{"className":670},[],[672],{"type":28,"value":446},{"type":28,"value":674}," — Unit testing framework",{"type":23,"tag":676,"props":677,"children":678},"style",{},[679],{"type":28,"value":680},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":98,"depth":98,"links":682},[683],{"id":649,"depth":98,"text":652},"markdown","content:articles:unit-testing-micropython-with-mocks.md","content","articles/unit-testing-micropython-with-mocks.md","md",1718891181770] \ No newline at end of file +[{"data":1,"prerenderedAt":690},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"draft":6,"tags":11,"categories":16,"excerpt":19,"body":29,"_type":684,"_id":685,"_source":686,"_file":687,"_stem":688,"_extension":689},"/articles/unit-testing-micropython-with-mocks","articles",false,"","Unit Testing in MicroPython with Mocks","Unit testing code for embedded systems can be challenging. While it's possible\nto leverage emulators, write side-effect free code, or run tests on the\nhardware itself, it's often easiest to unit test the code on your personal\ncomputer with mocked hardware functionality.","2020-02-07",[12,13,14,15],"micropython","testing","mocks","tutorial",[17,18],"python","embedded",{"type":20,"children":21},"root",[22],{"type":23,"tag":24,"props":25,"children":26},"element","p",{},[27],{"type":28,"value":9},"text",{"type":20,"children":30,"toc":681},[31,35,42,47,53,75,252,278,398,419,618,646,653,675],{"type":23,"tag":24,"props":32,"children":33},{},[34],{"type":28,"value":9},{"type":23,"tag":36,"props":37,"children":39},"h1",{"id":38},"mocking",[40],{"type":28,"value":41},"Mocking",{"type":23,"tag":24,"props":43,"children":44},{},[45],{"type":28,"value":46},"Mocks allow us to replace the hardware interfacing functionality under-the-hood\nwith predefined results and side-effects. For example, if there is a piece of\nlogic that retrieves values from an accelerometer to get a device's\norientation, it would be possible to mock the returned values of the\naccelerometer -- allowing us to run the unit tests on a device that does not\nhave an accelerometer sensor installed.",{"type":23,"tag":36,"props":48,"children":50},{"id":49},"a-micropython-mocking-example",[51],{"type":28,"value":52},"A MicroPython Mocking Example",{"type":23,"tag":24,"props":54,"children":55},{},[56,58,65,67,73],{"type":28,"value":57},"In this example, we will be unit testing a module named ",{"type":23,"tag":59,"props":60,"children":62},"code",{"className":61},[],[63],{"type":28,"value":64},"time_logger",{"type":28,"value":66},", that\ndepends on the MicroPython library ",{"type":23,"tag":59,"props":68,"children":70},{"className":69},[],[71],{"type":28,"value":72},"utime",{"type":28,"value":74}," to log the most recent Epoch time to\na file.",{"type":23,"tag":76,"props":77,"children":80},"pre",{"className":78,"code":79,"language":17,"meta":7,"style":7},"language-python shiki shiki-themes github-light","# time_logger.py\n\nclass TimeLogger(object):\n\n def save_time(self):\n \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n \"\"\"\n with open(\"LAST_KNOWN_TIME\", \"w+\") as f:\n f.write(str(utime.time()))\n",[81],{"type":23,"tag":59,"props":82,"children":83},{"__ignoreMap":7},[84,96,106,139,147,166,176,185,233],{"type":23,"tag":85,"props":86,"children":89},"span",{"class":87,"line":88},"line",1,[90],{"type":23,"tag":85,"props":91,"children":93},{"style":92},"--shiki-default:#6A737D",[94],{"type":28,"value":95},"# time_logger.py\n",{"type":23,"tag":85,"props":97,"children":99},{"class":87,"line":98},2,[100],{"type":23,"tag":85,"props":101,"children":103},{"emptyLinePlaceholder":102},true,[104],{"type":28,"value":105},"\n",{"type":23,"tag":85,"props":107,"children":109},{"class":87,"line":108},3,[110,116,122,128,134],{"type":23,"tag":85,"props":111,"children":113},{"style":112},"--shiki-default:#D73A49",[114],{"type":28,"value":115},"class",{"type":23,"tag":85,"props":117,"children":119},{"style":118},"--shiki-default:#6F42C1",[120],{"type":28,"value":121}," TimeLogger",{"type":23,"tag":85,"props":123,"children":125},{"style":124},"--shiki-default:#24292E",[126],{"type":28,"value":127},"(",{"type":23,"tag":85,"props":129,"children":131},{"style":130},"--shiki-default:#005CC5",[132],{"type":28,"value":133},"object",{"type":23,"tag":85,"props":135,"children":136},{"style":124},[137],{"type":28,"value":138},"):\n",{"type":23,"tag":85,"props":140,"children":142},{"class":87,"line":141},4,[143],{"type":23,"tag":85,"props":144,"children":145},{"emptyLinePlaceholder":102},[146],{"type":28,"value":105},{"type":23,"tag":85,"props":148,"children":150},{"class":87,"line":149},5,[151,156,161],{"type":23,"tag":85,"props":152,"children":153},{"style":112},[154],{"type":28,"value":155}," def",{"type":23,"tag":85,"props":157,"children":158},{"style":118},[159],{"type":28,"value":160}," save_time",{"type":23,"tag":85,"props":162,"children":163},{"style":124},[164],{"type":28,"value":165},"(self):\n",{"type":23,"tag":85,"props":167,"children":169},{"class":87,"line":168},6,[170],{"type":23,"tag":85,"props":171,"children":173},{"style":172},"--shiki-default:#032F62",[174],{"type":28,"value":175}," \"\"\" Overwrite a file with the most recent Epoch timestamp from `utime`\n",{"type":23,"tag":85,"props":177,"children":179},{"class":87,"line":178},7,[180],{"type":23,"tag":85,"props":181,"children":182},{"style":172},[183],{"type":28,"value":184}," \"\"\"\n",{"type":23,"tag":85,"props":186,"children":188},{"class":87,"line":187},8,[189,194,199,203,208,213,218,223,228],{"type":23,"tag":85,"props":190,"children":191},{"style":112},[192],{"type":28,"value":193}," with",{"type":23,"tag":85,"props":195,"children":196},{"style":130},[197],{"type":28,"value":198}," open",{"type":23,"tag":85,"props":200,"children":201},{"style":124},[202],{"type":28,"value":127},{"type":23,"tag":85,"props":204,"children":205},{"style":172},[206],{"type":28,"value":207},"\"LAST_KNOWN_TIME\"",{"type":23,"tag":85,"props":209,"children":210},{"style":124},[211],{"type":28,"value":212},", ",{"type":23,"tag":85,"props":214,"children":215},{"style":172},[216],{"type":28,"value":217},"\"w+\"",{"type":23,"tag":85,"props":219,"children":220},{"style":124},[221],{"type":28,"value":222},") ",{"type":23,"tag":85,"props":224,"children":225},{"style":112},[226],{"type":28,"value":227},"as",{"type":23,"tag":85,"props":229,"children":230},{"style":124},[231],{"type":28,"value":232}," f:\n",{"type":23,"tag":85,"props":234,"children":236},{"class":87,"line":235},9,[237,242,247],{"type":23,"tag":85,"props":238,"children":239},{"style":124},[240],{"type":28,"value":241}," f.write(",{"type":23,"tag":85,"props":243,"children":244},{"style":130},[245],{"type":28,"value":246},"str",{"type":23,"tag":85,"props":248,"children":249},{"style":124},[250],{"type":28,"value":251},"(utime.time()))\n",{"type":23,"tag":24,"props":253,"children":254},{},[255,257,262,264,269,271,276],{"type":28,"value":256},"First, because the ",{"type":23,"tag":59,"props":258,"children":260},{"className":259},[],[261],{"type":28,"value":72},{"type":28,"value":263}," module is not installed on the machine that the unit\ntests on, we must mock ",{"type":23,"tag":59,"props":265,"children":267},{"className":266},[],[268],{"type":28,"value":72},{"type":28,"value":270}," module before importing ",{"type":23,"tag":59,"props":272,"children":274},{"className":273},[],[275],{"type":28,"value":64},{"type":28,"value":277}," in our\nunit test file.",{"type":23,"tag":76,"props":279,"children":281},{"className":78,"code":280,"language":17,"meta":7,"style":7},"# test_time_logger.py\n\nimport unittest\n\nfrom unittest.mock import MagicMock\n\nsys.modules['utime'] = MagicMock()\nfrom time_logger import TimeLogger\n",[282],{"type":23,"tag":59,"props":283,"children":284},{"__ignoreMap":7},[285,293,300,313,320,342,349,377],{"type":23,"tag":85,"props":286,"children":287},{"class":87,"line":88},[288],{"type":23,"tag":85,"props":289,"children":290},{"style":92},[291],{"type":28,"value":292},"# test_time_logger.py\n",{"type":23,"tag":85,"props":294,"children":295},{"class":87,"line":98},[296],{"type":23,"tag":85,"props":297,"children":298},{"emptyLinePlaceholder":102},[299],{"type":28,"value":105},{"type":23,"tag":85,"props":301,"children":302},{"class":87,"line":108},[303,308],{"type":23,"tag":85,"props":304,"children":305},{"style":112},[306],{"type":28,"value":307},"import",{"type":23,"tag":85,"props":309,"children":310},{"style":124},[311],{"type":28,"value":312}," unittest\n",{"type":23,"tag":85,"props":314,"children":315},{"class":87,"line":141},[316],{"type":23,"tag":85,"props":317,"children":318},{"emptyLinePlaceholder":102},[319],{"type":28,"value":105},{"type":23,"tag":85,"props":321,"children":322},{"class":87,"line":149},[323,328,333,337],{"type":23,"tag":85,"props":324,"children":325},{"style":112},[326],{"type":28,"value":327},"from",{"type":23,"tag":85,"props":329,"children":330},{"style":124},[331],{"type":28,"value":332}," unittest.mock ",{"type":23,"tag":85,"props":334,"children":335},{"style":112},[336],{"type":28,"value":307},{"type":23,"tag":85,"props":338,"children":339},{"style":124},[340],{"type":28,"value":341}," MagicMock\n",{"type":23,"tag":85,"props":343,"children":344},{"class":87,"line":168},[345],{"type":23,"tag":85,"props":346,"children":347},{"emptyLinePlaceholder":102},[348],{"type":28,"value":105},{"type":23,"tag":85,"props":350,"children":351},{"class":87,"line":178},[352,357,362,367,372],{"type":23,"tag":85,"props":353,"children":354},{"style":124},[355],{"type":28,"value":356},"sys.modules[",{"type":23,"tag":85,"props":358,"children":359},{"style":172},[360],{"type":28,"value":361},"'utime'",{"type":23,"tag":85,"props":363,"children":364},{"style":124},[365],{"type":28,"value":366},"] ",{"type":23,"tag":85,"props":368,"children":369},{"style":112},[370],{"type":28,"value":371},"=",{"type":23,"tag":85,"props":373,"children":374},{"style":124},[375],{"type":28,"value":376}," MagicMock()\n",{"type":23,"tag":85,"props":378,"children":379},{"class":87,"line":187},[380,384,389,393],{"type":23,"tag":85,"props":381,"children":382},{"style":112},[383],{"type":28,"value":327},{"type":23,"tag":85,"props":385,"children":386},{"style":124},[387],{"type":28,"value":388}," time_logger ",{"type":23,"tag":85,"props":390,"children":391},{"style":112},[392],{"type":28,"value":307},{"type":23,"tag":85,"props":394,"children":395},{"style":124},[396],{"type":28,"value":397}," TimeLogger\n",{"type":23,"tag":24,"props":399,"children":400},{},[401,403,409,411,417],{"type":28,"value":402},"Then, we can write a test that patches the ",{"type":23,"tag":59,"props":404,"children":406},{"className":405},[],[407],{"type":28,"value":408},"utime.time",{"type":28,"value":410}," functionality so that\nit returns a value of our choosing -- in this case, ",{"type":23,"tag":59,"props":412,"children":414},{"className":413},[],[415],{"type":28,"value":416},"1234",{"type":28,"value":418},".",{"type":23,"tag":76,"props":420,"children":422},{"className":78,"code":421,"language":17,"meta":7,"style":7},"class TestTimeLogger(unittest.TestCase):\n\n def test_save_time(self):\n \"\"\" Verify that the Epoch time is written to file\n \"\"\"\n with unittest.mock.patch(\"utime.time\", return_value=1234):\n t = TimeLogger()\n t.save_time()\n with open(\"LAST_KNOWN_TIME\") as f:\n self.assertEqual(\"1234\", f.read())\n",[423],{"type":23,"tag":59,"props":424,"children":425},{"__ignoreMap":7},[426,460,467,483,491,498,537,554,562,594],{"type":23,"tag":85,"props":427,"children":428},{"class":87,"line":88},[429,433,438,442,447,451,456],{"type":23,"tag":85,"props":430,"children":431},{"style":112},[432],{"type":28,"value":115},{"type":23,"tag":85,"props":434,"children":435},{"style":118},[436],{"type":28,"value":437}," TestTimeLogger",{"type":23,"tag":85,"props":439,"children":440},{"style":124},[441],{"type":28,"value":127},{"type":23,"tag":85,"props":443,"children":444},{"style":118},[445],{"type":28,"value":446},"unittest",{"type":23,"tag":85,"props":448,"children":449},{"style":124},[450],{"type":28,"value":418},{"type":23,"tag":85,"props":452,"children":453},{"style":118},[454],{"type":28,"value":455},"TestCase",{"type":23,"tag":85,"props":457,"children":458},{"style":124},[459],{"type":28,"value":138},{"type":23,"tag":85,"props":461,"children":462},{"class":87,"line":98},[463],{"type":23,"tag":85,"props":464,"children":465},{"emptyLinePlaceholder":102},[466],{"type":28,"value":105},{"type":23,"tag":85,"props":468,"children":469},{"class":87,"line":108},[470,474,479],{"type":23,"tag":85,"props":471,"children":472},{"style":112},[473],{"type":28,"value":155},{"type":23,"tag":85,"props":475,"children":476},{"style":118},[477],{"type":28,"value":478}," test_save_time",{"type":23,"tag":85,"props":480,"children":481},{"style":124},[482],{"type":28,"value":165},{"type":23,"tag":85,"props":484,"children":485},{"class":87,"line":141},[486],{"type":23,"tag":85,"props":487,"children":488},{"style":172},[489],{"type":28,"value":490}," \"\"\" Verify that the Epoch time is written to file\n",{"type":23,"tag":85,"props":492,"children":493},{"class":87,"line":149},[494],{"type":23,"tag":85,"props":495,"children":496},{"style":172},[497],{"type":28,"value":184},{"type":23,"tag":85,"props":499,"children":500},{"class":87,"line":168},[501,505,510,515,519,525,529,533],{"type":23,"tag":85,"props":502,"children":503},{"style":112},[504],{"type":28,"value":193},{"type":23,"tag":85,"props":506,"children":507},{"style":124},[508],{"type":28,"value":509}," unittest.mock.patch(",{"type":23,"tag":85,"props":511,"children":512},{"style":172},[513],{"type":28,"value":514},"\"utime.time\"",{"type":23,"tag":85,"props":516,"children":517},{"style":124},[518],{"type":28,"value":212},{"type":23,"tag":85,"props":520,"children":522},{"style":521},"--shiki-default:#E36209",[523],{"type":28,"value":524},"return_value",{"type":23,"tag":85,"props":526,"children":527},{"style":112},[528],{"type":28,"value":371},{"type":23,"tag":85,"props":530,"children":531},{"style":130},[532],{"type":28,"value":416},{"type":23,"tag":85,"props":534,"children":535},{"style":124},[536],{"type":28,"value":138},{"type":23,"tag":85,"props":538,"children":539},{"class":87,"line":178},[540,545,549],{"type":23,"tag":85,"props":541,"children":542},{"style":124},[543],{"type":28,"value":544}," t ",{"type":23,"tag":85,"props":546,"children":547},{"style":112},[548],{"type":28,"value":371},{"type":23,"tag":85,"props":550,"children":551},{"style":124},[552],{"type":28,"value":553}," TimeLogger()\n",{"type":23,"tag":85,"props":555,"children":556},{"class":87,"line":187},[557],{"type":23,"tag":85,"props":558,"children":559},{"style":124},[560],{"type":28,"value":561}," t.save_time()\n",{"type":23,"tag":85,"props":563,"children":564},{"class":87,"line":235},[565,570,574,578,582,586,590],{"type":23,"tag":85,"props":566,"children":567},{"style":112},[568],{"type":28,"value":569}," with",{"type":23,"tag":85,"props":571,"children":572},{"style":130},[573],{"type":28,"value":198},{"type":23,"tag":85,"props":575,"children":576},{"style":124},[577],{"type":28,"value":127},{"type":23,"tag":85,"props":579,"children":580},{"style":172},[581],{"type":28,"value":207},{"type":23,"tag":85,"props":583,"children":584},{"style":124},[585],{"type":28,"value":222},{"type":23,"tag":85,"props":587,"children":588},{"style":112},[589],{"type":28,"value":227},{"type":23,"tag":85,"props":591,"children":592},{"style":124},[593],{"type":28,"value":232},{"type":23,"tag":85,"props":595,"children":597},{"class":87,"line":596},10,[598,603,608,613],{"type":23,"tag":85,"props":599,"children":600},{"style":130},[601],{"type":28,"value":602}," self",{"type":23,"tag":85,"props":604,"children":605},{"style":124},[606],{"type":28,"value":607},".assertEqual(",{"type":23,"tag":85,"props":609,"children":610},{"style":172},[611],{"type":28,"value":612},"\"1234\"",{"type":23,"tag":85,"props":614,"children":615},{"style":124},[616],{"type":28,"value":617},", f.read())\n",{"type":23,"tag":24,"props":619,"children":620},{},[621,623,629,631,637,639,644],{"type":28,"value":622},"Now, when the ",{"type":23,"tag":59,"props":624,"children":626},{"className":625},[],[627],{"type":28,"value":628},"save_time",{"type":28,"value":630}," method gets the latest time from ",{"type":23,"tag":59,"props":632,"children":634},{"className":633},[],[635],{"type":28,"value":636},"utime.time()",{"type":28,"value":638},", the\nvalue will be patched to return ",{"type":23,"tag":59,"props":640,"children":642},{"className":641},[],[643],{"type":28,"value":416},{"type":28,"value":645},". That value will be written to a file,\nand our unit test will pass!",{"type":23,"tag":647,"props":648,"children":650},"h2",{"id":649},"references",[651],{"type":28,"value":652},"References",{"type":23,"tag":654,"props":655,"children":656},"ol",{},[657],{"type":23,"tag":658,"props":659,"children":660},"li",{},[661],{"type":23,"tag":662,"props":663,"children":667},"a",{"href":664,"rel":665},"https://docs.python.org/3/library/unittest.html",[666],"nofollow",[668,673],{"type":23,"tag":59,"props":669,"children":671},{"className":670},[],[672],{"type":28,"value":446},{"type":28,"value":674}," — Unit testing framework",{"type":23,"tag":676,"props":677,"children":678},"style",{},[679],{"type":28,"value":680},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":98,"depth":98,"links":682},[683],{"id":649,"depth":98,"text":652},"markdown","content:articles:unit-testing-micropython-with-mocks.md","content","articles/unit-testing-micropython-with-mocks.md","articles/unit-testing-micropython-with-mocks","md",1720229315499] \ No newline at end of file diff --git a/articles/unit-testing-micropython-with-mocks/index.html b/articles/unit-testing-micropython-with-mocks/index.html index e178e2ed..7bdbf67f 100644 --- a/articles/unit-testing-micropython-with-mocks/index.html +++ b/articles/unit-testing-micropython-with-mocks/index.html @@ -4,35 +4,36 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - - - - -

            Unit Testing in MicroPython with Mocks

            2020-02-07

            Unit testing code for embedded systems can be challenging. While it's possible + + + + + + + + + + + + + + + + +

            Unit Testing in MicroPython with Mocks

            Unit testing code for embedded systems can be challenging. While it's possible to leverage emulators, write side-effect free code, or run tests on the hardware itself, it's often easiest to unit test the code on your personal computer with mocked hardware functionality.

            Mocking

            Mocks allow us to replace the hardware interfacing functionality under-the-hood @@ -74,5 +75,5 @@ self.assertEqual("1234", f.read())

            Now, when the save_time method gets the latest time from utime.time(), the value will be patched to return 1234. That value will be written to a file, -and our unit test will pass!

            References

            1. unittest — Unit testing framework
            - \ No newline at end of file +and our unit test will pass!

            References

            1. unittest — Unit testing framework
            + \ No newline at end of file diff --git a/articles/vim-fugitive-gpg-pinentry/_payload.json b/articles/vim-fugitive-gpg-pinentry/_payload.json index 316f5970..53b77ae5 100644 --- a/articles/vim-fugitive-gpg-pinentry/_payload.json +++ b/articles/vim-fugitive-gpg-pinentry/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":328},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"excerpt":17,"body":56,"_type":323,"_id":324,"_source":325,"_file":326,"_extension":327},"/articles/vim-fugitive-gpg-pinentry","articles",false,"","Using pinentry-mac to sign commits from vim-fugitive","In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","2024-05-11",[12,13],"vim","tip",[15,16],"tooling","tips",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,28,37,39,46,48,54],{"type":26,"value":27},"text","In order to sign git commits from within Vim using a plugin like ",{"type":21,"tag":29,"props":30,"children":34},"a",{"href":31,"rel":32},"https://github.com/tpope/vim-fugitive",[33],"nofollow",[35],{"type":26,"value":36},"tpope/vim-fugitive",{"type":26,"value":38},", it is necessary to configure the ",{"type":21,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":26,"value":45},"gpg-agent",{"type":26,"value":47}," to use a GUI based ",{"type":21,"tag":40,"props":49,"children":51},{"className":50},[],[52],{"type":26,"value":53},"pinentry-program",{"type":26,"value":55},".",{"type":18,"children":57,"toc":319},[58,80,87,129,135,140,178,198,206,218,250,255,308,313],{"type":21,"tag":22,"props":59,"children":60},{},[61,62,67,68,73,74,79],{"type":26,"value":27},{"type":21,"tag":29,"props":63,"children":65},{"href":31,"rel":64},[33],[66],{"type":26,"value":36},{"type":26,"value":38},{"type":21,"tag":40,"props":69,"children":71},{"className":70},[],[72],{"type":26,"value":45},{"type":26,"value":47},{"type":21,"tag":40,"props":75,"children":77},{"className":76},[],[78],{"type":26,"value":53},{"type":26,"value":55},{"type":21,"tag":81,"props":82,"children":84},"h2",{"id":83},"preface",[85],{"type":26,"value":86},"Preface",{"type":21,"tag":22,"props":88,"children":89},{},[90,92,99,101,106,107,112,114,120,122,128],{"type":26,"value":91},"The man, the myth, the legend, Timothy Popallopollis himself ",{"type":21,"tag":29,"props":93,"children":96},{"href":94,"rel":95},"https://github.com/tpope/vim-fugitive/issues/846#issuecomment-253816577",[33],[97],{"type":26,"value":98},"recommends",{"type":26,"value":100}," configuring your ",{"type":21,"tag":40,"props":102,"children":104},{"className":103},[],[105],{"type":26,"value":45},{"type":26,"value":47},{"type":21,"tag":40,"props":108,"children":110},{"className":109},[],[111],{"type":26,"value":53},{"type":26,"value":113},". On macOS this can be done quite by simply installing ",{"type":21,"tag":40,"props":115,"children":117},{"className":116},[],[118],{"type":26,"value":119},"pinentry-mac",{"type":26,"value":121},", and updating your ",{"type":21,"tag":40,"props":123,"children":125},{"className":124},[],[126],{"type":26,"value":127},"gpg-agent.conf",{"type":26,"value":55},{"type":21,"tag":81,"props":130,"children":132},{"id":131},"configuration",[133],{"type":26,"value":134},"Configuration",{"type":21,"tag":22,"props":136,"children":137},{},[138],{"type":26,"value":139},"First things first, let's install the pinentry program.",{"type":21,"tag":141,"props":142,"children":146},"pre",{"code":143,"language":144,"meta":7,"className":145,"style":7},"$ brew install pinentry-mac\n","bash","language-bash shiki shiki-themes github-light",[147],{"type":21,"tag":40,"props":148,"children":149},{"__ignoreMap":7},[150],{"type":21,"tag":151,"props":152,"children":155},"span",{"class":153,"line":154},"line",1,[156,162,168,173],{"type":21,"tag":151,"props":157,"children":159},{"style":158},"--shiki-default:#6F42C1",[160],{"type":26,"value":161},"$",{"type":21,"tag":151,"props":163,"children":165},{"style":164},"--shiki-default:#032F62",[166],{"type":26,"value":167}," brew",{"type":21,"tag":151,"props":169,"children":170},{"style":164},[171],{"type":26,"value":172}," install",{"type":21,"tag":151,"props":174,"children":175},{"style":164},[176],{"type":26,"value":177}," pinentry-mac\n",{"type":21,"tag":22,"props":179,"children":180},{},[181,183,188,190,196],{"type":26,"value":182},"Then, all we need to do is set the ",{"type":21,"tag":40,"props":184,"children":186},{"className":185},[],[187],{"type":26,"value":53},{"type":26,"value":189}," option in your ",{"type":21,"tag":40,"props":191,"children":193},{"className":192},[],[194],{"type":26,"value":195},"~/.gnupg/gpg-agent.conf",{"type":26,"value":197}," file.",{"type":21,"tag":141,"props":199,"children":201},{"code":200},"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n",[202],{"type":21,"tag":40,"props":203,"children":204},{"__ignoreMap":7},[205],{"type":26,"value":200},{"type":21,"tag":22,"props":207,"children":208},{},[209,211,217],{"type":26,"value":210},"If your don't know the path to your pinentry program, you can throw down a quick ",{"type":21,"tag":40,"props":212,"children":214},{"className":213},[],[215],{"type":26,"value":216},"which",{"type":26,"value":55},{"type":21,"tag":141,"props":219,"children":221},{"code":220,"language":144,"meta":7,"className":145,"style":7},"$ which pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n",[222],{"type":21,"tag":40,"props":223,"children":224},{"__ignoreMap":7},[225,241],{"type":21,"tag":151,"props":226,"children":227},{"class":153,"line":154},[228,232,237],{"type":21,"tag":151,"props":229,"children":230},{"style":158},[231],{"type":26,"value":161},{"type":21,"tag":151,"props":233,"children":234},{"style":164},[235],{"type":26,"value":236}," which",{"type":21,"tag":151,"props":238,"children":239},{"style":164},[240],{"type":26,"value":177},{"type":21,"tag":151,"props":242,"children":244},{"class":153,"line":243},2,[245],{"type":21,"tag":151,"props":246,"children":247},{"style":158},[248],{"type":26,"value":249},"/opt/homebrew/bin/pinentry-mac\n",{"type":21,"tag":22,"props":251,"children":252},{},[253],{"type":26,"value":254},"Or use your Homebrew prefix.",{"type":21,"tag":141,"props":256,"children":258},{"code":257,"language":144,"meta":7,"className":145,"style":7},"$ echo $(brew --prefix)/bin/pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n",[259],{"type":21,"tag":40,"props":260,"children":261},{"__ignoreMap":7},[262,301],{"type":21,"tag":151,"props":263,"children":264},{"class":153,"line":154},[265,269,274,280,285,291,296],{"type":21,"tag":151,"props":266,"children":267},{"style":158},[268],{"type":26,"value":161},{"type":21,"tag":151,"props":270,"children":271},{"style":164},[272],{"type":26,"value":273}," echo",{"type":21,"tag":151,"props":275,"children":277},{"style":276},"--shiki-default:#24292E",[278],{"type":26,"value":279}," $(",{"type":21,"tag":151,"props":281,"children":282},{"style":158},[283],{"type":26,"value":284},"brew",{"type":21,"tag":151,"props":286,"children":288},{"style":287},"--shiki-default:#005CC5",[289],{"type":26,"value":290}," --prefix",{"type":21,"tag":151,"props":292,"children":293},{"style":276},[294],{"type":26,"value":295},")",{"type":21,"tag":151,"props":297,"children":298},{"style":164},[299],{"type":26,"value":300},"/bin/pinentry-mac\n",{"type":21,"tag":151,"props":302,"children":303},{"class":153,"line":243},[304],{"type":21,"tag":151,"props":305,"children":306},{"style":158},[307],{"type":26,"value":249},{"type":21,"tag":22,"props":309,"children":310},{},[311],{"type":26,"value":312},"But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim.",{"type":21,"tag":314,"props":315,"children":316},"style",{},[317],{"type":26,"value":318},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":243,"depth":243,"links":320},[321,322],{"id":83,"depth":243,"text":86},{"id":131,"depth":243,"text":134},"markdown","content:articles:vim-fugitive-gpg-pinentry.md","content","articles/vim-fugitive-gpg-pinentry.md","md",1718891181715] \ No newline at end of file +[{"data":1,"prerenderedAt":329},["Reactive",2],{"page-data":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"draft":6,"date":10,"tags":11,"categories":14,"excerpt":17,"body":56,"_type":323,"_id":324,"_source":325,"_file":326,"_stem":327,"_extension":328},"/articles/vim-fugitive-gpg-pinentry","articles",false,"","Using pinentry-mac to sign commits from vim-fugitive","In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.","2024-05-11",[12,13],"vim","tip",[15,16],"tooling","tips",{"type":18,"children":19},"root",[20],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,28,37,39,46,48,54],{"type":26,"value":27},"text","In order to sign git commits from within Vim using a plugin like ",{"type":21,"tag":29,"props":30,"children":34},"a",{"href":31,"rel":32},"https://github.com/tpope/vim-fugitive",[33],"nofollow",[35],{"type":26,"value":36},"tpope/vim-fugitive",{"type":26,"value":38},", it is necessary to configure the ",{"type":21,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":26,"value":45},"gpg-agent",{"type":26,"value":47}," to use a GUI based ",{"type":21,"tag":40,"props":49,"children":51},{"className":50},[],[52],{"type":26,"value":53},"pinentry-program",{"type":26,"value":55},".",{"type":18,"children":57,"toc":319},[58,80,87,129,135,140,178,198,206,218,250,255,308,313],{"type":21,"tag":22,"props":59,"children":60},{},[61,62,67,68,73,74,79],{"type":26,"value":27},{"type":21,"tag":29,"props":63,"children":65},{"href":31,"rel":64},[33],[66],{"type":26,"value":36},{"type":26,"value":38},{"type":21,"tag":40,"props":69,"children":71},{"className":70},[],[72],{"type":26,"value":45},{"type":26,"value":47},{"type":21,"tag":40,"props":75,"children":77},{"className":76},[],[78],{"type":26,"value":53},{"type":26,"value":55},{"type":21,"tag":81,"props":82,"children":84},"h2",{"id":83},"preface",[85],{"type":26,"value":86},"Preface",{"type":21,"tag":22,"props":88,"children":89},{},[90,92,99,101,106,107,112,114,120,122,128],{"type":26,"value":91},"The man, the myth, the legend, Timothy Popallopollis himself ",{"type":21,"tag":29,"props":93,"children":96},{"href":94,"rel":95},"https://github.com/tpope/vim-fugitive/issues/846#issuecomment-253816577",[33],[97],{"type":26,"value":98},"recommends",{"type":26,"value":100}," configuring your ",{"type":21,"tag":40,"props":102,"children":104},{"className":103},[],[105],{"type":26,"value":45},{"type":26,"value":47},{"type":21,"tag":40,"props":108,"children":110},{"className":109},[],[111],{"type":26,"value":53},{"type":26,"value":113},". On macOS this can be done quite by simply installing ",{"type":21,"tag":40,"props":115,"children":117},{"className":116},[],[118],{"type":26,"value":119},"pinentry-mac",{"type":26,"value":121},", and updating your ",{"type":21,"tag":40,"props":123,"children":125},{"className":124},[],[126],{"type":26,"value":127},"gpg-agent.conf",{"type":26,"value":55},{"type":21,"tag":81,"props":130,"children":132},{"id":131},"configuration",[133],{"type":26,"value":134},"Configuration",{"type":21,"tag":22,"props":136,"children":137},{},[138],{"type":26,"value":139},"First things first, let's install the pinentry program.",{"type":21,"tag":141,"props":142,"children":146},"pre",{"code":143,"language":144,"meta":7,"className":145,"style":7},"$ brew install pinentry-mac\n","bash","language-bash shiki shiki-themes github-light",[147],{"type":21,"tag":40,"props":148,"children":149},{"__ignoreMap":7},[150],{"type":21,"tag":151,"props":152,"children":155},"span",{"class":153,"line":154},"line",1,[156,162,168,173],{"type":21,"tag":151,"props":157,"children":159},{"style":158},"--shiki-default:#6F42C1",[160],{"type":26,"value":161},"$",{"type":21,"tag":151,"props":163,"children":165},{"style":164},"--shiki-default:#032F62",[166],{"type":26,"value":167}," brew",{"type":21,"tag":151,"props":169,"children":170},{"style":164},[171],{"type":26,"value":172}," install",{"type":21,"tag":151,"props":174,"children":175},{"style":164},[176],{"type":26,"value":177}," pinentry-mac\n",{"type":21,"tag":22,"props":179,"children":180},{},[181,183,188,190,196],{"type":26,"value":182},"Then, all we need to do is set the ",{"type":21,"tag":40,"props":184,"children":186},{"className":185},[],[187],{"type":26,"value":53},{"type":26,"value":189}," option in your ",{"type":21,"tag":40,"props":191,"children":193},{"className":192},[],[194],{"type":26,"value":195},"~/.gnupg/gpg-agent.conf",{"type":26,"value":197}," file.",{"type":21,"tag":141,"props":199,"children":201},{"code":200},"default-cache-ttl 600\nmax-cache-ttl 7200\npinentry-program /opt/homebrew/bin/pinentry-mac\n",[202],{"type":21,"tag":40,"props":203,"children":204},{"__ignoreMap":7},[205],{"type":26,"value":200},{"type":21,"tag":22,"props":207,"children":208},{},[209,211,217],{"type":26,"value":210},"If your don't know the path to your pinentry program, you can throw down a quick ",{"type":21,"tag":40,"props":212,"children":214},{"className":213},[],[215],{"type":26,"value":216},"which",{"type":26,"value":55},{"type":21,"tag":141,"props":219,"children":221},{"code":220,"language":144,"meta":7,"className":145,"style":7},"$ which pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n",[222],{"type":21,"tag":40,"props":223,"children":224},{"__ignoreMap":7},[225,241],{"type":21,"tag":151,"props":226,"children":227},{"class":153,"line":154},[228,232,237],{"type":21,"tag":151,"props":229,"children":230},{"style":158},[231],{"type":26,"value":161},{"type":21,"tag":151,"props":233,"children":234},{"style":164},[235],{"type":26,"value":236}," which",{"type":21,"tag":151,"props":238,"children":239},{"style":164},[240],{"type":26,"value":177},{"type":21,"tag":151,"props":242,"children":244},{"class":153,"line":243},2,[245],{"type":21,"tag":151,"props":246,"children":247},{"style":158},[248],{"type":26,"value":249},"/opt/homebrew/bin/pinentry-mac\n",{"type":21,"tag":22,"props":251,"children":252},{},[253],{"type":26,"value":254},"Or use your Homebrew prefix.",{"type":21,"tag":141,"props":256,"children":258},{"code":257,"language":144,"meta":7,"className":145,"style":7},"$ echo $(brew --prefix)/bin/pinentry-mac\n/opt/homebrew/bin/pinentry-mac\n",[259],{"type":21,"tag":40,"props":260,"children":261},{"__ignoreMap":7},[262,301],{"type":21,"tag":151,"props":263,"children":264},{"class":153,"line":154},[265,269,274,280,285,291,296],{"type":21,"tag":151,"props":266,"children":267},{"style":158},[268],{"type":26,"value":161},{"type":21,"tag":151,"props":270,"children":271},{"style":164},[272],{"type":26,"value":273}," echo",{"type":21,"tag":151,"props":275,"children":277},{"style":276},"--shiki-default:#24292E",[278],{"type":26,"value":279}," $(",{"type":21,"tag":151,"props":281,"children":282},{"style":158},[283],{"type":26,"value":284},"brew",{"type":21,"tag":151,"props":286,"children":288},{"style":287},"--shiki-default:#005CC5",[289],{"type":26,"value":290}," --prefix",{"type":21,"tag":151,"props":292,"children":293},{"style":276},[294],{"type":26,"value":295},")",{"type":21,"tag":151,"props":297,"children":298},{"style":164},[299],{"type":26,"value":300},"/bin/pinentry-mac\n",{"type":21,"tag":151,"props":302,"children":303},{"class":153,"line":243},[304],{"type":21,"tag":151,"props":305,"children":306},{"style":158},[307],{"type":26,"value":249},{"type":21,"tag":22,"props":309,"children":310},{},[311],{"type":26,"value":312},"But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim.",{"type":21,"tag":314,"props":315,"children":316},"style",{},[317],{"type":26,"value":318},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":243,"depth":243,"links":320},[321,322],{"id":83,"depth":243,"text":86},{"id":131,"depth":243,"text":134},"markdown","content:articles:vim-fugitive-gpg-pinentry.md","content","articles/vim-fugitive-gpg-pinentry.md","articles/vim-fugitive-gpg-pinentry","md",1720229315487] \ No newline at end of file diff --git a/articles/vim-fugitive-gpg-pinentry/index.html b/articles/vim-fugitive-gpg-pinentry/index.html index e320c5fa..5eff9a8c 100644 --- a/articles/vim-fugitive-gpg-pinentry/index.html +++ b/articles/vim-fugitive-gpg-pinentry/index.html @@ -4,32 +4,33 @@ - - + + - - - - + + + + - + + - - - - - - - - - - - - - -

            Using pinentry-mac to sign commits from vim-fugitive

            2024-05-11

            In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.

            Preface

            The man, the myth, the legend, Timothy Popallopollis himself recommends configuring your gpg-agent to use a GUI based pinentry-program. On macOS this can be done quite by simply installing pinentry-mac, and updating your gpg-agent.conf.

            Configuration

            First things first, let's install the pinentry program.

            $ brew install pinentry-mac
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +

            Using pinentry-mac to sign commits from vim-fugitive

            In order to sign git commits from within Vim using a plugin like tpope/vim-fugitive, it is necessary to configure the gpg-agent to use a GUI based pinentry-program.

            Preface

            The man, the myth, the legend, Timothy Popallopollis himself recommends configuring your gpg-agent to use a GUI based pinentry-program. On macOS this can be done quite by simply installing pinentry-mac, and updating your gpg-agent.conf.

            Configuration

            First things first, let's install the pinentry program.

            $ brew install pinentry-mac
             

            Then, all we need to do is set the pinentry-program option in your ~/.gnupg/gpg-agent.conf file.

            default-cache-ttl 600
             max-cache-ttl 7200
             pinentry-program /opt/homebrew/bin/pinentry-mac
            @@ -37,5 +38,5 @@
             /opt/homebrew/bin/pinentry-mac
             

            Or use your Homebrew prefix.

            $ echo $(brew --prefix)/bin/pinentry-mac
             /opt/homebrew/bin/pinentry-mac
            -

            But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim.

            - \ No newline at end of file +

            But that's all it takes. Now, you should be prompted to enter your gpg pin in an external window when signing commits from vim.

            + \ No newline at end of file diff --git a/atom/index.html b/atom/index.html index 65506a27..42311052 100644 --- a/atom/index.html +++ b/atom/index.html @@ -2,7 +2,7 @@ https://cmpadden.github.io cmpadden.github.io - 2024-06-20T13:46:21.253Z + 2024-07-06T01:28:35.036Z Nuxt static site generation + Feed for Node.js Colton Padden diff --git a/card/_payload.json b/card/_payload.json index 651f7037..33e7bdd3 100644 --- a/card/_payload.json +++ b/card/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180653] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314469] \ No newline at end of file diff --git a/card/index.html b/card/index.html index f343a328..1cb0107d 100644 --- a/card/index.html +++ b/card/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            TL;DR
            Name
            Colton
            Profession
            Astronaut
            Hobby
            Skydiving
            - \ No newline at end of file + + + + + + + +
            TL;DR
            Name
            Colton
            Profession
            Astronaut
            Hobby
            Skydiving
            + \ No newline at end of file diff --git a/examples/nested_transitions/_payload.json b/examples/nested_transitions/_payload.json index 6189ece7..33e7bdd3 100644 --- a/examples/nested_transitions/_payload.json +++ b/examples/nested_transitions/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180654] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314469] \ No newline at end of file diff --git a/examples/nested_transitions/index.html b/examples/nested_transitions/index.html index fa76089a..97ec5783 100644 --- a/examples/nested_transitions/index.html +++ b/examples/nested_transitions/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            - \ No newline at end of file + + + + + + + +
            + \ No newline at end of file diff --git a/index.html b/index.html index 70da13f6..e7dd10c8 100644 --- a/index.html +++ b/index.html @@ -4,16 +4,16 @@ - - - - - - - + + + + + + + - - - -
            Currently, I am helping educate engineers and building the future of data orchestration at Dagster.
            Previously, I worked at Gemini building the data platform that provided company-wide insights into the exchange and business. At Georgetown University's Massive Data Institute building data warehousing, processing solutions, and portals to aid social scientists and researchers to leverage large-scale organic data. And previously I provided consulting for financial institutions and government agencies in the D.C. area around data practices, and identity and access management.
            - \ No newline at end of file + + + +
            Currently, I am helping educate engineers and building the future of data orchestration at Dagster.
            Previously, I worked at Gemini building the data platform that provided company-wide insights into the exchange and business. At Georgetown University's Massive Data Institute building data warehousing, processing solutions, and portals to aid social scientists and researchers to leverage large-scale organic data. And previously I provided consulting for financial institutions and government agencies in the D.C. area around data practices, and identity and access management.
            + \ No newline at end of file diff --git a/playground/_payload.json b/playground/_payload.json index cfd0e434..baed9c1e 100644 --- a/playground/_payload.json +++ b/playground/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180661] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314474] \ No newline at end of file diff --git a/playground/audio/_payload.json b/playground/audio/_payload.json index c9c54b39..9de12128 100644 --- a/playground/audio/_payload.json +++ b/playground/audio/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180656] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314471] \ No newline at end of file diff --git a/playground/audio/index.html b/playground/audio/index.html index d49acdaf..6fd725a8 100644 --- a/playground/audio/index.html +++ b/playground/audio/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            Enable
            Disable
            Time Domain Waveform
            Frequency Spectrogram
            Frequency Bar Chart
            Frequency Buffer History
            IndexMeanMinMaxFFTBuffer
            Time Domain Buffer History
            IndexMeanMinMaxFFTBuffer
            - \ No newline at end of file + + + + + + + +
            Enable
            Disable
            Time Domain Waveform
            Frequency Spectrogram
            Frequency Bar Chart
            Frequency Buffer History
            IndexMeanMinMaxFFTBuffer
            Time Domain Buffer History
            IndexMeanMinMaxFFTBuffer
            + \ No newline at end of file diff --git a/playground/chords/_payload.json b/playground/chords/_payload.json index d15c6b4b..8bff7aac 100644 --- a/playground/chords/_payload.json +++ b/playground/chords/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180657] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314472] \ No newline at end of file diff --git a/playground/chords/index.html b/playground/chords/index.html index bbc975fe..e965f62f 100644 --- a/playground/chords/index.html +++ b/playground/chords/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            Unfortunately, the Web MIDI API is not supported in all browsers...
            - \ No newline at end of file + + + + + + + +
            Unfortunately, the Web MIDI API is not supported in all browsers...
            + \ No newline at end of file diff --git a/playground/conway/_payload.json b/playground/conway/_payload.json index fa8a0f92..8bff7aac 100644 --- a/playground/conway/_payload.json +++ b/playground/conway/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180658] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314472] \ No newline at end of file diff --git a/playground/conway/index.html b/playground/conway/index.html index ba1a8d53..116bc9e5 100644 --- a/playground/conway/index.html +++ b/playground/conway/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            - \ No newline at end of file + + + + + + + +
            + \ No newline at end of file diff --git a/playground/french/_payload.json b/playground/french/_payload.json index bb7eb467..62589aa3 100644 --- a/playground/french/_payload.json +++ b/playground/french/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180659] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314473] \ No newline at end of file diff --git a/playground/french/index.html b/playground/french/index.html index d66d8fb5..e0341f70 100644 --- a/playground/french/index.html +++ b/playground/french/index.html @@ -4,14 +4,14 @@ - - - - - + + + + + - - - -
            1000 French Conjugations
            Loading...
            - \ No newline at end of file + + + +
            1000 French Conjugations
            Loading...
            + \ No newline at end of file diff --git a/playground/index.html b/playground/index.html index 1736e558..bc12dce7 100644 --- a/playground/index.html +++ b/playground/index.html @@ -4,13 +4,13 @@ - - - - - - - - -
            - \ No newline at end of file + + + + + + + + +
            + \ No newline at end of file diff --git a/playground/matrix/_payload.json b/playground/matrix/_payload.json index 957edac4..baed9c1e 100644 --- a/playground/matrix/_payload.json +++ b/playground/matrix/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180662] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314474] \ No newline at end of file diff --git a/playground/matrix/index.html b/playground/matrix/index.html index f530fd92..98ed5871 100644 --- a/playground/matrix/index.html +++ b/playground/matrix/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            Walk through the steps of matrix multiplication with randomly generated matrices. Press the Spacebar or click the buttons to iterate through the steps.
            Matrix A
            Matrix B
            - \ No newline at end of file + + + + + + + +
            Walk through the steps of matrix multiplication with randomly generated matrices. Press the Spacebar or click the buttons to iterate through the steps.
            Matrix A
            Matrix B
            + \ No newline at end of file diff --git a/playground/metronome/_payload.json b/playground/metronome/_payload.json index 86829632..fe556d51 100644 --- a/playground/metronome/_payload.json +++ b/playground/metronome/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180663] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314475] \ No newline at end of file diff --git a/playground/metronome/index.html b/playground/metronome/index.html index 2282ec55..59a68691 100644 --- a/playground/metronome/index.html +++ b/playground/metronome/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            - \ No newline at end of file + + + + + + + +
            + \ No newline at end of file diff --git a/playground/midi/_payload.json b/playground/midi/_payload.json index cfc6f954..feb03b82 100644 --- a/playground/midi/_payload.json +++ b/playground/midi/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180664] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314476] \ No newline at end of file diff --git a/playground/midi/index.html b/playground/midi/index.html index c17b95a4..7b949370 100644 --- a/playground/midi/index.html +++ b/playground/midi/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            Unfortunately, the Web MIDI API is not supported in all browsers...
            - \ No newline at end of file + + + + + + + +
            Unfortunately, the Web MIDI API is not supported in all browsers...
            + \ No newline at end of file diff --git a/playground/palettes/mountains/_payload.json b/playground/palettes/mountains/_payload.json index cfc6f954..feb03b82 100644 --- a/playground/palettes/mountains/_payload.json +++ b/playground/palettes/mountains/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180664] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314476] \ No newline at end of file diff --git a/playground/palettes/mountains/index.html b/playground/palettes/mountains/index.html index e4981936..007f45c9 100644 --- a/playground/palettes/mountains/index.html +++ b/playground/palettes/mountains/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            Click or tap anywhere to redraw the waves!
            - \ No newline at end of file + + + + + + + +
            Click or tap anywhere to redraw the waves!
            + \ No newline at end of file diff --git a/playground/palettes/variance/_payload.json b/playground/palettes/variance/_payload.json index aca177c4..8bcc7a8f 100644 --- a/playground/palettes/variance/_payload.json +++ b/playground/palettes/variance/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180665] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314477] \ No newline at end of file diff --git a/playground/palettes/variance/index.html b/playground/palettes/variance/index.html index 565870a4..8ffaa71b 100644 --- a/playground/palettes/variance/index.html +++ b/playground/palettes/variance/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            - \ No newline at end of file + + + + + + + +
            + \ No newline at end of file diff --git a/playground/plotter/_payload.json b/playground/plotter/_payload.json index d91b427f..a943eaba 100644 --- a/playground/plotter/_payload.json +++ b/playground/plotter/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180666] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314478] \ No newline at end of file diff --git a/playground/plotter/index.html b/playground/plotter/index.html index 5268657c..e86a1aab 100644 --- a/playground/plotter/index.html +++ b/playground/plotter/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            - \ No newline at end of file + + + + + + + +
            + \ No newline at end of file diff --git a/playground/tiling/_payload.json b/playground/tiling/_payload.json index 28a0742a..680f3602 100644 --- a/playground/tiling/_payload.json +++ b/playground/tiling/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891180668] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314480] \ No newline at end of file diff --git a/playground/tiling/index.html b/playground/tiling/index.html index fb3771d1..0e17980d 100644 --- a/playground/tiling/index.html +++ b/playground/tiling/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            m-ary tree based tiling
            - \ No newline at end of file + + + + + + + +
            m-ary tree based tiling
            + \ No newline at end of file diff --git a/playground/waves/_payload.json b/playground/waves/_payload.json index 9c0e43ba..544865c2 100644 --- a/playground/waves/_payload.json +++ b/playground/waves/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1718891181166] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1720229314954] \ No newline at end of file diff --git a/playground/waves/index.html b/playground/waves/index.html index 0d4e2571..f565de22 100644 --- a/playground/waves/index.html +++ b/playground/waves/index.html @@ -4,12 +4,12 @@ - - - - - - - -
            y(x) = A sin((2π / λ) x)
            y(x) = A cos((2π / λ) x)
            y(x) = A tan((2π / λ) x)
            Click or tap anywhere to clear the canvas!
            - \ No newline at end of file + + + + + + + +
            y(x) = A sin((2π / λ) x)
            y(x) = A cos((2π / λ) x)
            y(x) = A tan((2π / λ) x)
            Click or tap anywhere to clear the canvas!
            + \ No newline at end of file