diff --git a/README.md b/README.md index 651de1e..ed93ff2 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,6 @@ -## Commands +# Kompact.io site -recompile css -```sh - tailwindcss -i ./content/css/main.css -o ./content/css/mini.css --minify -``` +## Commands -build, serve and watch -```sh - cabal run site -- watch -``` - -deploy -```sh - rsync -r --delete ./_site/* genesis:/var/www/kompactio-landing/ -``` +Enter devshell, and run `menu` +See flake for details. diff --git a/content/css/main.css b/content/css/main.css index 8a6a617..ad292cc 100644 --- a/content/css/main.css +++ b/content/css/main.css @@ -5,7 +5,8 @@ @font-face { /* Set in tailwindconfig */ font-family: "jetbrains-mono"; - src: local("jetbrains-mono"), + src: + local("jetbrains-mono"), url("/fonts/JetBrainsMono-Medium.woff2") format("woff2"); } @@ -13,59 +14,61 @@ article { margin-bottom: 2rem; } -article>section> :is(pre, p, h1, h2, h3, h4, h5, h6) { +article > section > :is(pre, p, h1, h2, h3, h4, h5, h6) { margin-top: 2rem; } -article>section { - font-family: "Lucida" Grande, sans-serif; +article > section { + font-family: + "Lucida" Grande, + sans-serif; } -article>section> :is(h1, h2, h3, h4, h5, h6, code) { +article > section > :is(h1, h2, h3, h4, h5, h6, code) { font-family: "jetbrains-mono"; } -article>section>blockquote { +article > section > blockquote { padding: 1rem; border-left-width: 4px; border-color: rgb(239 68 68); font-style: italic; } -article>section>h1 { +article > section > h1 { margin-top: 2rem; font-size: 3rem; } -article>section>h1::before { +article > section > h1::before { content: "# "; } -article>section>h2 { +article > section > h2 { font-size: 2rem; } -article>section>h2::before { +article > section > h2::before { content: "## "; } -article>section>h3 { +article > section > h3 { font-size: 1.5rem; } -article>section>h3::before { +article > section > h3::before { content: "### "; } -article>section>h4 { +article > section > h4 { font-size: 1.3rem; } -article>section>h4::before { +article > section > h4::before { content: "#### "; } -article>section { +article > section { margin-top: 4rem; } @@ -90,4 +93,16 @@ article ul { article ol { margin-left: 1rem; list-style: decimal inside; -} \ No newline at end of file +} + +#footnotes { + padding-top: 1rem; +} + +#footnotes > ol > li { + margin-top: 1rem; +} + +#footnotes > ol > li > p { + display: inline; +} diff --git a/content/css/mini.css b/content/css/mini.css index e8dfc84..63913b8 100644 --- a/content/css/mini.css +++ b/content/css/mini.css @@ -1 +1,953 @@ -/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:jetbrains-mono;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.absolute{position:absolute}.relative{position:relative}.inset-y-0{top:0;bottom:0}.left-0{left:0}.right-0{right:0}.z-10{z-index:10}.m-auto{margin:auto}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-16{height:4rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-96{height:24rem}.h-full{height:100%}.min-h-\[50vh\]{min-height:50vh}.min-h-screen{min-height:100vh}.w-48{width:12rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-auto{width:auto}.max-w-7xl{max-width:80rem}.max-w-prose{max-width:65ch}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.origin-top-right{transform-origin:top right}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.scale-100,.scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.gap-12{gap:3rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-1{padding:.25rem}.p-2{padding:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-3{padding-bottom:.75rem}.pr-2{padding-right:.5rem}.pt-2{padding-top:.5rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-6xl{font-size:3.75rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-75{transition-duration:75ms}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}@font-face{font-family:jetbrains-mono;src:local("jetbrains-mono"),url(/fonts/JetBrainsMono-Medium.woff2) format("woff2")}article{margin-bottom:2rem}article>section>:is(pre,p,h1,h2,h3,h4,h5,h6){margin-top:2rem}article>section{font-family:Lucida,Grande,sans-serif}article>section>:is(h1,h2,h3,h4,h5,h6,code){font-family:jetbrains-mono}article>section>blockquote{padding:1rem;border-left-width:4px;border-color:#ef4444;font-style:italic}article>section>h1{margin-top:2rem;font-size:3rem}article>section>h1:before{content:"# "}article>section>h2{font-size:2rem}article>section>h2:before{content:"## "}article>section>h3{font-size:1.5rem}article>section>h3:before{content:"### "}article>section>h4{font-size:1.3rem}article>section>h4:before{content:"#### "}article>section{margin-top:4rem}article a{text-decoration-color:#ef4444;text-decoration-thickness:4px;transition-duration:70ms}article a,article a:hover{text-decoration-line:underline}article a:hover{text-decoration-thickness:8px;text-decoration-color:#b91c1c}article ul{margin-left:1rem;list-style-type:"- "}article ol{margin-left:1rem;list-style:decimal inside}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-inset:focus{--tw-ring-inset:inset}.focus\:ring-white:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(255 255 255/var(--tw-ring-opacity))}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}.focus\:ring-offset-gray-800:focus{--tw-ring-offset-color:#1f2937}:is(.dark .dark\:bg-gradient-to-br){background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}:is(.dark .dark\:from-slate-950){--tw-gradient-from:#020617 var(--tw-gradient-from-position);--tw-gradient-to:#02061700 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:to-black){--tw-gradient-to:#000 var(--tw-gradient-to-position)}:is(.dark .dark\:fill-white){fill:#fff}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:text-yellow-400){--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity))}@media (min-width:640px){.sm\:static{position:static}.sm\:inset-auto{inset:auto}.sm\:mx-4{margin-left:1rem;margin-right:1rem}.sm\:ml-6{margin-left:1.5rem}.sm\:block{display:block}.sm\:inline{display:inline}.sm\:hidden{display:none}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:items-stretch{align-items:stretch}.sm\:justify-start{justify-content:flex-start}.sm\:gap-8{gap:2rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pr-0{padding-right:0}}@media (min-width:768px){.md\:mx-24{margin-left:6rem;margin-right:6rem}.md\:gap-8{gap:2rem}}@media (min-width:1024px){.lg\:block{display:block}.lg\:hidden{display:none}.lg\:px-8{padding-left:2rem;padding-right:2rem}} \ No newline at end of file +*, +:after, +:before { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgba(59, 130, 246, 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgba(59, 130, 246, 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} /*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/ +*, +:after, +:before { + border: 0 solid #e5e7eb; + box-sizing: border-box; +} +:after, +:before { + --tw-content: ""; +} +:host, +html { + line-height: 1.5; + -webkit-text-size-adjust: 100%; + font-family: jetbrains-mono; + font-feature-settings: normal; + font-variation-settings: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-tap-highlight-color: transparent; +} +body { + line-height: inherit; + margin: 0; +} +hr { + border-top-width: 1px; + color: inherit; + height: 0; +} +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} +a { + color: inherit; + text-decoration: inherit; +} +b, +strong { + font-weight: bolder; +} +code, +kbd, +pre, +samp { + font-family: + ui-monospace, + SFMono-Regular, + Menlo, + Monaco, + Consolas, + Liberation Mono, + Courier New, + monospace; + font-feature-settings: normal; + font-size: 1em; + font-variation-settings: normal; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sub { + bottom: -0.25em; +} +sup { + top: -0.5em; +} +table { + border-collapse: collapse; + border-color: inherit; + text-indent: 0; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font-family: inherit; + font-feature-settings: inherit; + font-size: 100%; + font-variation-settings: inherit; + font-weight: inherit; + letter-spacing: inherit; + line-height: inherit; + margin: 0; + padding: 0; +} +button, +select { + text-transform: none; +} +button, +input:where([type="button"]), +input:where([type="reset"]), +input:where([type="submit"]) { + -webkit-appearance: button; + background-color: transparent; + background-image: none; +} +:-moz-focusring { + outline: auto; +} +:-moz-ui-invalid { + box-shadow: none; +} +progress { + vertical-align: baseline; +} +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} +::-webkit-search-decoration { + -webkit-appearance: none; +} +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} +summary { + display: list-item; +} +blockquote, +dd, +dl, +figure, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +p, +pre { + margin: 0; +} +fieldset { + margin: 0; +} +fieldset, +legend { + padding: 0; +} +menu, +ol, +ul { + list-style: none; + margin: 0; + padding: 0; +} +dialog { + padding: 0; +} +textarea { + resize: vertical; +} +input::-moz-placeholder, +textarea::-moz-placeholder { + color: #9ca3af; + opacity: 1; +} +input::placeholder, +textarea::placeholder { + color: #9ca3af; + opacity: 1; +} +[role="button"], +button { + cursor: pointer; +} +:disabled { + cursor: default; +} +audio, +canvas, +embed, +iframe, +img, +object, +svg, +video { + display: block; + vertical-align: middle; +} +img, +video { + height: auto; + max-width: 100%; +} +[hidden]:where(:not([hidden="until-found"])) { + display: none; +} +.container { + width: 100%; +} +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} +.sr-only { + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + clip: rect(0, 0, 0, 0); + border-width: 0; + white-space: nowrap; +} +.absolute { + position: absolute; +} +.relative { + position: relative; +} +.inset-y-0 { + bottom: 0; + top: 0; +} +.left-0 { + left: 0; +} +.right-0 { + right: 0; +} +.z-10 { + z-index: 10; +} +.m-auto { + margin: auto; +} +.mx-2 { + margin-left: 0.5rem; + margin-right: 0.5rem; +} +.mx-auto { + margin-left: auto; + margin-right: auto; +} +.ml-3 { + margin-left: 0.75rem; +} +.ml-4 { + margin-left: 1rem; +} +.mt-2 { + margin-top: 0.5rem; +} +.mt-4 { + margin-top: 1rem; +} +.block { + display: block; +} +.inline { + display: inline; +} +.flex { + display: flex; +} +.inline-flex { + display: inline-flex; +} +.grid { + display: grid; +} +.hidden { + display: none; +} +.h-16 { + height: 4rem; +} +.h-6 { + height: 1.5rem; +} +.h-8 { + height: 2rem; +} +.h-96 { + height: 24rem; +} +.h-full { + height: 100%; +} +.min-h-\[50vh\] { + min-height: 50vh; +} +.min-h-screen { + min-height: 100vh; +} +.w-48 { + width: 12rem; +} +.w-6 { + width: 1.5rem; +} +.w-8 { + width: 2rem; +} +.w-auto { + width: auto; +} +.max-w-48 { + max-width: 12rem; +} +.max-w-7xl { + max-width: 80rem; +} +.max-w-prose { + max-width: 65ch; +} +.flex-1 { + flex: 1 1 0%; +} +.flex-shrink-0 { + flex-shrink: 0; +} +.origin-top-right { + transform-origin: top right; +} +.scale-100 { + --tw-scale-x: 1; + --tw-scale-y: 1; +} +.scale-100, +.scale-95 { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.scale-95 { + --tw-scale-x: 0.95; + --tw-scale-y: 0.95; +} +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) + rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) + scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.resize { + resize: both; +} +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} +.flex-row { + flex-direction: row; +} +.flex-col { + flex-direction: column; +} +.items-start { + align-items: flex-start; +} +.items-center { + align-items: center; +} +.justify-center { + justify-content: center; +} +.justify-between { + justify-content: space-between; +} +.justify-around { + justify-content: space-around; +} +.gap-12 { + gap: 3rem; +} +.gap-2 { + gap: 0.5rem; +} +.gap-4 { + gap: 1rem; +} +.space-x-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-left: calc(1rem * (1 - var(--tw-space-x-reverse))); + margin-right: calc(1rem * var(--tw-space-x-reverse)); +} +.space-y-1 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); + margin-top: calc(0.25rem * (1 - var(--tw-space-y-reverse))); +} +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.rounded-full { + border-radius: 9999px; +} +.rounded-md { + border-radius: 0.375rem; +} +.bg-gray-100 { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1)); +} +.bg-gray-800 { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1)); +} +.bg-gray-900 { + --tw-bg-opacity: 1; + background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1)); +} +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); +} +.p-1 { + padding: 0.25rem; +} +.p-2 { + padding: 0.5rem; +} +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} +.py-1 { + padding-bottom: 0.25rem; + padding-top: 0.25rem; +} +.py-12 { + padding-bottom: 3rem; + padding-top: 3rem; +} +.py-2 { + padding-bottom: 0.5rem; + padding-top: 0.5rem; +} +.py-6 { + padding-bottom: 1.5rem; + padding-top: 1.5rem; +} +.py-8 { + padding-bottom: 2rem; + padding-top: 2rem; +} +.pb-3 { + padding-bottom: 0.75rem; +} +.pr-2 { + padding-right: 0.5rem; +} +.pt-2 { + padding-top: 0.5rem; +} +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} +.text-6xl { + font-size: 3.75rem; + line-height: 1; +} +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} +.font-bold { + font-weight: 700; +} +.font-medium { + font-weight: 500; +} +.text-gray-300 { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity, 1)); +} +.text-gray-400 { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity, 1)); +} +.text-gray-700 { + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity, 1)); +} +.text-gray-800 { + --tw-text-opacity: 1; + color: rgb(31 41 55 / var(--tw-text-opacity, 1)); +} +.text-gray-900 { + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity, 1)); +} +.text-red-500 { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity, 1)); +} +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} +.opacity-0 { + opacity: 0; +} +.opacity-100 { + opacity: 1; +} +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), + 0 4px 6px -4px rgba(0, 0, 0, 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), + 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.ring-1 { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); +} +.ring-black { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity, 1)); +} +.ring-opacity-5 { + --tw-ring-opacity: 0.05; +} +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) + var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) + var(--tw-sepia) var(--tw-drop-shadow); +} +.transition { + transition-duration: 0.15s; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + -webkit-backdrop-filter; + transition-property: color, background-color, border-color, + text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, + backdrop-filter; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + opacity, + box-shadow, + transform, + filter, + backdrop-filter, + -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.duration-100 { + transition-duration: 0.1s; +} +.duration-75 { + transition-duration: 75ms; +} +.ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} +.ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +@font-face { + font-family: jetbrains-mono; + src: + local("jetbrains-mono"), + url(/fonts/JetBrainsMono-Medium.woff2) format("woff2"); +} +article { + margin-bottom: 2rem; +} +article > section > :is(pre, p, h1, h2, h3, h4, h5, h6) { + margin-top: 2rem; +} +article > section { + font-family: Lucida, Grande, sans-serif; +} +article > section > :is(h1, h2, h3, h4, h5, h6, code) { + font-family: jetbrains-mono; +} +article > section > blockquote { + border-color: #ef4444; + border-left-width: 4px; + font-style: italic; + padding: 1rem; +} +article > section > h1 { + font-size: 3rem; + margin-top: 2rem; +} +article > section > h1:before { + content: "# "; +} +article > section > h2 { + font-size: 2rem; +} +article > section > h2:before { + content: "## "; +} +article > section > h3 { + font-size: 1.5rem; +} +article > section > h3:before { + content: "### "; +} +article > section > h4 { + font-size: 1.3rem; +} +article > section > h4:before { + content: "#### "; +} +article > section { + margin-top: 4rem; +} +article a { + text-decoration-color: #ef4444; + text-decoration-thickness: 4px; + transition-duration: 70ms; +} +article a, +article a:hover { + text-decoration-line: underline; +} +article a:hover { + text-decoration-color: #b91c1c; + text-decoration-thickness: 8px; +} +article ul { + list-style-type: "- "; + margin-left: 1rem; +} +article ol { + list-style: decimal inside; + margin-left: 1rem; +} +#footnotes { + padding-top: 1rem; +} +#footnotes > ol > li { + margin-top: 1rem; +} +#footnotes > ol > li > p { + display: inline; +} +.hover\:bg-gray-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1)); +} +.hover\:text-white:hover { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} +.focus\:outline-none:focus { + outline: 2px solid transparent; + outline-offset: 2px; +} +.focus\:ring-2:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 + var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 + calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), + var(--tw-shadow, 0 0 #0000); +} +.focus\:ring-inset:focus { + --tw-ring-inset: inset; +} +.focus\:ring-white:focus { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity, 1)); +} +.focus\:ring-offset-2:focus { + --tw-ring-offset-width: 2px; +} +.focus\:ring-offset-gray-800:focus { + --tw-ring-offset-color: #1f2937; +} +.dark\:bg-gradient-to-br:is(.dark *) { + background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); +} +.dark\:from-slate-950:is(.dark *) { + --tw-gradient-from: #020617 var(--tw-gradient-from-position); + --tw-gradient-to: rgba(2, 6, 23, 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} +.dark\:to-black:is(.dark *) { + --tw-gradient-to: #000 var(--tw-gradient-to-position); +} +.dark\:fill-white:is(.dark *) { + fill: #fff; +} +.dark\:text-gray-200:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(229 231 235 / var(--tw-text-opacity, 1)); +} +.dark\:text-white:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} +.dark\:text-yellow-400:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(250 204 21 / var(--tw-text-opacity, 1)); +} +@media (min-width: 640px) { + .sm\:static { + position: static; + } + .sm\:inset-auto { + inset: auto; + } + .sm\:mx-4 { + margin-left: 1rem; + margin-right: 1rem; + } + .sm\:ml-6 { + margin-left: 1.5rem; + } + .sm\:block { + display: block; + } + .sm\:inline { + display: inline; + } + .sm\:hidden { + display: none; + } + .sm\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .sm\:flex-row { + flex-direction: row; + } + .sm\:items-stretch { + align-items: stretch; + } + .sm\:justify-start { + justify-content: flex-start; + } + .sm\:gap-8 { + gap: 2rem; + } + .sm\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + .sm\:pr-0 { + padding-right: 0; + } +} +@media (min-width: 768px) { + .md\:mx-24 { + margin-left: 6rem; + margin-right: 6rem; + } + .md\:gap-8 { + gap: 2rem; + } +} +@media (min-width: 1024px) { + .lg\:block { + display: block; + } + .lg\:hidden { + display: none; + } + .lg\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } +} diff --git a/content/css/prism.css b/content/css/prism.css index e4baabb..8645700 100644 --- a/content/css/prism.css +++ b/content/css/prism.css @@ -1,3 +1,118 @@ /* PrismJS 1.29.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+haskell+json+nix+racket+rust+scheme */ -code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help} +code[class*="language-"], +pre[class*="language-"] { + color: #000; + background: 0 0; + text-shadow: 0 1px #fff; + font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} +code[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, +pre[class*="language-"] ::-moz-selection, +pre[class*="language-"]::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} +code[class*="language-"] ::selection, +code[class*="language-"]::selection, +pre[class*="language-"] ::selection, +pre[class*="language-"]::selection { + text-shadow: none; + background: #b3d4fc; +} +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} +pre[class*="language-"] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; +} +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} +:not(pre) > code[class*="language-"] { + padding: 0.1em; + border-radius: 0.3em; + white-space: normal; +} +.token.cdata, +.token.comment, +.token.doctype, +.token.prolog { + color: #708090; +} +.token.punctuation { + color: #999; +} +.token.namespace { + opacity: 0.7; +} +.token.boolean, +.token.constant, +.token.deleted, +.token.number, +.token.property, +.token.symbol, +.token.tag { + color: #905; +} +.token.attr-name, +.token.builtin, +.token.char, +.token.inserted, +.token.selector, +.token.string { + color: #690; +} +.language-css .token.string, +.style .token.string, +.token.entity, +.token.operator, +.token.url { + color: #9a6e3a; + background: hsla(0, 0%, 100%, 0.5); +} +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} +.token.class-name, +.token.function { + color: #dd4a68; +} +.token.important, +.token.regex, +.token.variable { + color: #e90; +} +.token.bold, +.token.important { + font-weight: 700; +} +.token.italic { + font-style: italic; +} +.token.entity { + cursor: help; +} diff --git a/content/drafts/why-building-tx-is-hard.md b/content/drafts/why-building-tx-is-hard.md new file mode 100644 index 0000000..74be2cf --- /dev/null +++ b/content/drafts/why-building-tx-is-hard.md @@ -0,0 +1,59 @@ +--- +title: why is building txs hard? +--- + +## What is a dapp? + +A typical dapp has a number of components: + +- Validators: also called the _on-chain_ part. + The decentralized network of nodes that maintain the chain run this code as part of the process of deciding + whether a tx is to be added to the chain or rejected. +- Chain indexing: watches the chain and records the data relevant to the dapp. +- Pretty front-end: typically how a user interacts with a dapp. +- Tx-building code: A component of the frontend. + It takes data from the user, the user's wallet, the chain-indexer and possibly elsewhere + to construct txs to be submitted to the chain that the validators will deem acceptable. + +Here we have really described a browser-based plutus dapp. +Considering the term _dapp_ more generally, the Daedalus wallet is a dapp which is neither browser based nor involves any Plutus. +Cli-based dapps also exist, such as multi-sig using native scripts. + +## What is a tx? + +At its core, the chain is a list of transaction outputs. +The chain is changed by submitting a tx which "spends" existing unspent transaction outputs (utxos) and appending new ones. +(There's other possible modifications too, like minting native assets and staking _etc_, but the key part is spending.) + +The on-chain part is where the dapp has its integrity, but users can only interact with the on-chain part of the dapp by submitting txs. + +The on-chain part is relatively simple. +It inspects each tx that it is concerned with, and if it does not like what it sees, it fails. +Cardano is, in this sense, a lean chain. + +The off-chain part is relatively complex. +There may be no, one, or many potential valid txs that would satisfy the user's intent. + +At its core, a transaction is a list of inputs and outputs. +The inputs are spent, and the outputs created. +It must also contain the necessary signatures. + +## Some history + +When Plutus was first dreamed up, it wasn't just a language. +It was whole environment in which dapps would be engaged with. +The on-chain and off-chain code were coupled into a single framework with seamless extensive testing. +Dapps ran in the _PAB_, Plutus Application Backend. +Everything was great. + +Except that it didn't work. +The chain-indexer would periodically fall-over, +it required users had to maintain a full node, +and the api never matured in to something stable, complete, and bug-free. +In addition, the validators it produced were bloated and un-optimized and would quickly hit the constraints of the cardano blockchain. + +As a result teams turned to coming up with alternatives. +One of the first was MLabs and co in creating pluto and plutarch. +Later Aiken appeared to meet similar needs. +These began resolving issues with the on-chain part. +This left the off-chain part wanting. diff --git a/content/index.md b/content/index.md index 0e759e9..c362bae 100644 --- a/content/index.md +++ b/content/index.md @@ -1,3 +1,5 @@ --- title: Kompact.io ---- \ No newline at end of file +--- + +## Hero diff --git a/content/posts/are-we-zk-cardano-yet.md b/content/posts/are-we-zk-cardano-yet.md index 809fb45..b602332 100644 --- a/content/posts/are-we-zk-cardano-yet.md +++ b/content/posts/are-we-zk-cardano-yet.md @@ -3,74 +3,73 @@ title: Are we zk-Cardano yet? date: 2023-08-07 --- -Not so long ago Emurgo announced they were doing a Cardano centered hackathon. +Not so long ago Emurgo announced they were doing a Cardano centered hackathon. It was a welcome prospect - very few similar such events seem to exist in the space. -Things went monotonically south ever since the announcement, but that's a different story. +Things went monotonically south ever since the announcement, but that's a different story. -One particularly interesting quirk was that of the three "tracks" of the hackathon, -one was _Zero Knowledge_ (aka zk). +One particularly interesting quirk was that of the three "tracks" of the hackathon, +one was _Zero Knowledge_ (aka zk). Why particularly interesting quirk? In some sense it is not surprising: zk has been very trendy these last few years around blockchains. However, building on Cardano is notoriously challenging. Building with zk on a zk-native blockchain is itself a very steep learning curve. -So combining the two, zk on Cardano seemed... a bit mad. +So combining the two, zk on Cardano seemed... a bit mad. -This post is borne out of a best effort of how far "zk on Cardano" can be pushed. +This post is borne out of a best effort of how far "zk on Cardano" can be pushed. ## What is zk? -There is no shortage of explanations describing what zk is -( _eg_ [by Vitalik](https://vitalik.ca/general/2021/01/26/snarks.html){target="_blank"} or -[a full mooc](https://zk-learning.org/){target="_blank"} ). +There is no shortage of explanations describing what zk is +( _eg_ [by Vitalik](https://vitalik.ca/general/2021/01/26/snarks.html){target="\_blank"} or +[a full mooc](https://zk-learning.org/){target="\_blank"} ). There is also a reasonable breath to the field of zk that includes things like distributed compute. Zk involves some really neat maths that lets you do some seemingly magical feats and pairs well with blockchain in extending what is functionally possible. -Let's stick to a simple and prototypical example. +Let's stick to a simple and prototypical example. Suppose Alice and Bob are playing battleships. The game begins with Alice and Bob placing their ships within their own coordinate grid. -They then take turns picking coordinates to "strike". -If they hit nothing then their turn ends, but if they hit a ship then they strike again. -The winner is the first to strike all coordinates containing their opponent's ships. +They then take turns picking coordinates to "strike". +If they hit nothing then their turn ends, but if they hit a ship then they strike again. +The winner is the first to strike all coordinates containing their opponent's ships. Alice knows Bob as being a notorious liar; how can she enjoy the game? Each guess she makes, Bob gleefully shouts "Miss!". She can't ask Bob to show he's not lying by revealing the actual locations of the ships. -She could ask Charlie to independently verify Bob's not lying, -but then what if Charlie is actually on team Bob and also lies. +She could ask Charlie to independently verify Bob's not lying, +but then what if Charlie is actually on team Bob and also lies. Or Bob might suspect Charlie is actually on team Alice, slyly brought in to give Alice some hints. -Is there a way that Bob can prove to Alice that each guess is a miss, +Is there a way that Bob can prove to Alice that each guess is a miss, but without revealing the locations of the ships either to Alice or anyone else? -The answer is yes. -Using zk Bob can produce a proof each time Alice's guess misses if and only if it honestly does. +The answer is yes. +Using zk Bob can produce a proof each time Alice's guess misses if and only if it honestly does. Alice can inspect each proof and verify Bob's response. Alice can interrogate the proof as much as she wants, but she won't learn anything more than -her guess was a miss. +her guess was a miss. There are a multitude of different ways to do this, but essentially it involves modeling the problem as a bunch of algebra -over finite fields - like a lot of cryptography. +over finite fields - like a lot of cryptography. What's the _snark_ of zk-snark? -Snark stands for _Succinct Non-Interactive Argument of Knowledge_. -And without saying anything more, it means that Alice has to do way less algebra than Bob. +Snark stands for _Succinct Non-Interactive Argument of Knowledge_. +And without saying anything more, it means that Alice has to do way less algebra than Bob. In applications this is important because Bob might not be able to lie anymore but he could still waste Alice's time. - ## Sudoku snark -Sudoku snark was the entrant to Emurgo's hackathon. -The summary-pitch-story deck is [here](https://pub.kompact.io/sudoku-snark){target="_blank"}. -Links to the associated repos: [plutus-zk](https://github.com/waalge/plutus-zk){target="_blank"} -and [sudoku-snark](https://github.com/waalge/sudoku-snark){target="_blank"}. +Sudoku snark was the entrant to Emurgo's hackathon. +The summary-pitch-story deck is [here](https://pub.kompact.io/sudoku-snark){target="\_blank"}. +Links to the associated repos: [plutus-zk](https://github.com/waalge/plutus-zk){target="\_blank"} +and [sudoku-snark](https://github.com/waalge/sudoku-snark){target="\_blank"}. -Just after the hackathon got underway there was a -[large PR merged](https://github.com/input-output-hk/plutus/pull/5231){target="_blank"} +Just after the hackathon got underway there was a +[large PR merged](https://github.com/input-output-hk/plutus/pull/5231){target="\_blank"} into the main branch of plutus. -It's a mammoth culmination of many many months of work. -In it were some fundamental primitives needed for running zk algorithms. +It's a mammoth culmination of many many months of work. +In it were some fundamental primitives needed for running zk algorithms. The idea of the project was as follows: @@ -79,35 +78,35 @@ The idea of the project was as follows: - try to get a version of hydra running this newest version of plutus - wrap up in a gui -Unsurprisingly to anyone who's hung around the Cardano ecosystem long enough, -this third part is where things got stuck. +Unsurprisingly to anyone who's hung around the Cardano ecosystem long enough, +this third part is where things got stuck. We did get as far as running a cluster of nodes in the Conway era with the latest version of plutus -but unrelated changes seemed to thwart any chance of building transactions here. +but unrelated changes seemed to thwart any chance of building transactions here. -A quick shout-out to the [modulo-p.io](https://modulo-p.io/){target="_blank"} team. -They had a different approach and managed to implement a zk algorithm with the existing plutus primitives. +A quick shout-out to the [modulo-p.io](https://modulo-p.io/){target="\_blank"} team. +They had a different approach and managed to implement a zk algorithm with the existing plutus primitives. This spared the need to play the foolhardy dependency bumping game with the Cardano node. -However, because zk is so arithmetically intense, +However, because zk is so arithmetically intense, the app wont run outside a hydra head and with very generous max unit budgets (afaics). This approach won't be necessary when we have the new version of plutus available. Nonetheless, it's very neat to see it done and they packaged it very nicely. The validator in Sudoku snark uses [groth16](https://eprint.iacr.org/2016/260.pdf). -In part because this was already mostly available from the plutus repo itself. +In part because this was already mostly available from the plutus repo itself. It is also the most obvious candidate to begin with. -It's relatively mature, relatively simple, can be implemented from the new primitives, -and importantly in Cardano land has small proof size. +It's relatively mature, relatively simple, can be implemented from the new primitives, +and importantly in Cardano land has small proof size. (As far as I know, the smallest of comparable algorithms.) The program to generate the setup and proofs uses the Arkworks framework. Again this choice was initially inspired by a script from the IOG team, -but again it seems like a smart choice. -Arkworks is a well conceived, highly modular framework for zk, -which makes it easy to pull in the bits we need to perform our off-chain logic. +but again it seems like a smart choice. +Arkworks is a well conceived, highly modular framework for zk, +which makes it easy to pull in the bits we need to perform our off-chain logic. The choice of game, sudoku, was in turn inspired by an arkworks example. It's not the most compelling of choices, but it's simple and it did for now. -Battleships would have been more compelling or mastermind as the modulo-p team used. +Battleships would have been more compelling or mastermind as the modulo-p team used. The intended game play involved locking Ada at a utxo correspondinig to a sudoku puzzle, and spendable only if a player could provide proof they knew the solution. @@ -118,10 +117,10 @@ Other details were TBC: is it first and second prizes? are players whitelisted? We're close. -There is potentially still quite a while before these new primitives in plutus reach mainnet. -The word on the street is that it might happen before the end of 2023. +There is potentially still quite a while before these new primitives in plutus reach mainnet. +The word on the street is that it might happen before the end of 2023. -Even sooner, there will be versions of the Cardano node available with the new primitives, +Even sooner, there will be versions of the Cardano node available with the new primitives, and so possibly plumb-able into hydra without causing oneself an aneurysm. In development time that's not so long: we can start thinking about what to build with zk on Cardano. diff --git a/content/posts/hydra-is-cool.md b/content/posts/hydra-is-cool.md index 7bbed18..990ea18 100644 --- a/content/posts/hydra-is-cool.md +++ b/content/posts/hydra-is-cool.md @@ -1,104 +1,104 @@ --- -title: "Hydra is neat: You don't need Hydra" +title: "Hydra is cool: You don't need Hydra" date: 2023-09-20 ---- +--- -## Hydra is neat +## Hydra is cool -Hydra[^1] is a very cool project. It is a layer 2 for Cardano that is _isomorphic_ to the L1. +Hydra[^1] is a very cool project. It is a layer 2 for Cardano that is _isomorphic_ to the L1. Here isomorphic means that Plutus runs in Hydra just like it does on the L1. That dapp you've just toiled over for months to run on the L1 can be put in Hydra and 'just work'. +[^1]: + This post does not distinguish between Hydra and Hydra Head referring to both as Hydra. + If you want to know more about Hydra, then check out their + [explainers](https://hydra.family/head-protocol/core-concepts). + ## Hydra's compromise Hydra boasts it can achieve higher throughput and lower transaction fees compared to the Cardano L1 -as well as near instant settling and no roll-backs. -You may be asking _If my dapp just works on Hydra and it's better in all key respects, +as well as near instant settling and no roll-backs. +You may be asking _If my dapp just works on Hydra and it's better in all key respects, then why don't we all just use Hydra?_. The answer is because these improvements come at a cost. Consensus in Hydra differs from that on the L1. -Hydra doesn't use ouroboros; all participating hydra nodes +Hydra doesn't use ouroboros. Instead all participating hydra nodes must sign-off on all updates to the chain state. -Practically speaking, far fewer nodes can participate in Hydra -and one quiet node stops the whole Hydra chain updating. -Not great for an L1. +Practically speaking, far fewer nodes can participate in Hydra +and one quiet node stops the whole Hydra chain updating. +Not great for an L1. ## You don't need Hydra -Hydra is an example of a way to do state channels. -A state channel relies on the integrity of the L1, while accumulating state separately from it (L2). -At some point the the layers are brought into sync. +Hydra is an example of a way to do state channels. +A state channel relies on the integrity of the L1, while accumulating state separately from it (L2). +At some point the layers are brought into sync. This is when funds on the L1 can be unlocked, and/or the state of the L2 updated. -Hydra could be thought to be providing some future-proofing. +Hydra could be thought to be providing some future-proofing. It is possible for a Hydra instance to run indefinitely -and scripts yet written will be executable in some already running instance. -However, because Hydra's consensus is so brittle the longevity of an instance is not something to depend on. +and Plutus scripts not yet written will be executable in some already running instance. +However, because Hydra's consensus is so brittle the longevity of an instance is not something to depend on. Each and any transaction may be its last. -A key question is when considering Hydra is _Do I need isomorphic-ness?_. +A key question when considering Hydra is _Do I need isomorphic-ness?_. If you know all your business logic before instantiation -then the answer is **no, you don't care for isomorphic-ness**. -Instead, you can roll-your-own L2. It depends on your use case as to how much work that ends up being. +then the answer is **no, you don't care for isomorphic-ness**. +Instead, you can roll-your-own L2. +It depends on your use case as to how much work that ends up being. It can be very simple. - ## You don't want Hydra -In Hydra, the latest agreed state in the L2 is the one that the L1 will accept as the most legitimate. -This is a sensible default. +In Hydra, the latest agreed state in the L2 is the one that the L1 will accept as the most legitimate. +This is a sensible default. Suppose however you have a game of poker where one player learns that they've lost and rage quits. -From the game's perspective, that final transaction should be forced through - the player's loss is inevitable. +From the game's perspective, that final transaction should be forced through - the player's loss is inevitable. At present this isn't possible with Hydra. -If a party doesn't sign then a state isn't valid. +If a party doesn't sign, then a state isn't valid. In another use case, suppose there is some particularly intense on-chain verification -that would be prohibitive on the L1 but that you'd like the results of which to -persist onto the L1 and/or be recovered in future L2 instances. -This could be done with validity tokens but anything minted in the L2 won't persist onto the L1. +that would be prohibitive on the L1 but that you'd like the results of which to +persist onto the L1 and/or be recovered in future L2 instances. +This could be done with validity tokens but anything minted in the L2 won't persist onto the L1. -Another key question then is _What is the right way to sync the L1 and L2 states?_. -Hydra has a way of it doing it which might or might not be appropriate for your use case. -Rolling your own L2 means that the sync logic can fit your business needs. +Another key question then is _What is the right way to sync the L1 and L2 states?_. +Hydra has a way of it doing it which might or might not be appropriate for your use case. +Rolling your own L2 means that the sync logic can fit your business needs. Both the cases above are resolvable with custom sync logic. ## An Example: Subbit.xyz -Probably the simplest, non-trivial example using state channels is [Subbit.xyz][https://subbit.xyz]. -Subbit.xyz is premised on the observation that subscription is very common use case: +Probably the simplest, non-trivial example using state channels is [Subbit.xyz](https://subbit.xyz). +Subbit.xyz is premised on the observation that subscription is a very common use case: there are two parties where one pays the other incrementally. -It sacrifices generality to gain absolutely minimal overhead for both parties. +It sacrifices generality to gain absolutely minimal overhead for both parties. In Subbit.xyz, Alice, a consumer, subscribes to some service of Bob, a provider. Alice instantiates the channel by locking funds, similar to Hydra. There are only two mechanisms for unlocking - one for Alice and the other for Bob. -All logic is known at instantiation. +All logic is known at instantiation. -A consumer needs only to keep track of their account balance, -ascertain the cost of each outgoing request, -and produce valid signatures for a few dozen bytes of data at a time. -They don't need to watch the L1 and its a non-chatty protocol. -The low resource needs opens it up to applications -on intermittently connected user devices such as laptops and mobile, +A consumer needs only to keep track of their account balance, +ascertain the cost of each outgoing request, +and produce valid signatures for a few dozen bytes of data at a time. +They don't need to watch the L1 and it's a non-chatty protocol. +The low resource needs opens it up to applications +on intermittently connected user devices such as laptops and mobile, and even micro-controllers. High throughput remains achievable. -A provider must track each subscriber's account, and periodically check the state of the L1. -This could conceivably be as little as once a week or once a month. +A provider must track each subscriber's account, and periodically check the state of the L1. +This could conceivably be as little as once a week or once a month. The low resource needs for a provider means they have the ability to serve more with less. ## Hydra for QoL -When Hydra reaches a point of maturity that its plug and play, +When Hydra reaches a point of maturity that it's plug and play, it's potentially far easier to deploy with Hydra then roll-your-own L2. Isomorphic-ness gives Hydra incredible flexibility and generality. -You don't need isomorphic-ness but because of it, Hydra could be an easy and convenient solution. - -As for custom sync logic, it is surely the case that there is a tranche on interesting applications where -its far easier and more effective to reuse Hydra infra and modify it than creating your own L2 from scratch. - -[^1]: This post does not distinguish between Hydra and Hydra Head referring to both as Hydra. -If you want to know more about Hydra, then check out their -[explainers](https://hydra.family/head-protocol/core-concepts). +You don't need isomorphic-ness but because of it, Hydra could be an easy and convenient solution. +As for custom sync logic, it is surely the case that there is a tranche of interesting applications where +it's far easier and more effective to reuse Hydra infra and modify it than creating your own L2 from scratch. diff --git a/content/posts/tracing-aiken-build.md b/content/posts/tracing-aiken-build.md index 4ff0d79..98e3a3b 100644 --- a/content/posts/tracing-aiken-build.md +++ b/content/posts/tracing-aiken-build.md @@ -3,160 +3,160 @@ title: Tracing Aiken Build date: 2023-09-02 --- -Aims: +Aims: -> Describe the pipeline and components getting from Aiken to Uplc. +> Describe the pipeline and components getting from Aiken to Uplc. ## The Preface ### Motivations The motivation for writing this came from a desire to add additional features to Aiken not yet available. -One such feature would evaluate an arbitrary function in Aiken callable from JavaScript. -This would help a lot with testing and when trying to align on and off-chain code. +One such feature would evaluate an arbitrary function in Aiken callable from JavaScript. +This would help a lot with testing and when trying to align on and off-chain code. Another more pipe dreamy, ad-hoc function extraction - from a span of code, generate a function. A digression to answer _why would this be at all helpful?!_ Validator logic often needs a broad context throughout. How then to best factor code? -Possible solutions: +Possible solutions: -1. Introduce types / structs +1. Introduce types / structs 2. Have functions with lots of arguments 3. Don't The problems are: 1. Requires relentless constructing and deconstructing across the function call. -This adds costs. -2. Becomes tedious aligning the definition and function call. -3. Ends up with very long validators which are hard to unit test. + This adds costs. +2. Becomes tedious aligning the definition and function call. +3. Ends up with very long validators which are hard to unit test. My current preferred way is to accept that validator functions are long. Ad-hoc function extraction would allow for sections of code to be tested without needing to be factored out. To do either of these, we need to get to grips with the Aiken compilation pipeline. -### This won't age well +### This won't age well -Aiken is undergoing active development. -This post started life with Aiken ~v1.14. -Aiken v1.15 introduced reasonably significant changes to the compilation pipeline. -The word is that there aren't any more big changes in the near future, -but this article will undoubtedly begin to diverge from the current code-base even before publishing. +Aiken is undergoing active development. +This post started life with Aiken ~v1.14. +Aiken v1.15 introduced reasonably significant changes to the compilation pipeline. +The word is that there aren't any more big changes in the near future, +but this article will undoubtedly begin to diverge from the current code-base even before publishing. ### Limitations of narrating code -Narrating code becomes a compromise between being honest and accurate, and being readable and digestible. +Narrating code becomes a compromise between being honest and accurate, and being readable and digestible. The command `aiken build` covers well in excess of 10,000 LoC. The writing of this post ground to a halt as it reached deeper into the code-base. To redeem it, some (possibly large) sections remain black boxes. ## Aiken build -Tracing `aiken build`, the pipeline is roughly: +Tracing `aiken build`, the pipeline is roughly: ```sample - . -> Project::read_source_files -> + . -> Project::read_source_files -> Vec -> Project::parse_sources -> ParsedModules -> Project::type_check -> - CheckedModules -> CodeGenerator::build -> - AirTree -> AirTree::to_vec -> - Vec -> CodeGenerator::uplc_code_gen -> - Program / Term -> serialize -> + CheckedModules -> CodeGenerator::build -> + AirTree -> AirTree::to_vec -> + Vec -> CodeGenerator::uplc_code_gen -> + Program / Term -> serialize -> . ``` We'll pick our way through these steps At a high level we are trying to do something straightforward: reformulate Aiken code as Uplc. -Some Aiken expressions are relatively easy to handle for example an Aiken `Int` goes to an `Int` in Uplc. -Some Aiken expressions require more involved handling, for example an Aiken `If... If Else... Else ` +Some Aiken expressions are relatively easy to handle for example an Aiken `Int` goes to an `Int` in Uplc. +Some Aiken expressions require more involved handling, for example an Aiken `If... If Else... Else ` must have the branches "nested" in Uplc. Aiken has lots of nice-to-haves like pattern matching, modules, and generics; Uplc has none of these. -### The Preamble +### The Preamble #### Cli handling -The cli enters at `aiken/src/cmd/mod.rs` which parses the command. +The cli enters at `aiken/src/cmd/mod.rs` which parses the command. With some establishing of context, the program enters `Project::build` (`crates/aiken-project/src/lib.rs`), -which in turn calls `Project::compile`. +which in turn calls `Project::compile`. #### File crawl -The program looks for Aiken files in both `./lib` and `./validator` sub-directories. -For each it walks over all contents (recursively) looking for `.ak` extensions. -It treats these two sets of files a little differently. +The program looks for Aiken files in both `./lib` and `./validator` sub-directories. +For each it walks over all contents (recursively) looking for `.ak` extensions. +It treats these two sets of files a little differently. For example, only validator files can contain the special validator functions. #### Parse and Type check `Project::parse_sources` parses the module source code. -The heavy lifting is done by `aiken_lang::parser::module`, which is evaluated on each file. +The heavy lifting is done by `aiken_lang::parser::module`, which is evaluated on each file. It produces a `Module` containing a list of parsed definitions of the file: functions, types _etc_, -together with metadata like docstrings and the file path. - -`Project::type_check` inspects the parsed modules and, as the name implies, checks the types. +together with metadata like docstrings and the file path. + +`Project::type_check` inspects the parsed modules and, as the name implies, checks the types. It flags type level warnings and errors and constructs a hash map of `CheckedModule`s. #### Code generator -The code generator `CodeGenerator` (`aiken-lang/src/gen_uplc.rs`) is given -the definitions found from the previous step, -together with the plutus builtins. -It has additional fields for things like debugging. +The code generator `CodeGenerator` (`aiken-lang/src/gen_uplc.rs`) is given +the definitions found from the previous step, +together with the plutus builtins. +It has additional fields for things like debugging. This is handed over to a `Blueprint` (`aiken-project/src/blueprint/mod.rs`). -The blueprint does little more than find the validators on which to run the code gen. +The blueprint does little more than find the validators on which to run the code gen. The heavy lifting is done by `CodeGenerator::generate`. -We are now ready to take the source code and create plutus. +We are now ready to take the source code and create plutus. ### In the air Things become a bit intimidating at this point in terms of sheer lines of code: -`gen_uplc.rs` and three modules in `gen_uplc/` totals > 8500 LoC. +`gen_uplc.rs` and three modules in `gen_uplc/` totals > 8500 LoC. -Aiken has its own _intermediate representation_ called `air` (as in Aiken Intermediate Representation). +Aiken has its own _intermediate representation_ called `air` (as in Aiken Intermediate Representation). Intermediate representations are common in compiled languages. -`Air` is defined in `aiken-lang/src/gen_uplc/air.rs`. -Unsurprisingly, it looks a little bit like a language between Aiken and plutus. +`Air` is defined in `aiken-lang/src/gen_uplc/air.rs`. +Unsurprisingly, it looks a little bit like a language between Aiken and plutus. -In fact, Aiken has another intermediate representation: `AirTree`. -This is constructed between the `TypedExpr` and `Vec` ie between parsed Aiken and air. +In fact, Aiken has another intermediate representation: `AirTree`. +This is constructed between the `TypedExpr` and `Vec` ie between parsed Aiken and air. -#### Climbing the AirTree +#### Climbing the AirTree -Within `CodeGenerator::generate`, `CodeGenerator::build` is called on the function body. +Within `CodeGenerator::generate`, `CodeGenerator::build` is called on the function body. This takes a `TypedExpr` and constructs and returns an `AirTree`. The construction is recursive as it traverses the recursive `TypedExpr` data structure. More on what an airtree is and its construction below. At the same time `self` is treated as `mut`, so we need to keep an eye on this too. -The method which is called and uses this mutability of self is `self.assignment`. +The method which is called and uses this mutability of self is `self.assignment`. It does so by -```sample -- self.assignment - └ self.expect_type_assign +```sample +- self.assignment + └ self.expect_type_assign └ self.code_gen_functions.insert ``` and thus is creating a hashmap of all the functions that appear in the definition. From the call to return of `assign` covers > 600 LoC so we'll leave this as a black box. -(`self.handle_each_clause` is also called with `mut` which in turn calls `self.build` for which `mut` it is needed.) +(`self.handle_each_clause` is also called with `mut` which in turn calls `self.build` for which `mut` it is needed.) Validators in Aiken are boolean functions while in Uplc they are unit-valued (aka void-valued) functions. -Thus the air tree is wrapped such that `false` results in an error (`wrap_validator_condition`). -I don't know why there is a prevailing thought that boolean functions are preferable to functions +Thus the air tree is wrapped such that `false` results in an error (`wrap_validator_condition`). +I don't know why there is a prevailing thought that boolean functions are preferable to functions that error if anything is wrong - which is what validators are. -`check_validator_args` again extends the airtree from the previous step, +`check_validator_args` again extends the airtree from the previous step, and again calls `self.assignment` mutating self. -Something interesting is happening here. +Something interesting is happening here. Script context is the final argument of a validator - for any script purpose. -`check_validator_args` treats the script context like it is an unused argument. +`check_validator_args` treats the script context like it is an unused argument. The importance of this is not immediate, and I've still yet to appreciate why this happens. Let's take a look at what AirTree actually is @@ -172,8 +172,8 @@ pub enum AirTree { } ``` -Note that `AirStatement` and `AirExpression` are mutually recursive definitions with `AirTree`. -Otherwise, it would be unclear from first inspection how tree-like this really is. +Note that `AirStatement` and `AirExpression` are mutually recursive definitions with `AirTree`. +Otherwise, it would be unclear from first inspection how tree-like this really is. `AirExpression` has multiple constructors. These include (non-exhaustive) @@ -183,55 +183,55 @@ Otherwise, it would be unclear from first inspection how tree-like this really i - handling when and if - handling error and tracing -`AirStatement` also has multiple constructors. These include +`AirStatement` also has multiple constructors. These include - let assignments and named function definitions -- handling expect assignments -- pattern matching +- handling expect assignments +- pattern matching - unwrapping data structures -Note that `AirTree` has many methods that are partial functions, -as in there are possible states that are not considered legitimate +Note that `AirTree` has many methods that are partial functions, +as in there are possible states that are not considered legitimate at different points of its construction and use. For example `hoist_over` will throw an error if called on an `Expression`. As `AirTree` is for internal use only, the scope for potential problems is reasonably contained. It seems likely this is to avoid similar-yet-different IRs between steps. -However, the trade off is that it partially obfuscates what is a valid state where. +However, the trade off is that it partially obfuscates what is a valid state where. -What is hoisting? Hoisting gives the airtree depth. +What is hoisting? Hoisting gives the airtree depth. The motivation is that by the time we hit Uplc it is "generally better" -that +that - function definitions appear once rather than being inlined multiple times -- the definition appears as close to use as possible +- the definition appears as close to use as possible -Hoisting creates tree paths. +Hoisting creates tree paths. The final airtree to airtree step, `self.hoist_functions_to_validator`, traverses these paths. -There is a lot of mutating of self, making it quite hard to keep a handle on things. +There is a lot of mutating of self, making it quite hard to keep a handle on things. In all this (several thousand?) LoC, it is essentially ascertaining in which node of the tree -to insert each function definition. +to insert each function definition. In a resource constrained environment like plutus, this effort is warranted. -At the same time this function deals with +At the same time this function deals with - monomophisation - no more generics - erasing opaque types -Neither of which exist at the Uplc level. +Neither of which exist at the Uplc level. #### Into Air -The `to_vec : AirTree -> Vec` is much easier to digest. +The `to_vec : AirTree -> Vec` is much easier to digest. For one, it is not evaluated in the context of the code generator, -and two, there is no mutation of the airtree. +and two, there is no mutation of the airtree. The function recursively takes nodes of the tree and maps them to entries in a mutable vector. It flattens the tree to a vec. -### Down to Uplc +### Down to Uplc Next we go from `Vec -> Term`. -This step is a little more involved than the previous. -For one, this is executed in the context of the code generator. +This step is a little more involved than the previous. +For one, this is executed in the context of the code generator. Moreover, the code generator is treated as mutable - ouch. On further inspection we see that the only mutation is setting `self.needs_field_access = true`. @@ -242,45 +242,45 @@ As noted above, some of the mappings from air to terms are immediate like `Air:: Others are less so. Some examples: -- `Air::Var` require 100 LoC to do case handling on different constructors. +- `Air::Var` require 100 LoC to do case handling on different constructors. - Lists in air have no immediate analogue in uplc -- builtins, as in built-in functions (standard shorthand), have to be mediated -with some combination of `force` and `delay` in order to behave as they should. -- user functions must be "uncurried", ie treated as a sequence of single argument functions, -and recursion must be handled +- builtins, as in built-in functions (standard shorthand), have to be mediated + with some combination of `force` and `delay` in order to behave as they should. +- user functions must be "uncurried", ie treated as a sequence of single argument functions, + and recursion must be handled - Do some magic in order to efficiently allow "record updates". #### Cranking the Optimizer There is a sequence of operations performed on the Uplc, mapping `Term -> Term`. -This removes inconsequential parts of the logic which have been generated, including: +This removes inconsequential parts of the logic which have been generated, including: - removing application of the identity function - directly substituting where apply lambda is applied to a constant or builtin - inline or simplify where apply lambda is applied to a parameter that appears once or not at all -Each of these optimizing methods has a its own relatively narrow focus, +Each of these optimizing methods has a its own relatively narrow focus, and so although there is a fair number of LoC, it's reasonably straightforward to follow. -Some are applied multiple times. +Some are applied multiple times. -### The End +### The End The generated program can now be serialized and included in the blueprint. ### Plutus Core Signposting -All this fuss is to get us to a point where we can write Uplc - and good Uplc at that. +All this fuss is to get us to a point where we can write Uplc - and good Uplc at that. Note that there are many ways to generate code and most of them are bad. -The various design decisions and compilation steps make more sense -when we have a better understanding of the target language. +The various design decisions and compilation steps make more sense +when we have a better understanding of the target language. -Uplc is a lambda calculus. -For a comprehensive definition on Uplc checkout the specification found -[here](https://github.com/input-output-hk/plutus/#specifications-and-design) from the plutus GitHub repo. +Uplc is a lambda calculus. +For a comprehensive definition on Uplc checkout the specification found +[here](https://github.com/input-output-hk/plutus/#specifications-and-design) from the plutus GitHub repo. (I imagine this link will be maintained longer than the current actual link.) -If you're not at all familiar with lambda calculus I recommend +If you're not at all familiar with lambda calculus I recommend [an unpacking](https://crypto.stanford.edu/~blynn/lambda/) by Ben Lynn. ### What next? -I think it would be helpful to have some examples... Watch this space. \ No newline at end of file +I think it would be helpful to have some examples... Watch this space. diff --git a/content/scripts/nav.js b/content/scripts/nav.js index 83347fd..6884c9c 100644 --- a/content/scripts/nav.js +++ b/content/scripts/nav.js @@ -1,15 +1,18 @@ -document.addEventListener('DOMContentLoaded', function () { +document.addEventListener("DOMContentLoaded", function () { // Get all "navbar-burger" elements - var $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0); + var $navbarBurgers = Array.prototype.slice.call( + document.querySelectorAll(".navbar-burger"), + 0, + ); // Check if there are any navbar burgers if ($navbarBurgers.length > 0) { // Add a click event on each of them $navbarBurgers.forEach(function ($el) { - $el.addEventListener('click', function () { + $el.addEventListener("click", function () { // Get the "main-nav" element - var $target = document.getElementById('main-nav'); + var $target = document.getElementById("main-nav"); // Toggle the class on "main-nav" - $target.classList.toggle('hidden'); + $target.classList.toggle("hidden"); }); }); } diff --git a/content/scripts/prism.js b/content/scripts/prism.js index 5341a34..408f00d 100644 --- a/content/scripts/prism.js +++ b/content/scripts/prism.js @@ -1,14 +1,1201 @@ /* PrismJS 1.29.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+haskell+json+nix+racket+rust+scheme */ -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(jg.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); -Prism.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var t={"included-cdata":{pattern://i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace(/__/g,(function(){return a})),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; -!function(s){var e=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|"+e.source+")*?(?:;|(?=\\s*\\{))"),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism); -Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; -Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp("(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])"),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp("((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))"),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute("on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)","javascript")),Prism.languages.js=Prism.languages.javascript; -!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",a={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},n={bash:a,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:n},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:a}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:n},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:n.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:n.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},a.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=n.variable[1].inside,i=0;i^\\\/])(?:--(?:(?=.)[^-!#$%*+=?&@|~.:<>^\\\/].*|$)|\{-[\s\S]*?-\})/m,lookbehind:!0},char:{pattern:/'(?:[^\\']|\\(?:[abfnrtv\\"'&]|\^[A-Z@[\]^_]|ACK|BEL|BS|CAN|CR|DC1|DC2|DC3|DC4|DEL|DLE|EM|ENQ|EOT|ESC|ETB|ETX|FF|FS|GS|HT|LF|NAK|NUL|RS|SI|SO|SOH|SP|STX|SUB|SYN|US|VT|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,alias:"string"},string:{pattern:/"(?:[^\\"]|\\(?:\S|\s+\\))*"/,greedy:!0},keyword:/\b(?:case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,"import-statement":{pattern:/(^[\t ]*)import\s+(?:qualified\s+)?(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*(?:\s+as\s+(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*)?(?:\s+hiding\b)?/m,lookbehind:!0,inside:{keyword:/\b(?:as|hiding|import|qualified)\b/,punctuation:/\./}},builtin:/\b(?:abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0o[0-7]+|0x[0-9a-f]+)\b/i,operator:[{pattern:/`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/,greedy:!0},{pattern:/(\s)\.(?=\s)/,lookbehind:!0},/[-!#$%*+=?&@|~:<>^\\\/][-!#$%*+=?&@|~.:<>^\\\/]*|\.[-!#$%*+=?&@|~.:<>^\\\/]+/],hvariable:{pattern:/\b(?:[A-Z][\w']*\.)*[_a-z][\w']*/,inside:{punctuation:/\./}},constant:{pattern:/\b(?:[A-Z][\w']*\.)*[A-Z][\w']*/,inside:{punctuation:/\./}},punctuation:/[{}[\];(),.:]/},Prism.languages.hs=Prism.languages.haskell; -Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json; -Prism.languages.nix={comment:{pattern:/\/\*[\s\S]*?\*\/|#.*/,greedy:!0},string:{pattern:/"(?:[^"\\]|\\[\s\S])*"|''(?:(?!'')[\s\S]|''(?:'|\\|\$\{))*''/,greedy:!0,inside:{interpolation:{pattern:/(^|(?:^|(?!'').)[^\\])\$\{(?:[^{}]|\{[^}]*\})*\}/,lookbehind:!0,inside:null}}},url:[/\b(?:[a-z]{3,7}:\/\/)[\w\-+%~\/.:#=?&]+/,{pattern:/([^\/])(?:[\w\-+%~.:#=?&]*(?!\/\/)[\w\-+%~\/.:#=?&])?(?!\/\/)\/[\w\-+%~\/.:#=?&]*/,lookbehind:!0}],antiquotation:{pattern:/\$(?=\{)/,alias:"important"},number:/\b\d+\b/,keyword:/\b(?:assert|builtins|else|if|in|inherit|let|null|or|then|with)\b/,function:/\b(?:abort|add|all|any|attrNames|attrValues|baseNameOf|compareVersions|concatLists|currentSystem|deepSeq|derivation|dirOf|div|elem(?:At)?|fetch(?:Tarball|url)|filter(?:Source)?|fromJSON|genList|getAttr|getEnv|hasAttr|hashString|head|import|intersectAttrs|is(?:Attrs|Bool|Function|Int|List|Null|String)|length|lessThan|listToAttrs|map|mul|parseDrvName|pathExists|read(?:Dir|File)|removeAttrs|replaceStrings|seq|sort|stringLength|sub(?:string)?|tail|throw|to(?:File|JSON|Path|String|XML)|trace|typeOf)\b|\bfoldl'\B/,boolean:/\b(?:false|true)\b/,operator:/[=!<>]=?|\+\+?|\|\||&&|\/\/|->?|[?@]/,punctuation:/[{}()[\].,:;]/},Prism.languages.nix.string.inside.interpolation.inside=Prism.languages.nix; -!function(e){e.languages.scheme={comment:/;.*|#;\s*(?:\((?:[^()]|\([^()]*\))*\)|\[(?:[^\[\]]|\[[^\[\]]*\])*\])|#\|(?:[^#|]|#(?!\|)|\|(?!#)|#\|(?:[^#|]|#(?!\|)|\|(?!#))*\|#)*\|#/,string:{pattern:/"(?:[^"\\]|\\.)*"/,greedy:!0},symbol:{pattern:/'[^()\[\]#'\s]+/,greedy:!0},char:{pattern:/#\\(?:[ux][a-fA-F\d]+\b|[-a-zA-Z]+\b|[\uD800-\uDBFF][\uDC00-\uDFFF]|\S)/,greedy:!0},"lambda-parameter":[{pattern:/((?:^|[^'`#])[(\[]lambda\s+)(?:[^|()\[\]'\s]+|\|(?:[^\\|]|\\.)*\|)/,lookbehind:!0},{pattern:/((?:^|[^'`#])[(\[]lambda\s+[(\[])[^()\[\]']+/,lookbehind:!0}],keyword:{pattern:/((?:^|[^'`#])[(\[])(?:begin|case(?:-lambda)?|cond(?:-expand)?|define(?:-library|-macro|-record-type|-syntax|-values)?|defmacro|delay(?:-force)?|do|else|except|export|guard|if|import|include(?:-ci|-library-declarations)?|lambda|let(?:rec)?(?:-syntax|-values|\*)?|let\*-values|only|parameterize|prefix|(?:quasi-?)?quote|rename|set!|syntax-(?:case|rules)|unless|unquote(?:-splicing)?|when)(?=[()\[\]\s]|$)/,lookbehind:!0},builtin:{pattern:/((?:^|[^'`#])[(\[])(?:abs|and|append|apply|assoc|ass[qv]|binary-port\?|boolean=?\?|bytevector(?:-append|-copy|-copy!|-length|-u8-ref|-u8-set!|\?)?|caar|cadr|call-with-(?:current-continuation|port|values)|call\/cc|car|cdar|cddr|cdr|ceiling|char(?:->integer|-ready\?|\?|<\?|<=\?|=\?|>\?|>=\?)|close-(?:input-port|output-port|port)|complex\?|cons|current-(?:error|input|output)-port|denominator|dynamic-wind|eof-object\??|eq\?|equal\?|eqv\?|error|error-object(?:-irritants|-message|\?)|eval|even\?|exact(?:-integer-sqrt|-integer\?|\?)?|expt|features|file-error\?|floor(?:-quotient|-remainder|\/)?|flush-output-port|for-each|gcd|get-output-(?:bytevector|string)|inexact\??|input-port(?:-open\?|\?)|integer(?:->char|\?)|lcm|length|list(?:->string|->vector|-copy|-ref|-set!|-tail|\?)?|make-(?:bytevector|list|parameter|string|vector)|map|max|member|memq|memv|min|modulo|negative\?|newline|not|null\?|number(?:->string|\?)|numerator|odd\?|open-(?:input|output)-(?:bytevector|string)|or|output-port(?:-open\?|\?)|pair\?|peek-char|peek-u8|port\?|positive\?|procedure\?|quotient|raise|raise-continuable|rational\?|rationalize|read-(?:bytevector|bytevector!|char|error\?|line|string|u8)|real\?|remainder|reverse|round|set-c[ad]r!|square|string(?:->list|->number|->symbol|->utf8|->vector|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?|<\?|<=\?|=\?|>\?|>=\?)?|substring|symbol(?:->string|\?|=\?)|syntax-error|textual-port\?|truncate(?:-quotient|-remainder|\/)?|u8-ready\?|utf8->string|values|vector(?:->list|->string|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?)?|with-exception-handler|write-(?:bytevector|char|string|u8)|zero\?)(?=[()\[\]\s]|$)/,lookbehind:!0},operator:{pattern:/((?:^|[^'`#])[(\[])(?:[-+*%/]|[<>]=?|=>?)(?=[()\[\]\s]|$)/,lookbehind:!0},number:{pattern:RegExp(function(e){for(var r in e)e[r]=e[r].replace(/<[\w\s]+>/g,(function(r){return"(?:"+e[r].trim()+")"}));return e[r]}({"":"\\d+(?:/\\d+)|(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[esfdl][+-]?\\d+)?","":"[+-]?|[+-](?:inf|nan)\\.0","":"[+-](?:|(?:inf|nan)\\.0)?i","":"(?:@|)?|","":"(?:#d(?:#[ei])?|#[ei](?:#d)?)?","":"[0-9a-f]+(?:/[0-9a-f]+)?","":"[+-]?|[+-](?:inf|nan)\\.0","":"[+-](?:|(?:inf|nan)\\.0)?i","":"(?:@|)?|","":"#[box](?:#[ei])?|(?:#[ei])?#[box]","":"(^|[()\\[\\]\\s])(?:|)(?=[()\\[\\]\\s]|$)"}),"i"),lookbehind:!0},boolean:{pattern:/(^|[()\[\]\s])#(?:[ft]|false|true)(?=[()\[\]\s]|$)/,lookbehind:!0},function:{pattern:/((?:^|[^'`#])[(\[])(?:[^|()\[\]'\s]+|\|(?:[^\\|]|\\.)*\|)(?=[()\[\]\s]|$)/,lookbehind:!0},identifier:{pattern:/(^|[()\[\]\s])\|(?:[^\\|]|\\.)*\|(?=[()\[\]\s]|$)/,lookbehind:!0,greedy:!0},punctuation:/[()\[\]']/}}(Prism); -Prism.languages.racket=Prism.languages.extend("scheme",{"lambda-parameter":{pattern:/([(\[]lambda\s+[(\[])[^()\[\]'\s]+/,lookbehind:!0}}),Prism.languages.insertBefore("racket","string",{lang:{pattern:/^#lang.+/m,greedy:!0,alias:"keyword"}}),Prism.languages.rkt=Prism.languages.racket; -!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/",t=0;t<2;t++)a=a.replace(//g,(function(){return a}));a=a.replace(//g,(function(){return"[^\\s\\S]"})),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism); +var _self = + "undefined" != typeof window + ? window + : "undefined" != typeof WorkerGlobalScope && + self instanceof WorkerGlobalScope + ? self + : {}, + Prism = (function (e) { + var n = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i, + t = 0, + r = {}, + a = { + manual: e.Prism && e.Prism.manual, + disableWorkerMessageHandler: + e.Prism && e.Prism.disableWorkerMessageHandler, + util: { + encode: function e(n) { + return n instanceof i + ? new i(n.type, e(n.content), n.alias) + : Array.isArray(n) + ? n.map(e) + : n + .replace(/&/g, "&") + .replace(/= g.reach); + A += w.value.length, w = w.next + ) { + var E = w.value; + if (n.length > e.length) return; + if (!(E instanceof i)) { + var P, + L = 1; + if (y) { + if (!(P = l(b, A, e, m)) || P.index >= e.length) break; + var S = P.index, + O = P.index + P[0].length, + j = A; + for (j += w.value.length; S >= j; ) + j += (w = w.next).value.length; + if (((A = j -= w.value.length), w.value instanceof i)) + continue; + for ( + var C = w; + C !== n.tail && (j < O || "string" == typeof C.value); + C = C.next + ) + L++, (j += C.value.length); + L--, (E = e.slice(A, j)), (P.index -= A); + } else if (!(P = l(b, 0, E, m))) continue; + S = P.index; + var N = P[0], + _ = E.slice(0, S), + M = E.slice(S + N.length), + W = A + E.length; + g && W > g.reach && (g.reach = W); + var z = w.prev; + if ( + (_ && ((z = u(n, z, _)), (A += _.length)), + c(n, z, L), + (w = u(n, z, new i(f, p ? a.tokenize(N, p) : N, k, N))), + M && u(n, w, M), + L > 1) + ) { + var I = { cause: f + "," + d, reach: W }; + o(e, n, t, w.prev, A, I), + g && I.reach > g.reach && (g.reach = I.reach); + } + } + } + } + } + } + function s() { + var e = { value: null, prev: null, next: null }, + n = { value: null, prev: e, next: null }; + (e.next = n), (this.head = e), (this.tail = n), (this.length = 0); + } + function u(e, n, t) { + var r = n.next, + a = { value: t, prev: n, next: r }; + return (n.next = a), (r.prev = a), e.length++, a; + } + function c(e, n, t) { + for (var r = n.next, a = 0; a < t && r !== e.tail; a++) r = r.next; + (n.next = r), (r.prev = n), (e.length -= a); + } + if ( + ((e.Prism = a), + (i.stringify = function e(n, t) { + if ("string" == typeof n) return n; + if (Array.isArray(n)) { + var r = ""; + return ( + n.forEach(function (n) { + r += e(n, t); + }), + r + ); + } + var i = { + type: n.type, + content: e(n.content, t), + tag: "span", + classes: ["token", n.type], + attributes: {}, + language: t, + }, + l = n.alias; + l && + (Array.isArray(l) + ? Array.prototype.push.apply(i.classes, l) + : i.classes.push(l)), + a.hooks.run("wrap", i); + var o = ""; + for (var s in i.attributes) + o += + " " + + s + + '="' + + (i.attributes[s] || "").replace(/"/g, """) + + '"'; + return ( + "<" + + i.tag + + ' class="' + + i.classes.join(" ") + + '"' + + o + + ">" + + i.content + + "" + ); + }), + !e.document) + ) + return e.addEventListener + ? (a.disableWorkerMessageHandler || + e.addEventListener( + "message", + function (n) { + var t = JSON.parse(n.data), + r = t.language, + i = t.code, + l = t.immediateClose; + e.postMessage(a.highlight(i, a.languages[r], r)), + l && e.close(); + }, + !1, + ), + a) + : a; + var g = a.util.currentScript(); + function f() { + a.manual || a.highlightAll(); + } + if ( + (g && + ((a.filename = g.src), + g.hasAttribute("data-manual") && (a.manual = !0)), + !a.manual) + ) { + var h = document.readyState; + "loading" === h || ("interactive" === h && g && g.defer) + ? document.addEventListener("DOMContentLoaded", f) + : window.requestAnimationFrame + ? window.requestAnimationFrame(f) + : window.setTimeout(f, 16); + } + return a; + })(_self); +"undefined" != typeof module && module.exports && (module.exports = Prism), + "undefined" != typeof global && (global.Prism = Prism); +(Prism.languages.markup = { + comment: { pattern: //, greedy: !0 }, + prolog: { pattern: /<\?[\s\S]+?\?>/, greedy: !0 }, + doctype: { + pattern: + /"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i, + greedy: !0, + inside: { + "internal-subset": { + pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/, + lookbehind: !0, + greedy: !0, + inside: null, + }, + string: { pattern: /"[^"]*"|'[^']*'/, greedy: !0 }, + punctuation: /^$|[[\]]/, + "doctype-tag": /^DOCTYPE/i, + name: /[^\s<>'"]+/, + }, + }, + cdata: { pattern: //i, greedy: !0 }, + tag: { + pattern: + /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/, + greedy: !0, + inside: { + tag: { + pattern: /^<\/?[^\s>\/]+/, + inside: { punctuation: /^<\/?/, namespace: /^[^\s>\/:]+:/ }, + }, + "special-attr": [], + "attr-value": { + pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, + inside: { + punctuation: [ + { pattern: /^=/, alias: "attr-equals" }, + { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }, + ], + }, + }, + punctuation: /\/?>/, + "attr-name": { + pattern: /[^\s>\/]+/, + inside: { namespace: /^[^\s>\/:]+:/ }, + }, + }, + }, + entity: [ + { pattern: /&[\da-z]{1,8};/i, alias: "named-entity" }, + /&#x?[\da-f]{1,8};/i, + ], +}), + (Prism.languages.markup.tag.inside["attr-value"].inside.entity = + Prism.languages.markup.entity), + (Prism.languages.markup.doctype.inside["internal-subset"].inside = + Prism.languages.markup), + Prism.hooks.add("wrap", function (a) { + "entity" === a.type && + (a.attributes.title = a.content.replace(/&/, "&")); + }), + Object.defineProperty(Prism.languages.markup.tag, "addInlined", { + value: function (a, e) { + var s = {}; + (s["language-" + e] = { + pattern: /(^$)/i, + lookbehind: !0, + inside: Prism.languages[e], + }), + (s.cdata = /^$/i); + var t = { + "included-cdata": { pattern: //i, inside: s }, + }; + t["language-" + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; + var n = {}; + (n[a] = { + pattern: RegExp( + "(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace( + /__/g, + function () { + return a; + }, + ), + "i", + ), + lookbehind: !0, + greedy: !0, + inside: t, + }), + Prism.languages.insertBefore("markup", "cdata", n); + }, + }), + Object.defineProperty(Prism.languages.markup.tag, "addAttribute", { + value: function (a, e) { + Prism.languages.markup.tag.inside["special-attr"].push({ + pattern: RegExp( + "(^|[\"'\\s])(?:" + + a + + ")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))", + "i", + ), + lookbehind: !0, + inside: { + "attr-name": /^[^\s=]+/, + "attr-value": { + pattern: /=[\s\S]+/, + inside: { + value: { + pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/, + lookbehind: !0, + alias: [e, "language-" + e], + inside: Prism.languages[e], + }, + punctuation: [{ pattern: /^=/, alias: "attr-equals" }, /"|'/], + }, + }, + }, + }); + }, + }), + (Prism.languages.html = Prism.languages.markup), + (Prism.languages.mathml = Prism.languages.markup), + (Prism.languages.svg = Prism.languages.markup), + (Prism.languages.xml = Prism.languages.extend("markup", {})), + (Prism.languages.ssml = Prism.languages.xml), + (Prism.languages.atom = Prism.languages.xml), + (Prism.languages.rss = Prism.languages.xml); +!(function (s) { + var e = + /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/; + (s.languages.css = { + comment: /\/\*[\s\S]*?\*\//, + atrule: { + pattern: RegExp( + "@[\\w-](?:[^;{\\s\"']|\\s+(?!\\s)|" + + e.source + + ")*?(?:;|(?=\\s*\\{))", + ), + inside: { + rule: /^@[\w-]+/, + "selector-function-argument": { + pattern: + /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/, + lookbehind: !0, + alias: "selector", + }, + keyword: { + pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/, + lookbehind: !0, + }, + }, + }, + url: { + pattern: RegExp( + "\\burl\\((?:" + e.source + "|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)", + "i", + ), + greedy: !0, + inside: { + function: /^url/i, + punctuation: /^\(|\)$/, + string: { pattern: RegExp("^" + e.source + "$"), alias: "url" }, + }, + }, + selector: { + pattern: RegExp( + "(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|" + + e.source + + ")*(?=\\s*\\{)", + ), + lookbehind: !0, + }, + string: { pattern: e, greedy: !0 }, + property: { + pattern: + /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i, + lookbehind: !0, + }, + important: /!important\b/i, + function: { pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i, lookbehind: !0 }, + punctuation: /[(){};:,]/, + }), + (s.languages.css.atrule.inside.rest = s.languages.css); + var t = s.languages.markup; + t && (t.tag.addInlined("style", "css"), t.tag.addAttribute("style", "css")); +})(Prism); +Prism.languages.clike = { + comment: [ + { pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, lookbehind: !0, greedy: !0 }, + { pattern: /(^|[^\\:])\/\/.*/, lookbehind: !0, greedy: !0 }, + ], + string: { + pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + greedy: !0, + }, + "class-name": { + pattern: + /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i, + lookbehind: !0, + inside: { punctuation: /[.\\]/ }, + }, + keyword: + /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/, + boolean: /\b(?:false|true)\b/, + function: /\b\w+(?=\()/, + number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, + operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, + punctuation: /[{}[\];(),.:]/, +}; +(Prism.languages.javascript = Prism.languages.extend("clike", { + "class-name": [ + Prism.languages.clike["class-name"], + { + pattern: + /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/, + lookbehind: !0, + }, + ], + keyword: [ + { pattern: /((?:^|\})\s*)catch\b/, lookbehind: !0 }, + { + pattern: + /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, + lookbehind: !0, + }, + ], + function: + /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, + number: { + pattern: RegExp( + "(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])", + ), + lookbehind: !0, + }, + operator: + /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/, +})), + (Prism.languages.javascript["class-name"][0].pattern = + /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/), + Prism.languages.insertBefore("javascript", "keyword", { + regex: { + pattern: RegExp( + "((?:^|[^$\\w\\xA0-\\uFFFF.\"'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))", + ), + lookbehind: !0, + greedy: !0, + inside: { + "regex-source": { + pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/, + lookbehind: !0, + alias: "language-regex", + inside: Prism.languages.regex, + }, + "regex-delimiter": /^\/|\/$/, + "regex-flags": /^[a-z]+$/, + }, + }, + "function-variable": { + pattern: + /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/, + alias: "function", + }, + parameter: [ + { + pattern: + /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/, + lookbehind: !0, + inside: Prism.languages.javascript, + }, + { + pattern: + /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i, + lookbehind: !0, + inside: Prism.languages.javascript, + }, + { + pattern: + /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/, + lookbehind: !0, + inside: Prism.languages.javascript, + }, + { + pattern: + /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/, + lookbehind: !0, + inside: Prism.languages.javascript, + }, + ], + constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/, + }), + Prism.languages.insertBefore("javascript", "string", { + hashbang: { pattern: /^#!.*/, greedy: !0, alias: "comment" }, + "template-string": { + pattern: + /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/, + greedy: !0, + inside: { + "template-punctuation": { pattern: /^`|`$/, alias: "string" }, + interpolation: { + pattern: + /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/, + lookbehind: !0, + inside: { + "interpolation-punctuation": { + pattern: /^\$\{|\}$/, + alias: "punctuation", + }, + rest: Prism.languages.javascript, + }, + }, + string: /[\s\S]+/, + }, + }, + "string-property": { + pattern: + /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m, + lookbehind: !0, + greedy: !0, + alias: "property", + }, + }), + Prism.languages.insertBefore("javascript", "operator", { + "literal-property": { + pattern: + /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m, + lookbehind: !0, + alias: "property", + }, + }), + Prism.languages.markup && + (Prism.languages.markup.tag.addInlined("script", "javascript"), + Prism.languages.markup.tag.addAttribute( + "on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)", + "javascript", + )), + (Prism.languages.js = Prism.languages.javascript); +!(function (e) { + var t = + "\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b", + a = { + pattern: /(^(["']?)\w+\2)[ \t]+\S.*/, + lookbehind: !0, + alias: "punctuation", + inside: null, + }, + n = { + bash: a, + environment: { pattern: RegExp("\\$" + t), alias: "constant" }, + variable: [ + { + pattern: /\$?\(\([\s\S]+?\)\)/, + greedy: !0, + inside: { + variable: [ + { pattern: /(^\$\(\([\s\S]+)\)\)/, lookbehind: !0 }, + /^\$\(\(/, + ], + number: + /\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/, + operator: + /--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/, + punctuation: /\(\(?|\)\)?|,|;/, + }, + }, + { + pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/, + greedy: !0, + inside: { variable: /^\$\(|^`|\)$|`$/ }, + }, + { + pattern: /\$\{[^}]+\}/, + greedy: !0, + inside: { + operator: /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/, + punctuation: /[\[\]]/, + environment: { + pattern: RegExp("(\\{)" + t), + lookbehind: !0, + alias: "constant", + }, + }, + }, + /\$(?:\w+|[#?*!@$])/, + ], + entity: + /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/, + }; + (e.languages.bash = { + shebang: { pattern: /^#!\s*\/.*/, alias: "important" }, + comment: { pattern: /(^|[^"{\\$])#.*/, lookbehind: !0 }, + "function-name": [ + { + pattern: /(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/, + lookbehind: !0, + alias: "function", + }, + { pattern: /\b[\w-]+(?=\s*\(\s*\)\s*\{)/, alias: "function" }, + ], + "for-or-select": { + pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/, + alias: "variable", + lookbehind: !0, + }, + "assign-left": { + pattern: /(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/, + inside: { + environment: { + pattern: RegExp("(^|[\\s;|&]|[<>]\\()" + t), + lookbehind: !0, + alias: "constant", + }, + }, + alias: "variable", + lookbehind: !0, + }, + parameter: { + pattern: /(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/, + alias: "variable", + lookbehind: !0, + }, + string: [ + { + pattern: /((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/, + lookbehind: !0, + greedy: !0, + inside: n, + }, + { + pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/, + lookbehind: !0, + greedy: !0, + inside: { bash: a }, + }, + { + pattern: + /(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/, + lookbehind: !0, + greedy: !0, + inside: n, + }, + { pattern: /(^|[^$\\])'[^']*'/, lookbehind: !0, greedy: !0 }, + { + pattern: /\$'(?:[^'\\]|\\[\s\S])*'/, + greedy: !0, + inside: { entity: n.entity }, + }, + ], + environment: { pattern: RegExp("\\$?" + t), alias: "constant" }, + variable: n.variable, + function: { + pattern: + /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/, + lookbehind: !0, + }, + keyword: { + pattern: + /(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/, + lookbehind: !0, + }, + builtin: { + pattern: + /(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/, + lookbehind: !0, + alias: "class-name", + }, + boolean: { + pattern: /(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/, + lookbehind: !0, + }, + "file-descriptor": { pattern: /\B&\d\b/, alias: "important" }, + operator: { + pattern: + /\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/, + inside: { "file-descriptor": { pattern: /^\d/, alias: "important" } }, + }, + punctuation: /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/, + number: { pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/, lookbehind: !0 }, + }), + (a.inside = e.languages.bash); + for ( + var s = [ + "comment", + "function-name", + "for-or-select", + "assign-left", + "parameter", + "string", + "environment", + "function", + "keyword", + "builtin", + "boolean", + "file-descriptor", + "operator", + "punctuation", + "number", + ], + o = n.variable[1].inside, + i = 0; + i < s.length; + i++ + ) + o[s[i]] = e.languages.bash[s[i]]; + (e.languages.sh = e.languages.bash), (e.languages.shell = e.languages.bash); +})(Prism); +(Prism.languages.haskell = { + comment: { + pattern: + /(^|[^-!#$%*+=?&@|~.:<>^\\\/])(?:--(?:(?=.)[^-!#$%*+=?&@|~.:<>^\\\/].*|$)|\{-[\s\S]*?-\})/m, + lookbehind: !0, + }, + char: { + pattern: + /'(?:[^\\']|\\(?:[abfnrtv\\"'&]|\^[A-Z@[\]^_]|ACK|BEL|BS|CAN|CR|DC1|DC2|DC3|DC4|DEL|DLE|EM|ENQ|EOT|ESC|ETB|ETX|FF|FS|GS|HT|LF|NAK|NUL|RS|SI|SO|SOH|SP|STX|SUB|SYN|US|VT|\d+|o[0-7]+|x[0-9a-fA-F]+))'/, + alias: "string", + }, + string: { pattern: /"(?:[^\\"]|\\(?:\S|\s+\\))*"/, greedy: !0 }, + keyword: + /\b(?:case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/, + "import-statement": { + pattern: + /(^[\t ]*)import\s+(?:qualified\s+)?(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*(?:\s+as\s+(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*)?(?:\s+hiding\b)?/m, + lookbehind: !0, + inside: { + keyword: /\b(?:as|hiding|import|qualified)\b/, + punctuation: /\./, + }, + }, + builtin: + /\b(?:abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/, + number: /\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0o[0-7]+|0x[0-9a-f]+)\b/i, + operator: [ + { pattern: /`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/, greedy: !0 }, + { pattern: /(\s)\.(?=\s)/, lookbehind: !0 }, + /[-!#$%*+=?&@|~:<>^\\\/][-!#$%*+=?&@|~.:<>^\\\/]*|\.[-!#$%*+=?&@|~.:<>^\\\/]+/, + ], + hvariable: { + pattern: /\b(?:[A-Z][\w']*\.)*[_a-z][\w']*/, + inside: { punctuation: /\./ }, + }, + constant: { + pattern: /\b(?:[A-Z][\w']*\.)*[A-Z][\w']*/, + inside: { punctuation: /\./ }, + }, + punctuation: /[{}[\];(),.:]/, +}), + (Prism.languages.hs = Prism.languages.haskell); +(Prism.languages.json = { + property: { + pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, + lookbehind: !0, + greedy: !0, + }, + string: { + pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/, + lookbehind: !0, + greedy: !0, + }, + comment: { pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/, greedy: !0 }, + number: /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i, + punctuation: /[{}[\],]/, + operator: /:/, + boolean: /\b(?:false|true)\b/, + null: { pattern: /\bnull\b/, alias: "keyword" }, +}), + (Prism.languages.webmanifest = Prism.languages.json); +(Prism.languages.nix = { + comment: { pattern: /\/\*[\s\S]*?\*\/|#.*/, greedy: !0 }, + string: { + pattern: /"(?:[^"\\]|\\[\s\S])*"|''(?:(?!'')[\s\S]|''(?:'|\\|\$\{))*''/, + greedy: !0, + inside: { + interpolation: { + pattern: /(^|(?:^|(?!'').)[^\\])\$\{(?:[^{}]|\{[^}]*\})*\}/, + lookbehind: !0, + inside: null, + }, + }, + }, + url: [ + /\b(?:[a-z]{3,7}:\/\/)[\w\-+%~\/.:#=?&]+/, + { + pattern: + /([^\/])(?:[\w\-+%~.:#=?&]*(?!\/\/)[\w\-+%~\/.:#=?&])?(?!\/\/)\/[\w\-+%~\/.:#=?&]*/, + lookbehind: !0, + }, + ], + antiquotation: { pattern: /\$(?=\{)/, alias: "important" }, + number: /\b\d+\b/, + keyword: /\b(?:assert|builtins|else|if|in|inherit|let|null|or|then|with)\b/, + function: + /\b(?:abort|add|all|any|attrNames|attrValues|baseNameOf|compareVersions|concatLists|currentSystem|deepSeq|derivation|dirOf|div|elem(?:At)?|fetch(?:Tarball|url)|filter(?:Source)?|fromJSON|genList|getAttr|getEnv|hasAttr|hashString|head|import|intersectAttrs|is(?:Attrs|Bool|Function|Int|List|Null|String)|length|lessThan|listToAttrs|map|mul|parseDrvName|pathExists|read(?:Dir|File)|removeAttrs|replaceStrings|seq|sort|stringLength|sub(?:string)?|tail|throw|to(?:File|JSON|Path|String|XML)|trace|typeOf)\b|\bfoldl'\B/, + boolean: /\b(?:false|true)\b/, + operator: /[=!<>]=?|\+\+?|\|\||&&|\/\/|->?|[?@]/, + punctuation: /[{}()[\].,:;]/, +}), + (Prism.languages.nix.string.inside.interpolation.inside = + Prism.languages.nix); +!(function (e) { + e.languages.scheme = { + comment: + /;.*|#;\s*(?:\((?:[^()]|\([^()]*\))*\)|\[(?:[^\[\]]|\[[^\[\]]*\])*\])|#\|(?:[^#|]|#(?!\|)|\|(?!#)|#\|(?:[^#|]|#(?!\|)|\|(?!#))*\|#)*\|#/, + string: { pattern: /"(?:[^"\\]|\\.)*"/, greedy: !0 }, + symbol: { pattern: /'[^()\[\]#'\s]+/, greedy: !0 }, + char: { + pattern: + /#\\(?:[ux][a-fA-F\d]+\b|[-a-zA-Z]+\b|[\uD800-\uDBFF][\uDC00-\uDFFF]|\S)/, + greedy: !0, + }, + "lambda-parameter": [ + { + pattern: + /((?:^|[^'`#])[(\[]lambda\s+)(?:[^|()\[\]'\s]+|\|(?:[^\\|]|\\.)*\|)/, + lookbehind: !0, + }, + { + pattern: /((?:^|[^'`#])[(\[]lambda\s+[(\[])[^()\[\]']+/, + lookbehind: !0, + }, + ], + keyword: { + pattern: + /((?:^|[^'`#])[(\[])(?:begin|case(?:-lambda)?|cond(?:-expand)?|define(?:-library|-macro|-record-type|-syntax|-values)?|defmacro|delay(?:-force)?|do|else|except|export|guard|if|import|include(?:-ci|-library-declarations)?|lambda|let(?:rec)?(?:-syntax|-values|\*)?|let\*-values|only|parameterize|prefix|(?:quasi-?)?quote|rename|set!|syntax-(?:case|rules)|unless|unquote(?:-splicing)?|when)(?=[()\[\]\s]|$)/, + lookbehind: !0, + }, + builtin: { + pattern: + /((?:^|[^'`#])[(\[])(?:abs|and|append|apply|assoc|ass[qv]|binary-port\?|boolean=?\?|bytevector(?:-append|-copy|-copy!|-length|-u8-ref|-u8-set!|\?)?|caar|cadr|call-with-(?:current-continuation|port|values)|call\/cc|car|cdar|cddr|cdr|ceiling|char(?:->integer|-ready\?|\?|<\?|<=\?|=\?|>\?|>=\?)|close-(?:input-port|output-port|port)|complex\?|cons|current-(?:error|input|output)-port|denominator|dynamic-wind|eof-object\??|eq\?|equal\?|eqv\?|error|error-object(?:-irritants|-message|\?)|eval|even\?|exact(?:-integer-sqrt|-integer\?|\?)?|expt|features|file-error\?|floor(?:-quotient|-remainder|\/)?|flush-output-port|for-each|gcd|get-output-(?:bytevector|string)|inexact\??|input-port(?:-open\?|\?)|integer(?:->char|\?)|lcm|length|list(?:->string|->vector|-copy|-ref|-set!|-tail|\?)?|make-(?:bytevector|list|parameter|string|vector)|map|max|member|memq|memv|min|modulo|negative\?|newline|not|null\?|number(?:->string|\?)|numerator|odd\?|open-(?:input|output)-(?:bytevector|string)|or|output-port(?:-open\?|\?)|pair\?|peek-char|peek-u8|port\?|positive\?|procedure\?|quotient|raise|raise-continuable|rational\?|rationalize|read-(?:bytevector|bytevector!|char|error\?|line|string|u8)|real\?|remainder|reverse|round|set-c[ad]r!|square|string(?:->list|->number|->symbol|->utf8|->vector|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?|<\?|<=\?|=\?|>\?|>=\?)?|substring|symbol(?:->string|\?|=\?)|syntax-error|textual-port\?|truncate(?:-quotient|-remainder|\/)?|u8-ready\?|utf8->string|values|vector(?:->list|->string|-append|-copy|-copy!|-fill!|-for-each|-length|-map|-ref|-set!|\?)?|with-exception-handler|write-(?:bytevector|char|string|u8)|zero\?)(?=[()\[\]\s]|$)/, + lookbehind: !0, + }, + operator: { + pattern: /((?:^|[^'`#])[(\[])(?:[-+*%/]|[<>]=?|=>?)(?=[()\[\]\s]|$)/, + lookbehind: !0, + }, + number: { + pattern: RegExp( + (function (e) { + for (var r in e) + e[r] = e[r].replace(/<[\w\s]+>/g, function (r) { + return "(?:" + e[r].trim() + ")"; + }); + return e[r]; + })({ + "": + "\\d+(?:/\\d+)|(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[esfdl][+-]?\\d+)?", + "": "[+-]?|[+-](?:inf|nan)\\.0", + "": "[+-](?:|(?:inf|nan)\\.0)?i", + "": + "(?:@|)?|", + "": "(?:#d(?:#[ei])?|#[ei](?:#d)?)?", + "": "[0-9a-f]+(?:/[0-9a-f]+)?", + "": "[+-]?|[+-](?:inf|nan)\\.0", + "": "[+-](?:|(?:inf|nan)\\.0)?i", + "": + "(?:@|)?|", + "": "#[box](?:#[ei])?|(?:#[ei])?#[box]", + "": + "(^|[()\\[\\]\\s])(?:|)(?=[()\\[\\]\\s]|$)", + }), + "i", + ), + lookbehind: !0, + }, + boolean: { + pattern: /(^|[()\[\]\s])#(?:[ft]|false|true)(?=[()\[\]\s]|$)/, + lookbehind: !0, + }, + function: { + pattern: + /((?:^|[^'`#])[(\[])(?:[^|()\[\]'\s]+|\|(?:[^\\|]|\\.)*\|)(?=[()\[\]\s]|$)/, + lookbehind: !0, + }, + identifier: { + pattern: /(^|[()\[\]\s])\|(?:[^\\|]|\\.)*\|(?=[()\[\]\s]|$)/, + lookbehind: !0, + greedy: !0, + }, + punctuation: /[()\[\]']/, + }; +})(Prism); +(Prism.languages.racket = Prism.languages.extend("scheme", { + "lambda-parameter": { + pattern: /([(\[]lambda\s+[(\[])[^()\[\]'\s]+/, + lookbehind: !0, + }, +})), + Prism.languages.insertBefore("racket", "string", { + lang: { pattern: /^#lang.+/m, greedy: !0, alias: "keyword" }, + }), + (Prism.languages.rkt = Prism.languages.racket); +!(function (e) { + for (var a = "/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/", t = 0; t < 2; t++) + a = a.replace(//g, function () { + return a; + }); + (a = a.replace(//g, function () { + return "[^\\s\\S]"; + })), + (e.languages.rust = { + comment: [ + { pattern: RegExp("(^|[^\\\\])" + a), lookbehind: !0, greedy: !0 }, + { pattern: /(^|[^\\:])\/\/.*/, lookbehind: !0, greedy: !0 }, + ], + string: { + pattern: /b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/, + greedy: !0, + }, + char: { + pattern: + /b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/, + greedy: !0, + }, + attribute: { + pattern: /#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/, + greedy: !0, + alias: "attr-name", + inside: { string: null }, + }, + "closure-params": { + pattern: /([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/, + lookbehind: !0, + greedy: !0, + inside: { + "closure-punctuation": { pattern: /^\||\|$/, alias: "punctuation" }, + rest: null, + }, + }, + "lifetime-annotation": { pattern: /'\w+/, alias: "symbol" }, + "fragment-specifier": { + pattern: /(\$\w+:)[a-z]+/, + lookbehind: !0, + alias: "punctuation", + }, + variable: /\$\w+/, + "function-definition": { + pattern: /(\bfn\s+)\w+/, + lookbehind: !0, + alias: "function", + }, + "type-definition": { + pattern: /(\b(?:enum|struct|trait|type|union)\s+)\w+/, + lookbehind: !0, + alias: "class-name", + }, + "module-declaration": [ + { + pattern: /(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/, + lookbehind: !0, + alias: "namespace", + }, + { + pattern: + /(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/, + lookbehind: !0, + alias: "namespace", + inside: { punctuation: /::/ }, + }, + ], + keyword: [ + /\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/, + /\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/, + ], + function: /\b[a-z_]\w*(?=\s*(?:::\s*<|\())/, + macro: { pattern: /\b\w+!/, alias: "property" }, + constant: /\b[A-Z_][A-Z_\d]+\b/, + "class-name": /\b[A-Z]\w*\b/, + namespace: { + pattern: /(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/, + inside: { punctuation: /::/ }, + }, + number: + /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/, + boolean: /\b(?:false|true)\b/, + punctuation: /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/, + operator: /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/, + }), + (e.languages.rust["closure-params"].inside.rest = e.languages.rust), + (e.languages.rust.attribute.inside.string = e.languages.rust.string); +})(Prism); diff --git a/flake.lock b/flake.lock index c3359ae..56d02ca 100644 --- a/flake.lock +++ b/flake.lock @@ -2,15 +2,14 @@ "nodes": { "devshell": { "inputs": { - "nixpkgs": "nixpkgs", - "systems": "systems" + "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1688380630, - "narHash": "sha256-8ilApWVb1mAi4439zS3iFeIT0ODlbrifm/fegWwgHjA=", + "lastModified": 1735644329, + "narHash": "sha256-tO3HrHriyLvipc4xr+Ewtdlo7wM1OjXNjlWRgmM7peY=", "owner": "numtide", "repo": "devshell", - "rev": "f9238ec3d75cefbb2b42a44948c4e8fb1ae9a205", + "rev": "f7795ede5b02664b57035b3b757876703e2c3eac", "type": "github" }, "original": { @@ -24,11 +23,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1683560683, - "narHash": "sha256-XAygPMN5Xnk/W2c1aW0jyEa6lfMDZWlQgiNtmHXytPc=", + "lastModified": 1738453229, + "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "006c75898cf814ef9497252b022e91c946ba8e17", + "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", "type": "github" }, "original": { @@ -38,11 +37,11 @@ }, "flake-root": { "locked": { - "lastModified": 1680964220, - "narHash": "sha256-dIdTYcf+KW9a4pKHsEbddvLVSfR1yiAJynzg2x0nfWg=", + "lastModified": 1723604017, + "narHash": "sha256-rBtQ8gg+Dn4Sx/s+pvjdq3CB2wQNzx9XGFq/JVGCB6k=", "owner": "srid", "repo": "flake-root", - "rev": "f1c0b93d05bdbea6c011136ba1a135c80c5b326c", + "rev": "b759a56851e10cb13f6b8e5698af7b59c44be26e", "type": "github" }, "original": { @@ -53,11 +52,11 @@ }, "haskell-flake": { "locked": { - "lastModified": 1684180957, - "narHash": "sha256-qtEZf4gcmQU5ePbFtltqpAS0PajWLURVC7nuoS46dSk=", + "lastModified": 1739669127, + "narHash": "sha256-2s3wYTqKq7aBa41VHWg/G2XAOii8MW+WAMtLdgy1cek=", "owner": "srid", "repo": "haskell-flake", - "rev": "4e1c76de8795608bb47295c018b37a563c492fd2", + "rev": "eabf8cf32e5f6a267ea637e1b3eabc9b7ddf29e1", "type": "github" }, "original": { @@ -68,11 +67,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1677383253, - "narHash": "sha256-UfpzWfSxkfXHnb4boXZNaKsAcUrZT9Hw+tao1oZxd08=", + "lastModified": 1722073938, + "narHash": "sha256-OpX0StkL8vpXyWOGUD6G+MA26wAXK6SpT94kLJXo6B4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9952d6bc395f5841262b006fbace8dd7e143b634", + "rev": "e36e9f57337d0ff0cf77aceb58af4c805472bfae", "type": "github" }, "original": { @@ -84,29 +83,23 @@ }, "nixpkgs-lib": { "locked": { - "dir": "lib", - "lastModified": 1682879489, - "narHash": "sha256-sASwo8gBt7JDnOOstnps90K1wxmVfyhsTPPNTGBPjjg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0", - "type": "github" + "lastModified": 1738452942, + "narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" }, "original": { - "dir": "lib", - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" } }, "nixpkgs_2": { "locked": { - "lastModified": 1684385584, - "narHash": "sha256-O7y0gK8OLIDqz+LaHJJyeu09IGiXlZIS3+JgEzGmmJA=", + "lastModified": 1739446958, + "narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "48a0fb7aab511df92a17cf239c37f2bd2ec9ae3a", + "rev": "2ff53fe64443980e139eaa286017f53f88336dd0", "type": "github" }, "original": { @@ -118,16 +111,16 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1680945546, - "narHash": "sha256-8FuaH5t/aVi/pR1XxnF0qi4WwMYC+YxlfdsA0V+TEuQ=", + "lastModified": 1735554305, + "narHash": "sha256-zExSA1i/b+1NMRhGGLtNfFGXgLtgo+dcuzHzaWA6w3Q=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d9f759f2ea8d265d974a6e1259bd510ac5844c5d", + "rev": "0e82ab234249d8eee3e8c91437802b32c74bb3fd", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-unstable", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } @@ -142,31 +135,16 @@ "treefmt-nix": "treefmt-nix" } }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "treefmt-nix": { "inputs": { "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1684416994, - "narHash": "sha256-KkZ9diPRl3Y05TngWYs/QhZKnI/3tA3s+2Hhmei8FnE=", + "lastModified": 1738953846, + "narHash": "sha256-yrK3Hjcr8F7qS/j2F+r7C7o010eVWWlm4T1PrbKBOxQ=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "42045102f90cfd23ca44ae4ef8362180fefcd7fd", + "rev": "4f09b473c936d41582dd744e19f34ec27592c5fd", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index c2bfaa3..66b7127 100644 --- a/flake.nix +++ b/flake.nix @@ -28,10 +28,11 @@ # system. haskellProjects.default = { - # packages.haskell-template.root = ./.; # Auto-discovered by haskell-flake - overrides = self: super: { }; devShell = { tools = hp: { + fourmolu = hp.fourmolu; + hoogle = hp.hoogle; + haskell-language-server = hp.haskell-language-server; treefmt = config.treefmt.build.wrapper; } // config.treefmt.build.programs; hlsCheck.enable = false; @@ -59,27 +60,53 @@ "-XImportQualifiedPost" ]; }; - + programs.prettier.enable = true; }; # Equivalent to inputs'.nixpkgs.legacyPackages.hello; - devShells.default = pkgs.mkShell { - inputsFrom = [ - config.haskellProjects.default.outputs.devShell - config.flake-root.devShell - ]; - packages = with pkgs; [ - caddy - nil - nodePackages_latest.vscode-langservers-extracted - nodePackages_latest.tailwindcss - nodePackages_latest.typescript-language-server - haskellPackages.hakyll - zlib - ]; - }; + devShells.default = + let + menu = pkgs.writeShellScriptBin "menu" + '' + echo -e "\nCommands available: \n${ + builtins.foldl' (x: y: x + " -> " + (pkgs.lib.getName y) + "\n") "" my-packages + }" + ''; + my-packages = [ + menu + build + watch + deploy + ]; + build = pkgs.writeShellScriptBin "build" '' + tailwindcss -i ./content/css/main.css -o ./content/css/mini.css --minify + cabal run site -- build + ''; + watch = pkgs.writeShellScriptBin "watch" '' + tailwindcss -i ./content/css/main.css -o ./content/css/mini.css --minify + cabal run site -- watch + ''; + deploy = pkgs.writeShellScriptBin "deploy" '' + rsync -r --delete ./docs/* genesis:/var/www/kompactio-landing/ + ''; + in + pkgs.mkShell { + inputsFrom = [ + config.haskellProjects.default.outputs.devShell + config.flake-root.devShell + ]; + packages = with pkgs; [ + caddy + nil + nodePackages_latest.vscode-langservers-extracted + nodePackages_latest.tailwindcss + nodePackages_latest.typescript-language-server + haskellPackages.hakyll + zlib + ] ++ my-packages; + }; }; flake = { # The usual flake attributes can be defined here, including system- diff --git a/kompact-landing.cabal b/kompact-landing.cabal deleted file mode 100644 index b9159f5..0000000 --- a/kompact-landing.cabal +++ /dev/null @@ -1,13 +0,0 @@ -name: example -version: 0.1.0.0 -build-type: Simple -cabal-version: >= 1.10 - -executable site - main-is: site.hs - build-depends: base == 4.* - , hakyll == 4.15.* - , hip == 1.5.* - , filepath - ghc-options: -threaded -rtsopts -with-rtsopts=-N - default-language: Haskell2010 diff --git a/site.cabal b/site.cabal new file mode 100644 index 0000000..4d48400 --- /dev/null +++ b/site.cabal @@ -0,0 +1,15 @@ +name: site +version: 0.1.0.0 +build-type: Simple +cabal-version: >=1.10 + +executable site + main-is: site.hs + build-depends: + base >=4 && <5 + , filepath + , hakyll >=4.16 && <4.17 + , hip >=1.5 && <1.6 + + ghc-options: -threaded -rtsopts -with-rtsopts=-N + default-language: Haskell2010 diff --git a/site.hs b/site.hs index 6392b50..eab1990 100644 --- a/site.hs +++ b/site.hs @@ -1,9 +1,9 @@ -------------------------------------------------------------------------------- {-# LANGUAGE OverloadedStrings #-} -import Data.Monoid (mappend) -import Hakyll -import System.FilePath (splitExtension, joinPath, splitDirectories, replaceExtension) +import Data.Monoid (mappend) +import Hakyll +import System.FilePath (joinPath, replaceExtension, splitDirectories, splitExtension) -------------------------------------------------------------------------------- main :: IO () @@ -17,38 +17,43 @@ main = hakyll $ do compile copyFileCompiler match "content/scripts/*" $ do - route rmPrefix + route rmPrefix compile copyFileCompiler match "content/css/*" $ do - route rmPrefix + route rmPrefix compile compressCssCompiler match "content/fonts/*" $ do - route rmPrefix + route rmPrefix compile copyFileCompiler match "content/posts/*.md" $ do route rmPrefixMd - compile $ pandocCompiler - >>= loadAndApplyTemplate "templates/post.html" postCtx - >>= loadAndApplyTemplate "templates/default.html" postCtx - >>= relativizeUrls + compile $ + pandocCompiler + >>= loadAndApplyTemplate "templates/post.html" postCtx + >>= loadAndApplyTemplate "templates/default.html" postCtx + >>= relativizeUrls create ["blog.html"] $ do route idRoute compile $ do posts <- recentFirst =<< loadAll "content/posts/*.md" let archiveCtx = - listField "posts" postCtx (return posts) `mappend` - constField "title" "Blog" `mappend` - defaultContext + listField "posts" postCtx (return posts) + `mappend` constField "title" "Blog" + `mappend` defaultContext makeItem "" >>= loadAndApplyTemplate "templates/blog.html" archiveCtx >>= loadAndApplyTemplate "templates/default.html" archiveCtx >>= relativizeUrls + -- match "content/index/*" $ do + -- compile $ + -- pandocCompilerWith x + match "content/index.md" $ do route rmPrefixMd @@ -63,18 +68,17 @@ main = hakyll $ do match "templates/*" $ compile templateBodyCompiler - -------------------------------------------------------------------------------- postCtx :: Context String postCtx = - dateField "date" "%Y-%m-%d" `mappend` - defaultContext + dateField "date" "%Y-%m-%d" + `mappend` defaultContext setExtensionInner :: String -> FilePath -> FilePath setExtensionInner = flip replaceExtension rmPrefixInner :: FilePath -> FilePath -rmPrefixInner = joinPath . tail . splitDirectories +rmPrefixInner = joinPath . tail . splitDirectories rmPrefix :: Routes rmPrefix = customRoute $ rmPrefixInner . toFilePath diff --git a/tailwind.config.js b/tailwind.config.js index 09222ae..5b6a472 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,19 +1,15 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - "./content/**/*.{html,js}", - "./templates/**/*.{html,js}", - ], + content: ["./content/**/*.{html,js}", "./templates/**/*.{html,js}"], theme: { extend: {}, fontFamily: { - 'sans' : ['jetbrains-mono',], + sans: ["jetbrains-mono"], }, typography: (theme) => ({}), }, - darkMode: 'class', + darkMode: "class", variants: {}, // plugins: [require('@tailwindcss/typography')], plugins: [], -} - +}; diff --git a/templates/about.html b/templates/about.html index 8e04a7f..04ceb23 100644 --- a/templates/about.html +++ b/templates/about.html @@ -1,27 +1,15 @@
-
- # about -
+
# about
- Kompact.io is dapp dev house. - - Our focus: + Kompact.io is dapp dev house. Our focus:
    -
  • - safety-first -
  • -
  • - fast turn around -
  • -
  • - integration support -
  • +
  • safety-first
  • +
  • fast turn around
  • +
  • integration support
Our typical process: -
- Idea -> Spec -> Impl -> Test -> Handover -
+
Idea -> Spec -> Impl -> Test -> Handover
-
\ No newline at end of file + diff --git a/templates/blog.html b/templates/blog.html index 5349dac..a1774b2 100644 --- a/templates/blog.html +++ b/templates/blog.html @@ -1,7 +1,5 @@
-
- # blog -
+
# blog
A nascent initiative sharing some of the things happening at Kompact.io.
@@ -9,4 +7,4 @@
$partial("templates/post-list.html")$ -
\ No newline at end of file +
diff --git a/templates/contact.html b/templates/contact.html index 28f6cac..92f8d77 100644 --- a/templates/contact.html +++ b/templates/contact.html @@ -1,11 +1,10 @@
-
- # contact -
+
# contact
- Questions? We'll be happy to help answer any of your questions. Send us an email and we'll get back to you shortly. + Questions? We'll be happy to help answer any of your questions. Send us an + email and we'll get back to you shortly.
Reach us on : kompactio@proton.me
-
\ No newline at end of file + diff --git a/templates/default.html b/templates/default.html index e042072..3f599ad 100644 --- a/templates/default.html +++ b/templates/default.html @@ -1,42 +1,41 @@ - - - - - - - - $title$ - - - } - updateTheme() - + +
+
+ $partial("templates/nav.html")$ +
+ $body$ +
+ $partial("templates/footer.html")$ +
+ - -
-
- $partial("templates/nav.html")$ -
- $body$ -
- $partial("templates/footer.html")$ -
- - - - - \ No newline at end of file + + diff --git a/templates/footer.html b/templates/footer.html index 4d1391d..c2e3a2b 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -1,22 +1,34 @@ - diff --git a/templates/hero.html b/templates/hero.html index fe8b73c..019adc2 100644 --- a/templates/hero.html +++ b/templates/hero.html @@ -1,12 +1,13 @@
-
- ⟨K⟩ -
+
⟨K⟩
-
withKompact $ do
-
· · dapp <- lean dev
-
· · run dapp
+
+ withKompact $ + do
+
· · dapp <- lean dev
+
· · run dapp
-
\ No newline at end of file + + diff --git a/templates/index.html b/templates/index.html index 11349d4..9a52f09 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,4 +4,4 @@ $partial("templates/services.html")$
$partial("templates/pricing.html")$
-$partial("templates/contact.html")$ \ No newline at end of file +$partial("templates/contact.html")$ diff --git a/templates/nav.html b/templates/nav.html index 67bdac9..bbb7765 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -9,7 +9,8 @@
- \ No newline at end of file + diff --git a/templates/post-list.html b/templates/post-list.html index 6e542ec..e0dcf2e 100644 --- a/templates/post-list.html +++ b/templates/post-list.html @@ -2,11 +2,9 @@ $for(posts)$
  • - - $date$ :: - + $date$ :: $title$
  • $endfor$ - \ No newline at end of file + diff --git a/templates/post.html b/templates/post.html index 6a9887f..b2653e4 100644 --- a/templates/post.html +++ b/templates/post.html @@ -1,20 +1,11 @@
    -

    - $title$ -

    +

    $title$

    $if(date)$ -

    - Posted on $date$ -

    - $endif$ - $if(author)$ -

    - by $author$ -

    +

    Posted on $date$

    + $endif$ $if(author)$ +

    by $author$

    $endif$
    -
    - $body$ -
    -
    \ No newline at end of file +
    $body$
    + diff --git a/templates/pricing.html b/templates/pricing.html index 0d5cd8f..a92c0f1 100644 --- a/templates/pricing.html +++ b/templates/pricing.html @@ -1,46 +1,39 @@
    -
    - # pricing -
    +
    # pricing
    - Plutus development has traditionally meant long development schedules, and expensive ( $ 25k+/mo FTE) engineers. - We can work with you at competitive rates in either deliverable or retainer based engagements. + Plutus development has traditionally meant long development schedules, and + expensive ( $ 25k+/mo FTE) engineers. We can work with you at + competitive rates in either deliverable or retainer based engagements.
    -
    -
    -
    - ## retainer -
    -
    - Time-based -
    -
    +
    +
    +
    ## retainer
    +

    Time-based

    +

    Still figuring out your project scope? -

    -
    +

    +

    Need an extra pair of hands on an existing project? -

    -
    +

    +

    Then a retainer based engagement is for you. -

    +

    -
    -
    - ## deliverable -
    -
    - Output-based -
    -
    +
    +
    ## deliverable
    +

    Output-based

    +

    You know what you want and need help implementing it? -

    -
    +

    +

    We'll first produce a spec on how the dapp will operate technically. - This involves discussing different options and trade-offs on things from UX to validator complexity. -

    -
    - Once settled we'll begin the implementation phase and finally integration phase. -
    + This involves discussing different options and trade-offs on things from + UX to validator complexity. +

    +

    + Once settled we'll begin the implementation phase and finally + integration phase. +

    -
    \ No newline at end of file + diff --git a/templates/services.html b/templates/services.html index d908598..303d007 100644 --- a/templates/services.html +++ b/templates/services.html @@ -1,35 +1,30 @@
    -
    - # services -
    +
    # services
    - We are cardano native dapp dev outfit focused on helping you going from 0 to launch ASAP. + We are cardano native dapp dev outfit focused on helping you going from 0 to + launch ASAP.
    -
    - ## strategy -
    +
    ## strategy
    - We'll work with you to validate your concept, and translate it into an implementable Proof of Concept + We'll work with you to validate your concept, and translate it into an + implementable Proof of Concept
    -
    - ## implementation -
    +
    ## implementation
    Cook up appropriate Plutus validators to meet your needs
    -
    - ## deployment -
    +
    ## deployment
    - We facilitate integrating the on-chain aspects with the rest of your stack + We facilitate integrating the on-chain aspects with the rest of your + stack
    -
    \ No newline at end of file + diff --git a/templates/tailwind-nav-example.html b/templates/tailwind-nav-example.html index b9ffa17..33f1424 100644 --- a/templates/tailwind-nav-example.html +++ b/templates/tailwind-nav-example.html @@ -3,55 +3,135 @@
    -
    -
    + -
    -
    -
    @@ -65,11 +145,38 @@ From: "transform opacity-100 scale-100" To: "transform opacity-0 scale-95" --> -
    @@ -80,10 +187,27 @@ - \ No newline at end of file + diff --git a/templates/terminal_default.html b/templates/terminal_default.html index 83d97b4..9ea834d 100644 --- a/templates/terminal_default.html +++ b/templates/terminal_default.html @@ -1,4 +1,4 @@ - + @@ -12,13 +12,13 @@ /> $title$ - + + + - - -