!doctype[html]/
< License: BSD / Copyright (C) 2023 Triv Collective
html[data-version=""]:
head:
meta[charset="utf-8"]/
title: Triv - Web Workshop
style:
'''
:root {
--chrome-height: 3rem;
--one-label-chrome-height: 2rem;
--two-label-chrome-height: 3rem;
--toolbar-button-width: 3rem;
--captioned-toolbar-button-width: 3rem;
--icon-toolbar-button-width: 2rem;
--label-height: 1.5rem;
--preview-border-thickness: 1px;
--footer-height: 1.5rem;
--grip-height: 1.5rem;
--toolbar-padding: 0.3rem;
--new-dialog-height: 9.5rem;
--load-dialog-height: 17.75rem;
--theme-dialog-height: 15.5rem;
--dialog-width: 320px;
--dialog-padding: 1rem;
--close-button-padding: 5px;
--panel-width: 50%;
--panel-width-no-px: 9999;
--input-height: 40%;
--output-height: 40%;
--chrome-color: #aaa;
--theme-warmth: 0;
--theme-wheel: 0deg;
--theme-saturation: 1;
--theme-contrast: 100%;
}
body {
margin: 0;
padding: 0;
line-height: 1.3;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
font-size: 14px;
color: #1b1b1b;
overflow: hidden;
}
@media (min-resolution: 120dpi) {
html { font-size: 96% }
body { font-size: 13.6px }
the-dialog[load] { height: calc(var(--load-dialog-height) * 1.02) !important }
}
body.resizing * {
cursor: grab
}
body.resizing iframe, body.resizing textarea {
pointer-events: none;
}
body.resizing the-preview the-title {
-webkit-user-select: none;
user-select: none;
}
[theming] {
filter: sepia(var(--theme-warmth)) hue-rotate(var(--theme-wheel)) saturate(var(--theme-saturation)) contrast(var(--theme-contrast));
}
the-chrome {
display: block;
position: absolute;
top: 0;
left: 0;
height: var(--chrome-height);
width: 100%;
background: linear-gradient(0deg, #949494 0%, #999 15%, #a9a9a9 100%);
z-index: 3;
overflow: hidden;
-webkit-user-select: none;
user-select: none;
}
:root.icons {
--chrome-height: var(--one-label-chrome-height);
--toolbar-button-width: var(--icon-toolbar-button-width);
}
:root.captions {
--chrome-height: var(--one-label-chrome-height);
--toolbar-button-width: var(--captioned-toolbar-button-width);
}
:root.icons.captions {
--chrome-height: var(--two-label-chrome-height);
--toolbar-button-width: var(--captioned-toolbar-button-width);
}
the-toolbar button {
height: calc(var(--chrome-height) - var(--toolbar-padding));
width: calc(var(--toolbar-button-width) - var(--toolbar-padding));
margin-top: calc(var(--toolbar-padding) / 2);
margin-left: var(--toolbar-padding);
padding: 0;
box-shadow: 1px 1px 3px 0 #999;
}
the-toolbar button:active {
padding-left: 2px;
}
button {
display: inline-block;
background: linear-gradient(0deg, #ccc 0%, #9f9f9f 100%);
border-top: 1px solid #eee;
border-left: 1px solid #eee;
border-right: 1px solid #777;
border-bottom: 1px solid #777;
border-radius: 5px;
color: #555;
text-align: center;
overflow: hidden;
position: relative;
}
button:focus {
background: linear-gradient(0deg, #e3e3e3 0%, #aaa 100%);
outline: 1px dotted #111;
outline-offset: -5px;
text-shadow: #eee 0 -1px 1px;
}
the-toolbar button:focus {
outline: 1px dotted #111;
outline-offset: -4px;
}
button[data-autofocus] {
box-shadow: 0 0 2px 0 #777;
}
input.button[type=checkbox] {
display:none;
}
label.button[checkbox]{
display:block;
height: calc(calc(var(--chrome-height) - var(--toolbar-padding)) - 2px);
width: calc(var(--toolbar-button-width) - var(--toolbar-padding));
margin-top: calc(var(--toolbar-padding) / 2);
margin-right: var(--toolbar-padding);
padding: 0;
box-shadow: 1px 1px 3px 0 #999;
display: inline-block;
background: linear-gradient(0deg, #ccc 0%, #9f9f9f 100%);
border-top: 1px solid #eee;
border-left: 1px solid #eee;
border-right: 1px solid #777;
border-bottom: 1px solid #777;
border-radius: 5px;
color: #555;
text-align: center;
float:right;
overflow: hidden;
}
the-toolbar button, the-toolbar label.button {
font-size: 11.5px;
letter-spacing: -0.1px;
}
the-toolbar label.button > div {
display: grid;
height: 100%;
align-content: center;
}
the-toolbar [system] {
height: 16px;
font-size: 14px;
font-family: Segoe UI Symbol, math, monospace;
margin-top: -1px;
margin-bottom: 1px;
text-shadow: #eee 0 -1px 1px;
}
input:checked + label.button[checkbox] [system] {
text-shadow: #c1c1c1 0 -1px 1px;
}
input:checked + label.button[checkbox]:focus [system] {
text-shadow: #eee 0 -1px 1px;
}
the-toolbar [raster] {
filter: contrast(0.08) drop-shadow(#eee 0 -1px 1px);
}
the-toolbar input:checked + label.button [raster] {
filter: contrast(0.08) drop-shadow(#c1c1c1 0 -1px 1px);
}
the-toolbar input:checked + label.button:focus [raster] {
filter: contrast(0.08) drop-shadow(#eee 0 -1px 1px);
}
button svg *, label.button[checkbox] svg * {
stroke: currentColor !important;
stroke-width: 0.33px !important;
}
button svg #path3745, button svg #path4605, label.button[checkbox] svg #path4655 {
fill: currentColor !important;
}
button:focus svg, label.button[checkbox]:focus svg {
filter: drop-shadow(#eee 0 -1px 1px);
}
input:checked + label.button[checkbox] {
height: calc(calc(var(--chrome-height) - var(--toolbar-padding)) - 3px);
width: calc(calc(var(--toolbar-button-width) - var(--toolbar-padding)) - 1px);
border-left-color: #6d6d6d;
border-top: #6d6d6d;
border-bottom-color: #dbdbdb;
border-right-color: #dbdbdb;
background: linear-gradient(#818181, #aeaeae);
border-bottom-width: 2px;
border-right-width: 2px;
box-shadow: inset 10px 10px 7px -5px #8d8d8d;
}
input:checked + label.button[checkbox] [text] {
margin-left: 1px;
margin-bottom: 1px;
}
label.button[checkbox]:focus {
background: linear-gradient(0deg, #e3e3e3 0%, #aaa 100%);
text-shadow: #eee 0 -1px 1px;
outline: 1px dotted #111;
outline-offset: -3px;
}
input:checked + label.button[checkbox]:focus {
text-shadow: #c1c1c1 0 -1px 1px;
}
input:checked + label.button[checkbox] toolbar-caption {
/* mitigates text overflow in Firefox */
block-size:15px;
top:0.1rem;
margin-top:1px;
}
:root toolbar-icon {
position: relative;
top: 1px;
left: 0px;
}
:root.captions toolbar-icon, :root.icons toolbar-caption {
block-size: 16px;
position: relative;
top: 0.15rem;
}
:root toolbar-icon {
display: none;
}
:root.raster.icons toolbar-icon[raster] {
display: block;
}
:root.vector.icons toolbar-icon[vector] {
display: block;
}
:root.system.icons toolbar-icon[system] {
display: block;
}
:root toolbar-caption {
display: none;
}
:root.captions toolbar-caption {
display: block;
}
the-contents {
display: block;
position: absolute;
bottom: var(--footer-height);
left: 0;
height: calc(calc(100vh - var(--chrome-height)) - var(--footer-height));
width: 100%;
background: #bbb;
}
the-panel {
display: block;
height: 100%;
width: var(--panel-width);
min-width: var(--grip-height);
max-width: calc(100vw - var(--grip-height));
background: #ccc;
}
footer {
position: absolute;
bottom: 0;
left: 0;
height: calc(var(--footer-height) - 3px);
width: 100%;
background: var(--chrome-color);
background: linear-gradient(180deg, #aaa 0, #ccc 100%);
border-bottom: 2px solid #aaa;
outline: 1px solid #eee;
z-index: 500;
color: #545454;
overflow: hidden;
-webkit-user-select: none;
user-select: none;
display: flex;
flex-wrap: wrap-reverse;
}
the-input {
display: block;
height: var(--input-height);
width: 100%;
background: #fff;
position: relative;
min-height: calc(var(--label-height) + 2px);
max-height: calc(calc(calc(100% - var(--label-height)) - var(--label-height)) - 3px);
z-index: 3;
}
the-output {
display: block;
height: var(--output-height);
width: 100%;
background: #eee;
position: relative;
min-height: calc(var(--label-height) + 0.5px);
max-height: calc(calc(calc(100% - var(--input-height)) - var(--label-height)) - 2px);
padding-bottom: 1px;
z-index: 1;
}
the-console {
display: block;
height: calc(calc(100% - var(--input-height)) - var(--output-height));
width: 100%;
background: #fff;
}
the-input the-label, the-output the-label, the-console the-label, the-preview the-label {
display: block;
height: calc(var(--label-height) - 2px);
width: 100%;
position: relative;
background: linear-gradient(0deg, #999 0, #bfbfbf 100%);
border-bottom: 1px solid #777;
border-top: 1px solid #eee;
}
the-input the-label:before, the-output the-label:before, the-console the-label:before {
position: relative;
top: 0.5px;
}
the-input the-label {
z-index: 1;
}
the-preview the-label {
display: flex;
overflow: hidden;
}
the-input the-label, the-preview the-label {
box-shadow: 0px 0.5px 3px 0 #ababab;
}
the-output the-label {
border-top: 1px solid #afafaf;
box-shadow: 0px 0.5px 3px 0 #676767;
z-index: 3;
}
the-console the-label {
box-shadow: 0px 0.5px 3px 0 #777;
}
the-input the-label.focused, the-preview the-label.focused {
box-shadow: 0px 0.5px 3px 0 #ababab, box-shadow: 0 0 2px 0 #dedede;;
}
the-output the-label.focused {
box-shadow: 0px 0.5px 3px 0 #676767, box-shadow: 0 0 2px 0 #dedede;
z-index: 3;
}
the-console the-label.focused {
box-shadow: 0px 0.5px 3px 0 #777, box-shadow: 0 0 2px 0 #dedede;
}
the-label {
text-shadow: #dedede -1px -1px 0px, #6f6f6f 1px 1px 0;
color: #7a7a7a;
}
the-label.focused {
text-shadow: #dedede -1px -1px 0px, #6f6f6f 1px 1px 0, #fff -2px -2px 2px, #fff 2px 2px 2px;
color: #bbb;
}
the-input the-label:before {
content: 'Input';
}
the-output the-label:before {
content: 'Output';
}
the-console the-label:before {
content: 'Console';
}
the-preview the-label:before {
content: 'Preview';
position: relative;
top: 0.5px;
}
the-preview the-title {
position: relative;
top: 0.5px;
line-break: anywhere;
text-indent: -100vw;
margin-left: 100vw;
-webkit-user-select;
user-select: none;
pointer-events: none;
}
the-preview the-title:before {
display: inline;
content: '-';
margin-left: 0.3rem;
margin-right: 0.3rem;
}
textarea {
display: block;
height: calc(100% - var(--label-height));
width: 100%;
resize: none;
position: relative;
top: -1px;
font-size: 14px;
margin: 0 0 0 0;
margin-bottom: -10px;
padding: 0;
outline: none;
}
the-input textarea {
height: calc(calc(100% - var(--label-height)) + 2px);
border: none;
box-shadow: inset 0px -3px 7px -7px #333;
}
the-output textarea {
border: none;
background: #ccc;
font-size: 12px;
padding-top:2px;
filter: saturate(0);
}
resizing-grip {
display: block;
height: var(--grip-height);
width: var(--grip-height);
position: absolute;
right: 0;
bottom: 0;
background: transparent;
cursor: grab;
margin-bottom: calc(0px - var(--label-height));
}
resizing-grip:after {
display: block;
content: '';
position:absolute;
bottom: 0.275rem;
right: 0.1rem;
width: 3.5px;
height: 3.5px;
border-radius: 100px;
background: #ababab;
box-shadow: -1px -1px 0 0 #7b7b7b, 1px 1px 0 0 #c8c8c8, -5px -5px 0 0 #ababab, -6px -6px 0 0 #7b7b7b, -4px -4px 0 0 #c8c8c8, 0px -10px 0 0 #ababab, -1px -11px 0 0 #7b7b7b, 1px -9px 0 0 #c8c8c8, -10px 0px 0 0 #ababab, -11px -1px 0 0 #7b7b7b, -9px 1px 0 0 #c8c8c8;
opacity: 0.85;
}
the-input the-label, the-output the-label, the-console the-label {
overflow:hidden;
}
the-input the-label:before, the-output the-label:before, the-console the-label:before {
opacity: calc(calc(var(--panel-width-no-px) * 0.05) - 3.4);
}
the-warnings {
display: block;
height: calc(100% - var(--label-height));
width: 100%;
background: #ccc;
overflow-y: scroll;
}
the-warnings:focus {
outline: none;
}
a-warning {
display: block;
background: #ddddaa;
font-family: monospace;
margin-top: 0.3rem;
margin-bottom: 0.3rem;
margin-left: 3px;
cursor: pointer;
}
a-warning:focus {
outline: 1px dotted #111;
}
the-preview {
display: block;
height: 100%;
width: calc(100% - var(--panel-width));
min-width: var(--grip-height);
max-width: calc(100vw - var(--grip-height));
background: #ddd;
position: absolute;
bottom: 0;
right: 0;
overflow: hidden;
z-index: 700;
}
the-display {
display: block;
height: calc(calc(100% - calc(var(--preview-border-thickness) * 2)) - var(--label-height));
width: calc(100% - calc(var(--preview-border-thickness) * 2));
border: var(--preview-border-thickness) solid #eee;
border-left: 1px solid #ccc;
background: #ddd;
}
the-display iframe {
height: 100%;
width: 100%;
border: none;
background: #fff;
}
footer the-version {
display: inline-block;
text-align: center;
position: relative;
margin: auto;
}
footer the-link {
overflow: hidden;
text-align: right;
word-break: break-all;
margin-right: 0.77rem;
letter-spacing: 0.5px;
display: inline-block;
width: 6rem;
}
footer the-link a, footer the-link a:hover,
footer the-link a:active, footer the-link a:focus,
footer the-link a:visited {
color: inherit;
outline: none;
text-decoration: none;
transition: color 0.2s ease-in-out;
}
footer the-link a:hover {
color: #eee;
transition: color 0.66s ease-in-out;
}
a-modal {
display: none;
}
a-modal * {
z-index: 1000;
}
the-overlay {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: #000;
opacity: 0.5;
transition: opacity 0.45s ease-out;
}
the-overlay.hidden {
opacity: 0;
transition: opacity 0.45s ease-out;
}
the-dialog {
display: block;
width: var(--dialog-width);
height: auto;
position: absolute;
top: calc(50% - calc(attr(height) / 2));
left: calc(50% - calc(var(--dialog-width) / 2));
background: #fff;
border-radius: 0.25rem;
box-shadow: 10px 10px 30px 0 rgba(0,0,0,0.3);
outline: none;
max-height: 100vh;
overflow-x: hidden;
overflow-y: auto;
-webkit-user-select: none;
user-selct: none;
}
the-dialog:before {
display: block;
content: '';
margin-bottom: 2.5rem;
}
the-dialog the-heading:before {
display: block;
content: '';
width: calc(100% + 0.7rem);
height: 2.5rem;
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
background: linear-gradient(0deg, #bdbdbd 0%, #b3b3b3 5%, #eee 80%, #d7d7d7 100%);
border-bottom: 1px solid #aaa;
position: absolute;
top: -0.7rem;
left: -0.7rem;
z-index: -1;
}
the-dialog the-heading close-button:after {
display: block;
content: 'x';
position: absolute;
right: calc(var(--dialog-padding) - calc(var(--close-button-padding) * 2));
text-shadow: #e1e1e1 -1px -1px 0px, #e1e1e1 1px 1px 0;
font-size: 14px;
font-weight: bold;
padding: var(--close-button-padding);
margin-top: calc(0px - var(--close-button-padding));
margin-left: calc(0px - var(--close-button-padding));
top: -1px;
}
the-dialog the-heading close-button:hover:after {
color: #f6f6f6;
text-shadow: #e1e1e1 0 0 7px, #c1c1c1 0px 1px 0;
}
the-dialog the-heading {
text-shadow: #e1e1e1 -1px -1px 0px, #e1e1e1 1px 1px 0;
letter-spacing: 0.7px;
color: #7a7a7a;
top: 0;
left: 0;
margin-top: 0.7rem;
margin-left: 0.7rem;
position: absolute;
width: calc(calc(100% - 0.7rem) - 0rem)
}
the-dialog the-prompt {
display: block;
padding-top: 16px;
padding-left: var(--dialog-padding);
padding-right: var(--dialog-padding);
}
the-dialog label[range] span {
position: relative;
top: 1.35rem;
left: var(--dialog-padding);
line-height: 1.7;
}
the-dialog input[type=range] {
position: absolute;
margin-top: 1.5rem;
width: 60%;
right: 0.5rem;
}
the-dialog label[checkbox] {
display: inline-block;
}
the-dialog label input[type=checkbox] {
vertical-align: middle;
}
the-dialog label[checkbox] span {
vertical-align: middle;
/* mitigates gap */
margin-left: calc(0px - calc(calc(1rem / 4) + 3px));
padding-left: calc(calc(1rem / 4) + 3px);
}
input[disabled] {
color: #909090;
}
label input[type="radio"][disabled] + span {
color: #909090;
}
the-dialog label[icons] {
position: absolute;
left: 0rem;
margin-left: var(--dialog-padding);
margin-right: 1rem;
top: 10.25rem;
}
the-dialog label[captions] {
position: absolute;
right: 0;
margin-right: var(--dialog-padding);
top: 10.25rem;
}
the-dialog label[preview] {
position: absolute;
left: 0;
margin-left: var(--dialog-padding);
bottom: calc(var(--dialog-padding) + 0.15rem);
}
the-dialog[new] {
display: block;
width: var(--dialog-width);
height: var(--new-dialog-height);
position: absolute;
top: calc(50% - calc(var(--new-dialog-height) / 2));
left: calc(50% - calc(var(--dialog-width) / 2));
background: #fff;
border-radius: 0.25rem;
box-shadow: 10px 10px 30px 0 rgba(0,0,0,0.3);
outline: none
}
the-dialog[new]:focus {
outline: none;
}
the-dialog[new] the-prompt {
display: block;
padding-top: 1.8rem;
padding-left: var(--dialog-padding);
padding-right: var(--dialog-padding);
}
a-modal the-buttons {
position: relative;
margin-right: var(--dialog-padding);
margin-bottom: var(--dialog-padding);
float: right;
}
a-modal button {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
width: 3.875rem;
margin-left: 0.75rem;
}
the-dialog[theme] {
display: block;
width: var(--dialog-width);
height: var(--theme-dialog-height);
position: absolute;
top: calc(50% - calc(var(--theme-dialog-height) / 2));
left: calc(50% - calc(var(--dialog-width) / 2));
background: #fff;
border-radius: 0.25rem;
box-shadow: 10px 10px 30px 0 rgba(0,0,0,0.3);
outline: none;
z-index: 1000;
}
the-dialog[theme] the-buttons {
position: absolute;
margin-right: var(--dialog-padding);
margin-bottom: var(--dialog-padding);
bottom: 0;
right: 0;
}
li {
margin: 0;
padding: 0;
}
the-dialog[load] {
height: var(--load-dialog-height);
top: calc(50% - calc(var(--load-dialog-height) / 2));
}
the-dialog[load] input[type="file"] {
text-overflow: ellipsis;
width: 100%;
margin-top: 2px;
margin-bottom: -2px;
}
the-dialog[load] ul {
padding: 0 var(--dialog-padding) 0 var(--dialog-padding);
}
the-dialog[load] ul > li {
list-style: none;
margin-bottom: 0.5rem;
}
the-dialog[load] ul > li label {
display: flex;
}
a-line {
display: flex;
align-items: center;
text-align: center;
margin: 1rem 0 1rem 0;
}
a-line:before, a-line:after {
content: '';
flex: 1;
border-bottom: 1px solid #bbb;
}
a-line:before {
margin-right: 0.5em;
}
a-line:after {
margin-left: 0.5em;
}
the-dialog[load] the-grid {
display: grid;
grid: ". auto";
margin-bottom: -1.25rem;
}
the-dialog[load] the-grid li {
display: block;
flex-basis: 50%;
height: 2.75rem;
margin: 0;
padding: 0;
}
the-dialog[load] the-grid li label {
display: inline;
width: calc(var(--dialog-width) / 3);
}
the-dialog[load] the-grid input[type=radio] {
vertical-align: top;
}
the-dialog[load] the-grid li label span {
display: inline-block;
position: relative;
vertical-align: text-bottom;
height: 1.5rem;
top: 0px;
width: 6rem;
text-align:center
}
the-dialog[load] docu-preview {
display: none;
width: 3rem;
height: 4rem;
background: #eee;
margin: auto;
}
'''
script[src="./3v.js"]:
script: """
(function () {
let callbackOnReady = (fn) => {
if (document.readyState != "loading") {
fn();
} else {
document.addEventListener("DOMContentLoaded", fn);
}
};
callbackOnReady(main);
function main() {
let appVersion = "0.1.0";
let toBase64 = theStr => btoa(Array.from(new TextEncoder().encode(theStr), x=>String.fromCodePoint(x)).join(""));
let fromBase64 = base64 => new TextDecoder().decode(Uint8Array.from(atob(base64), m=>m.codePointAt(0)));
let LT = String.fromCodePoint(60);
let GT = String.fromCodePoint(62);
let LTFSGT = LT + "/" + GT;
let exampleDocuments = {
welcome: `
[Welcome]
'''
to the${LTFSGT} Web Workshop!
'''
p: Press the Load ${String.fromCodePoint(128194)} button on the toolbar to see more
examples loaded as Input.
small: (Try the ${String.fromCodePoint(8220)}Tutorial${String.fromCodePoint(8221)} example if you already
read the Intro or Features)
p: Don't forget to save your work
with the Save ${String.fromCodePoint(128190)} button.
p: Compiled output and preview is automatic
as you type.
Toggle this with the
Comp. ${String.fromCodePoint(9654)} button.
p: More documentation is available at
a[href="https://www.triv.co" target="_blank"]:
www.triv.co
[.Keyboard shortcuts.]
ul:
li: Indent selection*
keyb: Insert
li: Deindent selection*
keyb: Alt+Insert
li: Toggle automatic compilation
keyb: Pause
small: *Undo/redo is not yet
implemented for these functions
[]
hr[]/
small.right.floated: Workshop version: ${appVersion}
style:
\"\"\"
body {padding: 1.33rem; font-size: 11pt;
line-height: 1.15}
body > div { margin: auto; min-width:19.5rem;
max-width: 29rem }
h1 {font-size: 19.5pt; text-align: center;
margin-bottom: 0.33rem;
font-family: Cambria, Times New Roman, sans-serif;
}
body > div > h1 { margin-left:-0.75rem }
body > div > h1 + h1 { font-size: 15.5pt;
font-style: italic; margin-bottom: 2.2rem;
margin-left: 0.33rem }
.regular {font-size:13.33pt; margin-right: 0.05rem}
h1 ~ div > h1 {font-size: 11pt;text-align: left;
letter-spacing: 0; margin-top:1.33rem}
p, li, small, h1 ~ div > h1 {
font-family: Tahoma, sans, sans-serif;
font: small-caption; line-height: 1.33}
h1 ~ div > h1 {font-weight: bold; font-size: 0.94em;
margin: 0; padding-top: 0.45rem}
small {font-size: 0.819em}
p, li {font-size: 10.75pt; letter-spacing: 0.3px}
abbr {text-decoration: none;
border-bottom: 1px dashed #333}
p keyb {color: #55a0a0;
text-shadow: -1px -1px 0 #fdff7a, 1px 1px 0 #39701e;
position: relative; top: -2px}
a {color: #3B9EFF}
ul {padding-left: 1.5rem}
li {margin-bottom: 0.33rem}
li > keyb, .right.floated {float: right}
keyb keyb {border: 1px solid; border-radius: 5px;
padding: 1.75px}
sup {font-size: 8.333pt; line-height: 0}
hr {margin-top: 1.25rem}
\"\"\"
`.trim(),
features: fromBase64("IWRvY3R5cGVbaHRtbF0vCmh0bWw6CiAgaGVhZDoKICAgIG1ldGFbY2hhcnNldD0idXRmLTgiXS8KICAgIHRpdGxlOiBGZWF0dXJlcwogICAgc3R5bGU6CiAgICAgICIiIgogICAgICBodG1sIHsKICAgICAgICBmb250LXNpemU6IDE0cHQ7CiAgICAgIH0KICAgICAgbWFpbiB7CiAgICAgICAgbWluLXdpZHRoOiAyMS4zcmVtOwogICAgICAgIHdpZHRoOiA1MCU7CiAgICAgICAgbWF4LXdpZHRoOiAzMC41cmVtOwogICAgICAgIG1hcmdpbjogYXV0bzsKICAgICAgICBwYWRkaW5nLWxlZnQ6IDEuNjZyZW07CiAgICAgICAgZm9udC1mYW1pbHk6IFRpbWVzIE5ldyBSb21hbiwgc2VyaWY7CiAgICAgIH0KICAgICAgbWFpbiA+IGRpdiA+IGgxIHsKICAgICAgICBmb250LXNpemU6IDIuM2VtOwogICAgICAgIGxldHRlci1zcGFjaW5nOiAwLjIzcmVtOwogICAgICAgIHRyYW5zZm9ybTogc2tld1goLTNkZWcpOwogICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjsKICAgICAgfQogICAgICBtYWluID4gZGl2ID4gaDEgfiBkaXYgPiBoMSB7CiAgICAgICAgZm9udC1zaXplOiAxNHB0OwogICAgICAgIHRyYW5zZm9ybTogc2tld1goLTNkZWcpOwogICAgICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOwogICAgICB9CiAgICAgIGgxIH4gZGl2ID4gaDEgfiBkaXYgPiBoMSB7CiAgICAgICAgZm9udC1zaXplOiAwLjk0NXJlbTsKICAgICAgfQogICAgICBzbWFsbCB7CiAgICAgICAgZm9udC1zaXplOiAwLjg2ZW07CiAgICAgIH0KICAgICAgbmF2ICsgZGl2IHsKICAgICAgICBwYWRkaW5nLWJvdHRvbTogMXJlbTsKICAgICAgfQogICAgICBbZGF0YS1zeW1ib2xdOmJlZm9yZSB7CiAgICAgICAgY29udGVudDogYXR0cihkYXRhLXN5bWJvbCk7CiAgICAgICAgZm9udC1zaXplOiAxLjcwNXJlbTsKICAgICAgICBtYXJnaW4tbGVmdDogLTIuOTU1cmVtOwogICAgICAgIG1hcmdpbi1yaWdodDogLTEwMCU7CiAgICAgICAgZmxvYXQ6bGVmdDsKICAgICAgfQogICAgICBwIGNvZGUgeyBmb250LXNpemU6IDAuODFlbSB9CiAgICAgIC5pbmxpbmVibG9jayB7IGRpc3BsYXk6IGlubGluZS1ibG9jayB9CiAgICAgIC5leGFtcGxlIHsKICAgICAgICBkaXNwbGF5OiBmbGV4OwogICAgICAgIG1heC13aWR0aDogMjlyZW07CiAgICAgICAgcGFkZGluZzogMnB4OwogICAgICAgIGNvbHVtbi1nYXA6IDEwcHg7CiAgICAgIH0KICAgICAgLmV4YW1wbGU6Zm9jdXMtd2l0aGluIHsKICAgICAgICAgcGFkZGluZy1sZWZ0OiAxLjA1cmVtOwogICAgICAgICBib3JkZXItbGVmdDogMnB4IHNvbGlkICM5MDkwOTA7CiAgICAgICAgIG1hcmdpbi1sZWZ0OiAtMS4wNXJlbTsKICAgICAgfQogICAgICAuZXhhbXBsZSB0ZXh0YXJlYSwgLmV4YW1wbGUgc2FtcCB7CiAgICAgICAgYmFja2dyb3VuZDogbm9uZTsKICAgICAgICBjb2xvcjogIzMwMzAzMDsKICAgICAgICBmb250LXNpemU6IDEwLjVwdDsKICAgICAgICBib3JkZXItcmFkaXVzOiAycHg7CiAgICAgICAgZmxleC1iYXNpczo1MCU7CiAgICAgICAgaGVpZ2h0OiA3cmVtOwogICAgICAgIG92ZXJmbG93OiBoaWRkZW47CiAgICAgICAgcmVzaXplOiBub25lOwogICAgICAgIG1pbi13aWR0aDogOC4zcmVtOwogICAgICAgfQogICAgICAuc21hbGwuZXhhbXBsZSB0ZXh0YXJlYSwgLnNtYWxsLmV4YW1wbGUgc2FtcCB7CiAgICAgICAgaGVpZ2h0OiAzLjVyZW07CiAgICAgIH0KICAgICAgLm1lZGl1bS5leGFtcGxlIHRleHRhcmVhLCAuc21hbGwuZXhhbXBsZSBzYW1wIHsKICAgICAgICBoZWlnaHQ6IDVyZW07CiAgICAgIH0KICAgICAgLmV4YW1wbGUgdGV4dGFyZWEgewogICAgICAgIGJvcmRlcjogbm9uZTsKICAgICAgICBtYXJnaW46IDAgMCAwIC0xLjA1cmVtOwogICAgICAgIHBhZGRpbmc6IDAgMCAwIDEuMDVyZW07CiAgICAgIH0KICAgICAgLmV4YW1wbGUgc2FtcCBwcmUgewogICAgICAgIHBhZGRpbmc6IDA7CiAgICAgICAgbWFyZ2luOiAwIDAgMCAwOwogICAgICAgIGNvbG9yOiAjYmRiZGJkOwogICAgICB9CiAgICAgIC5leGFtcGxlIHRleHRhcmVhOmZvY3VzIHsKICAgICAgICBvdXRsaW5lOiBub25lOwogICAgICB9CiAgICAgIC5leGFtcGxlIHRleHRhcmVhOmZvY3VzICsgc2FtcCBwcmUgewogICAgICAgIGNvbG9yOiAjOTA5MDkwOwogICAgICB9CiAgICAgIC5tb2RpZmllZC5leGFtcGxlIHRleHRhcmVhOmZvY3VzICsgc2FtcCBwcmUgewogICAgICAgIGNvbG9yOiAjNDU0NTQ1OwogICAgICB9CiAgICAgIC5leGFtcGxlOmZvY3VzLXdpdGhpbiB0ZXh0YXJlYSwgLmV4YW1wbGU6Zm9jdXMtd2l0aGluIHNhbXAgewogICAgICAgIG92ZXJmbG93OiBhdXRvOwogICAgICB9CiAgICAgIC5tb2RpZmllZC5leGFtcGxlOmZvY3VzLXdpdGhpbjpiZWZvcmUgewogICAgICAgIGRpc3BsYXk6IGJsb2NrOwogICAgICAgIGNvbnRlbnQ6ICcqJzsKICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgICAgICAgbWFyZ2luLWxlZnQ6IC00OS44cHg7CiAgICAgICAgbWFyZ2luLXRvcDogLTAuMDByZW07CiAgICAgIH0KICAgICAgLm5vdGljZSB7CiAgICAgICAgZm9udC1zdHlsZTogaXRhbGljOwogICAgICB9CiAgICAgIC5zbWFsbC1jYXBzIHsKICAgICAgICB0ZXh0LXRyYW5zZm9ybTogbG93ZXJjYXNlOwogICAgICAgIGZvbnQtdmFyaWFudDogc21hbGwtY2FwczsKICAgICAgICBmb250LXNpemU6IDEuMThlbTsKICAgICAgICBsaW5lLWhlaWdodDogMDsKICAgICAgfQogICAgICBhIHsKICAgICAgICBjb2xvcjogIzFlOTBmZgogICAgICB9CiAgICAgIGE6Zm9jdXMgewogICAgICAgIG91dGxpbmU6IDJweCBzb2xpZCAjYjNhNzlkOwogICAgICB9CiAgICAgIG5hdiB1bCB7CiAgICAgICAgY29sb3I6ICMzZjNmM2Y7CiAgICAgIH0KICAgICAgZGl2ICsgbmF2IHsKICAgICAgICBtYXJnaW4tdG9wOiAzcmVtOwogICAgICB9CiAgICAgIGRpdiArIG5hdiAuZWRpdDpiZWZvcmUgewogICAgICAgIGNvbnRlbnQ6ICJcMjcwZSI7CiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgICAgIG1hcmdpbi1sZWZ0OiAtMS4zNXJlbTsKICAgICAgICBmbG9hdDogbGVmdAogICAgICB9CiAgICAgIGRpdiArIG5hdiAucmV0dXJuOmJlZm9yZSB7CiAgICAgICAgY29udGVudDogIlwyMTkwIjsKICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgICAgICAgbWFyZ2luLWxlZnQ6IC0xLjI1cmVtOwogICAgICAgIGZsb2F0OiBsZWZ0CiAgICAgIH0KICAgICAgZm9vdGVyIHttYXJnaW4tdG9wOiAycmVtfQoiIiIKICAgIHNjcmlwdFtzcmM9Ii4vM3YuanMiXToKICBib2R5OgogICAgbWFpbjoKW0ZlYXR1cmVzXQoKcFtkYXRhLXN5bWJvbD0nJiN4MWY0ZGE7J106CiAgVHJpdiBpcyBhIHN5bnRheCB3aXRoIG9ubHkgYSBmZXcgZmVhdHVyZXMuCiAgSXQncyBhbHdheXMgaW50ZW5kZWQgdG8gc3RheSB0aGF0IHdheS4KbmF2OnVsOgogIGxpOmFbaHJlZj0iI011bHRpbGluZXMiXTogTXVsdGlsaW5lcwogIGxpOmFbaHJlZj0iI0VsZW1lbnRzIl06IEVsZW1lbnRzCiAgbGk6YVtocmVmPSIjU2VjdGlvbnMiXTogU2VjdGlvbnMKCjpzbWFsbC5ub3RpY2U6IEFsbCBleGFtcGxlcyBjbGlja2FibGUgYW5kIGVkaXRhYmxlCgpbLk11bHRpbGluZXMuXSMgaDEgJiBkYXRhLXN5bWJvbD0iJiN4MWY0YzM7IgoKWy4uKDEpIERlZmF1bHQgY29udGVudC4uXQpwW106IENvbnRlbnQgY2FuIGdvIDxlbT5vbiB0aGUgc2FtZSBsaW5lPC9lbT4gYXMgdGhlIGVsZW1lbnQsIDxlbSBjbGFzcz0iaW5saW5lYmxvY2siPgogIG9yIG9uIGFub3RoZXI6PC9lbT4KCmNvZGUuZXhhbXBsZToKICB0ZXh0YXJlYTogIiIiCmE6CiAgYjoKICAgIGM6IFNhbWUgbGluZQogICAgICAgb3IgYW5vdGhlcgoiIiIKICBzYW1wOnByZToKClsuLigyKSBMaXRlcmFscy4uXQoKOiBUcmlwbGUtcXVvdGVzICgiIG9yICcpIGxldCB5b3UgcHV0IDxzcGFuIGNsYXNzPSJzbWFsbC1jYXBzIj5IVE1MPC9zcGFuPiBhdCB0aGUgc3RhcnQgb2YgYSBsaW5lLgoKY29kZS5tZWRpdW0uZXhhbXBsZToKICB0ZXh0YXJlYTogJycnCiIiIgo8aHRtbD4KPC9odG1sPgoiIiIKJycnCiAgc2FtcDpwcmU6Cgo6IEFuZDogeW91IGRvbid0IGhhdmUgdG8gd2F0Y2ggb3V0IGZvciBjb2xvbnMgb3IgaW5kZW50YXRpb24uCgpjb2RlLnNtYWxsLmV4YW1wbGU6CiAgdGV4dGFyZWE6ICcnJwoiIiIKTGl0ZXJhbGx5OgoiIiIKJycnCiAgc2FtcDpwcmU6Cgo6IFRyaXBsZS1iYWNrcXVvdGVzIChgKSBhcmUgZm9yIHB1YmxpY2F0aW9uIG9mIDxzYW1wbGU+PHNwYW4gY2xhc3M9InNtYWxsLWNhcHMiPkhUTUw8L3NwYW4+IGVsZW1lbnRzPC9zYW1wbGU+LgoKY29kZS5leGFtcGxlOgogIHRleHRhcmVhOiAiIiIKYGBgCiZsdDtlbGVtZW50Jmd0OwogICZhbXA7YW1wOwombHQ7L2VsZW1lbnQmZ3Q7CmBgYAoiIiIKICBzYW1wOnByZToKClsuRWxlbWVudHMuXSMgaDEgJiBkYXRhLXN5bWJvbD0iJiN4MWY1MjM7IgoKOnNtYWxsOiBFbGVtZW50cyBhcmUgbm9ybWFsbHkgd3JpdHRlbiBhcyBlbGVtZW50IHN0YXRlbWVudHMsIHdpdGggYSBjb2xvbiAoOikgJm1kYXNoOyBhbmQgc29tZXRpbWVzIGFzIG5hdGl2ZSA8c3BhbiBjbGFzcz0ic21hbGwtY2FwcyI+SFRNTDwvc3Bhbj4gZWxlbWVudHMuCgpbLi4oMykgQXR0cmlidXRlcy4uXQoKOiBFbGVtZW50IGF0dHJpYnV0ZXMgY2FuIGJlIHNwZWNpZmllZCBlc3NlbnRpYWxseSBsaWtlIGEgc2VsZWN0b3IuCgpjb2RlLmV4YW1wbGU6CiAgdGV4dGFyZWE6ICIiIgphI2lkOgoKYS5jbGFzczoKCmFbYXR0cmlidXRlc106CiIiIgogIHNhbXA6cHJlOgoKWy4uKDQpIERlZmF1bHQgZWxlbWVudHMuLl0KCjogU2V0IGEgZGVmYXVsdCBlbGVtZW50IG5hbWUgYnkgZW1wdHkgYXR0cmlidXRlIGJyYWNrZXRzLgoKOiBBbnkgZWxlbWVudCB3aXRoIGEgbmFtZSBvbWl0dGVkLCBtYXJrZWQgd2l0aCBhIGNvbG9uICg6KSBwbGFjZW1lbnQgbWFyaywgYXNzdW1lcyB0aGUgZGVmYXVsdCBuYW1lLgoKY29kZS5zbWFsbC5leGFtcGxlOgogIHRleHRhcmVhOiAiIiIKcFtdOgo6CiIiIgogIHNhbXA6cHJlOgoKWy4uKDUpIFNlbGYtY2xvc2luZyBlbGVtZW50cy4uXQoKOiBFbGVtZW50cyB3aXRoIG5vIGNsb3NpbmcgdGFnIG11c3Qgc3BlY2lmeSBhdHRyaWJ1dGUgYnJhY2tldHMsIGV2ZW4gaWYgZW1wdHksIGFuZCBhIHRyYWlsaW5nIGZvcndhcmQgc2xhc2ggKC8pLgo6IEEgc2Vjb25kIGZvcndhcmQgc2xhc2ggKC8vKSBpcyBmb3IgPHNwYW4gY2xhc3M9InNtYWxsLWNhcHMiPlhNTDwvc3Bhbj4uCgpjb2RlLnNtYWxsLmV4YW1wbGU6CiAgdGV4dGFyZWE6ICIiIgpicltdLwpicltdLy8KIiIiCiAgc2FtcDpwcmU6CgoKWy4uKDYpIENvbnZlbmllbmNlIG5hdGl2ZSBlbGVtZW50cy4uXQoKOiBUcmlwbGUgc2luZ2xlLXF1b3RlcyBhcmUgZm9yIHNob3J0ZW5lZCwgY29udmVuaWVuY2UgPHNwYW4gY2xhc3M9InNtYWxsLWNhcHMiPkhUTUw8L3NwYW4+IGVsZW1lbnRzLgoKY29kZS5zbWFsbC5leGFtcGxlOgogIHRleHRhcmVhOiAiIiIKJycnCjxlbT5jb252ZW5pZW5jZTwvPgonJycKIiIiCiAgc2FtcDpwcmU6CgpbLlNlY3Rpb25zLl0jIGgxICYgZGF0YS1zeW1ib2w9IiYjeDFmNGQxOyIKClsuLig3KSBEZWZhdWx0IHNldHRpbmdzLi5dCgo6IFNlY3Rpb25zIGFyZSByZWFsbHkganVzdCA8Y29kZT5oMTwvY29kZT4ncyBpbiA8Y29kZT5kaXY8L2NvZGU+J3MsIG9yCiAgaWYgZGVjb3JhdGVkIHdpdGggYW4gPHNwYW4gY2xhc3M9InNtYWxsLWNhcHMiPklEPC9zcGFuPiBtYXJrICgjKSwgYSA8Y29kZT5kaXY8L2NvZGU+IHdpdGggYW4gaWQgYXR0cmlidXRlLgoKY29kZS5zbWFsbC5leGFtcGxlOgogIHRleHRhcmVhOiAiIiIKW1NlY3Rpb25dCiIiIgogIHNhbXA6cHJlOgoKWy4uKDgpIERlY29yYXRvcnMuLl0KCjogRWFjaCBzZXR0aW5nIG9uIHRoZSBzYW1lIGxpbmUgYXMgdGhlIHNlY3Rpb24gdGl0bGUgaXMgYSBkZWNvcmF0b3IuCjogUmVuYW1lIHRoZSBlbGVtZW50cywgdGhlIHRpdGxlL2lkIHByb3BlcnR5LCBvciBhZGQgbW9yZSBhdHRyaWJ1dGVzLgoKY29kZS5leGFtcGxlOgogIHRleHRhcmVhOiAiIiIKW1NlY3Rpb25dIwoKW1NlY3Rpb25daDYvYXJ0aWNsZQoiIiIKICBzYW1wOnByZToKClsuLig5KSBQbGFjZW1lbnQuLl0KCjogU2VjdGlvbnMgYXJlIHBsYWNlZCB3aXRoaW4gb3RoZXIgc2VjdGlvbnMgYnkKICBhIG1hdGNoZWQgbGV2ZWwgaW5kaWNhdG9yIGFyb3VuZCB0aGUgdGl0bGUgJm1kYXNoOwogIGJyYWNrZXRzIChzaGFsbG93ZXIpIG9yIGRvdHMgKGRlZXBlcikuCgpjb2RlLmV4YW1wbGU6CiAgdGV4dGFyZWE6ICIiIgpbW0FdXQpbQl0KWy5DLl0KIiIiCiAgc2FtcDpwcmU6Cgo6IGlzIGVxdWl2YWxlbnQgdG86Cgpjb2RlLmV4YW1wbGU6CiAgdGV4dGFyZWE6ICIiIgpbQV0KWy5CLl0KWy4uQy4uXQoiIiIKICBzYW1wOnByZToKClsuLigxMCkgQ2xvc2luZy4uXQoKOiBTZWN0aW9ucyBhcmUgb3B0aW9uYWxseSBjbG9zZWQgd2l0aCBhIHNpbmdsZSAoPGNvZGU+W108L2NvZGU+KQogIG9yIG11bHRpcGxlIHNldHMgb2YgZW1wdHkgYnJhY2tldHMgKDxjb2RlPltbW11dXTwvY29kZT4pCjogQSBzZWN0aW9uIHJlc2V0ICg8Y29kZT5bXSo8L2NvZGU+KSBjbG9zZXMgYWxsIHNlY3Rpb25zLgpjb2RlLmV4YW1wbGU6CiAgdGV4dGFyZWE6ICIiIgpbQV0KWy5CLl0KW10qCm5vdCBpbiBBIG9yIEIKIiIiCiAgc2FtcDpwcmU6CgpbW11dCgogICAgZm9vdGVyOgogICAgICBkaXY6IENvcHlyaWdodCAmY29weTsyMDIzIFRyaXYgQ29sbGVjdGl2ZQpbXQogICAgc2NyaXB0OiAiIiIKZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLmV4YW1wbGUgdGV4dGFyZWEiKS5mb3JFYWNoKGVsPT57CiAgZWwuc2V0QXR0cmlidXRlKCJzcGVsbGNoZWNrIiwgImZhbHNlIik7CiAgZWwuc2V0QXR0cmlidXRlKCJ3cmFwIiwgIm9mZiIpOwogIHAgPSBuZXcgUGFyc2VyVHJpdigpOwogIGVsLmRhdGFzZXQuZGVmYXVsdCA9IGVsLnZhbHVlOwogIGVsLnNldEF0dHJpYnV0ZSgiYXJpYS1kZXNjcmlwdGlvbiIsICJFeGFtcGxlIHNvdXJjZSBjb2RlLiIpOwogIGVsLm5leHRFbGVtZW50U2libGluZy50YWJJbmRleCA9ICItMSI7IC8vZm9yIGZpcmVmb3ggd2hlbiBvdmVyZmxvdzogYXV0bwogIGVsLm5leHRFbGVtZW50U2libGluZy5zZXRBdHRyaWJ1dGUoImFyaWEtZGVzY3JpcHRpb24iLCAiRXhhbXBsZSBvdXRwdXQuIik7CiAgZWwubmV4dEVsZW1lbnRTaWJsaW5nLnF1ZXJ5U2VsZWN0b3IoInByZSIpLnRleHRDb250ZW50ID0gcC5jb21waWxlV2l0aG91dFdhcm5pbmdzKGVsLnZhbHVlKTsKfSk7CmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIi5leGFtcGxlIHRleHRhcmVhIikuZm9yRWFjaChlbD0+ZWwuYWRkRXZlbnRMaXN0ZW5lcigia2V5dXAiLCBmdW5jdGlvbihlKSB7CiAgaWYgKGVsLnZhbHVlICE9PSBlbC5kYXRhc2V0LmRlZmF1bHQgfHwgZWwucGFyZW50RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoIm1vZGlmaWVkIikpIHsKICAgIHAgPSBuZXcgUGFyc2VyVHJpdigpOwogICAgY29tcGlsZWQgPSBlLnRhcmdldC5uZXh0RWxlbWVudFNpYmxpbmcucXVlcnlTZWxlY3RvcigicHJlIik7CiAgICBjb21waWxlZC50ZXh0Q29udGVudCA9IHAuY29tcGlsZVdpdGhvdXRXYXJuaW5ncyhlLnRhcmdldC52YWx1ZSk7CiAgICBpZiAoZWwudmFsdWUgIT09IGVsLmRhdGFzZXQuZGVmYXVsdCkgewogICAgICBjb21waWxlZC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgibW9kaWZpZWQiKTsKICAgIH0gZWxzZSBpZiAoZWwucGFyZW50RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoIm1vZGlmaWVkIikpIHsKICAgICAgZWwucGFyZW50RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCJtb2RpZmllZCIpOwogICAgfSAKICB9Cn0pKTsKIiIi").trim(),
tutorial: fromBase64("W1R1dG9yaWFsXQpwOiBPdXIgZG9jdW1lbnQgaGFzIGEgZmV3IGJ1Z3MuIExldCdzIHNlZSBpZiB3ZSBjYW4gY29ycmVjdCBpdD8KWy5MaXRlcmFscy5dCnA6IGBgYAoxLiA8ZW0+VGhpcyBsaW5lIGlzIGl0YWxpYzwvPgogICA8IS0tIExldCdzIGNoYW5nZSB0aGUgbGl0ZXJhbCB0b2dnbGVzCiAgICAgICAgZnJvbSAzIGJhY2txdW90ZXMgKGApIHRvIDMgc2luZ2xlLXF1b3RlcyAoJykuCiAgICAgICAgKERvbid0IHdvcnJ5IGlmIHRoZSBwcmV2aWV3CiAgICAgICAgbG9va3Mgb2ZmIHdoaWxlIGVkaXRpbmcpLgogICAgICAgIFJlbWVtYmVyIHRvIGNoYW5nZSBib3RoIHRoZQogICAgICAgIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHRvZ2dsZSEgLS0+CmBgYAogICA8LS0gdHJhaWxpbmcgdG9nZ2xlClsuRWxlbWVudHMuXQp1bDoKICBsaVtdOiAyLiBUaGlzIGxpbmUgaXMgYSBwYXJhZ3JhcGgKICAgIDwtLSBMZXQncyBjaGFuZ2UgdGhpcyB0byBwW106IGluc3RlYWQgb2YgbGlbXToKICA6IFBhcmFncmFwaHMgYXJlIHVzdWFsbHkgZGlzcGxheWVkIHdpdGggbWFyZ2lucwogIDogUGFyYWdyYXBocyBhcmUgbm90IGJ1bGxldGVkCgp1bDoKbGk6IDMuIFRoaXMgbGluZSBpcyB0aGUgZmlyc3QgaXRlbSBvZiBhbiB1bm9yZGVyZWQgbGlzdAogIDwtLSBMZXQncyBhZGQgMiBzcGFjZXMganVzdCBsaWtlIHRoZSBzZWNvbmQgbGlzdCBpdGVtCiAgPC0tIFRoZSByZXN1bHQgc2hvdWxkIGJlOiAgIGxpOiAzLiBUaGlzIGxpbmUgaXMgLi4uCiAgPC0tICAgICAgICAgICAgIChzcGFjZXMpOiBeXgogIGxpOiBUaGlzIGxpc3QgaXRlbSBpcyBzZWNvbmQgaW4gdGhlIHNhbWUgbGlzdAoKYXNpZGU6IDQuIFRoaXMgbGluZSBoYXMgYSBjaGVja21hcmsKICAgICA8LS0gTGV0J3MgYWRkIGEgImNoZWNrbWFyayIgYXR0cmlidXRlCiAgICAgPC0tIFRoZSByZXN1bHQgc2hvdWxkIGJlOiBhc2lkZVtjaGVja21hcmtdOiAuLi4KClsuU2VjdGlvbnMuXQoKWy4uTWFpbiBzZWN0aW9uLi5dCihUaGUgdGl0bGUgaGFzIGEgZG91YmxlIHVuZGVybGluZSkKWy4uRXhhbXBsZS4uXQogICA8LS0gICAgICA8LS0gTGV0J3MgY2hhbmdlIHRoZSBzZWN0aW9uIGxldmVsIHRvIDMgZG90cwpwOiA1LiBUaGUgdGl0bGUgaGFzIGEgc2luZ2xlIHVuZGVybGluZQoKICA8LS0gTGV0J3MgYWRkIGEgc2VjdGlvbiBjbG9zZXIKICA8LS0gVGhlIHJlc3VsdCBzaG91bGQgYmU6IFtdCnA6IDYuIFRoaXMgcGFyYWdyYXBoIGlzIG9ubHkgaW4gdGhlIE1haW4gc2VjdGlvbgoKWy4uLkV4YW1wbGUuLi5dCiAgICAgICAgICAgICAgICA8LS0gTGV0J3MgYWRkIGEgImNoZWNrbWFyayIgYXR0cmlidXRlCiAgICAgICAgICAgICAgICA8LS0gVGhlIHJlc3VsdCBzaG91bGQgYmU6CiAgICAgICAgICAgICAgICA8LS0gICBbLi4uRXhhbXBsZS4uLl0gJiBjaGVja21hcmsKcDogNy4gVGhpcyBzZWN0aW9uIGhhcyBhIGNoZWNrbWFyawoKCltdKgpmb290ZXI6CiAgaHJbXS8KICBwOnNtYWxsOiBJZiB5b3UgY29tcGxldGVkIHRoZSBjb3JyZWN0aW9ucwogICAgYW5kIHJlY2VpdmVkIDEwIGNoZWNrbWFya3MgKCYjeDI3MTM7KSw8YnI+CiAgICBjb25ncmF0dWxhdGlvbnMhCiAgICBZb3UndmUgY29tcGxldGVkIHRoZSBUcml2IHR1dG9yaWFsITxicj4KCnN0eWxlOiAiIiIKICBib2R5e21pbi13aWR0aDozNHJlbTtsaW5lLWhlaWdodDoxLjE1OwogICAgZm9udC1mYW1pbHk6IENhbGlicmksIEFyaWFsLCBzYW5zLXNlcmlmfQogIGJvZHk+ZGl2e21hcmdpbjoyLjc1cmVtIDByZW0gMCAzcmVtOwogICAgZm9udC1zaXplOjEycHQ7cG9zaXRpb246cmVsYXRpdmV9CiAgYm9keT5kaXY+cHttYXJnaW4tcmlnaHQ6M3JlbX0KICBib2R5PmRpdj5oMXtmb250LXNpemU6MThwdDt0ZXh0LWFsaWduOmNlbnRlcjsKICAgIG1hcmdpbi1yaWdodDo1cmVtO21hcmdpbi1ib3R0b206MS42NnJlbX0KICBib2R5PmRpdj5kaXY+aDF7Zm9udC1zaXplOjEzLjVwdDttYXJnaW4tdG9wOjEuNXJlbX0KICA6YmVmb3Jle3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjNyZW07Zm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBvcGFjaXR5OjAuMjt0ZXh0LWluZGVudDowfQogIDphZnRlcntwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDozcmVtO2ZvbnQtd2VpZ2h0OmJvbGQ7CiAgICBmb250LXNpemU6MTVweDsgbWFyZ2luOi0xcHggLTFweDsKICAgIGNvbG9yOiMzM2JiMzM7dGV4dC1pbmRlbnQ6MH0KICAvKiAxLiB1bmNvcnJlY3RlZCAqLwogIGJvZHk+ZGl2PmRpdj5we3RleHQtaW5kZW50Oi0xLjVyZW07bWFyZ2luOjAgN2VtIDAgMS41cmVtfQogIGJvZHk+ZGl2PmRpdj5wOmJlZm9yZXtjb250ZW50OidcMjYxMCd9CiAgLyogMS4gY29ycmVjdGVkICovCiAgZW06YWZ0ZXJ7Y29udGVudDonXDI3MTMnO2ZvbnQtc3R5bGU6bm9ybWFsO2xpbmUtaGVpZ2h0OjEuMn0KICAvKiAyLiAqLwogIHVsOmZpcnN0LW9mLXR5cGV7cGFkZGluZy1sZWZ0OjFyZW19CiAgdWw6Zmlyc3Qtb2YtdHlwZT4qKyp7cGFkZGluZy1sZWZ0OjEuMjVyZW19CiAgdWw6Zmlyc3Qtb2YtdHlwZT5saTpub3QoOmxhc3Qtb2YtdHlwZSkge3BhZGRpbmctYm90dG9tOjAuNXJlbX0KICAvKiAyLiB1bmNvcnJlY3RlZCAqLwogIHVsOmZpcnN0LW9mLXR5cGU+KjpiZWZvcmV7Y29udGVudDonXDI2MTAnfQogIC8qIDIuIGNvcnJlY3RlZCAqLwogIHVsOmZpcnN0LW9mLXR5cGU+cDphZnRlcntjb250ZW50OidcMjcxMyd9CiAgLyogMy4gdW5jb3JyZWN0ZWQgKi8KICB1bDplbXB0eXsgbWFyZ2luLXRvcDoxLjZyZW0gfQogIHVsK2xpK2xpeyBwYWRkaW5nOjAuNXJlbSAwIDEuNXJlbSAwfQogIHVsK2xpOmJlZm9yZXtjb250ZW50OidcMjYxMCd9CiAgdWwrbGkrbGk6YmVmb3Jle2NvbnRlbnQ6J1wyNjEwJ30KICAvKiAzLiBjb3JyZWN0ZWQgKi8KICB1bDpsYXN0LW9mLXR5cGU6bm90KDplbXB0eSl7cGFkZGluZy10b3A6MC42cmVtOwogICAgcGFkZGluZy1sZWZ0OjAuOTZyZW19CiAgdWw6bGFzdC1vZi10eXBlPmxpe3BhZGRpbmctYm90dG9tOjAuNXJlbX0KICB1bDpsYXN0LW9mLXR5cGU+bGk6bnRoLWNoaWxkKDEpOmJlZm9yZXtjb250ZW50OidcMjYxMCd9CiAgdWw6bGFzdC1vZi10eXBlPmxpOm50aC1jaGlsZCgyKTpiZWZvcmV7Y29udGVudDonXDI2MTAnfQogIHVsOmxhc3Qtb2YtdHlwZT5saTpudGgtY2hpbGQoMSk6YWZ0ZXJ7Y29udGVudDonXDI3MTMnfQogIHVsOmxhc3Qtb2YtdHlwZT5saTpudGgtY2hpbGQoMik6YWZ0ZXJ7Y29udGVudDonXDI3MTMnfQogIC8qIDQuIHVuY29ycmVjdGVkICovCiAgYXNpZGU6YmVmb3Jle2NvbnRlbnQ6J1wyNjEwJ30KICAvKiA0LiBjb3JyZWN0ZWQgKi8KICBhc2lkZVtjaGVja21hcmtdOmFmdGVye2NvbnRlbnQ6J1wyNzEzJ30KICAvKiA1LTcuICovCiAgZGl2PmRpdj5kaXY+aDF7Zm9udC1zaXplOjEwLjVwdDtmb250LXdlaWdodDpub3JtYWw7CiAgICB0ZXh0LWRlY29yYXRpb246ZG91YmxlIHVuZGVybGluZX0KICBkaXY+ZGl2PmRpdj5kaXY+aDF7Zm9udC1zaXplOjEwLjVwdDtmb250LXdlaWdodDpub3JtYWw7CiAgICB0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lfQogIGJvZHk+ZGl2PmRpdj5kaXZ7Ym9yZGVyLWxlZnQ6IDFweCBkb3R0ZWQgc2lsdmVyOwogICAgcGFkZGluZy1sZWZ0OjAuNXJlbX0KICBib2R5PmRpdj5kaXY+ZGl2PmRpdiB7Ym9yZGVyLWxlZnQ6IDFweCBkb3R0ZWQgc2lsdmVyOwogICAgcGFkZGluZy1sZWZ0OjAuNXJlbX0KICAvKiA1LiB1bmNvcnJlY3RlZCAqLwogIGJvZHk+ZGl2PmRpdj5kaXY6bnRoLWNoaWxkKDMpPgogICAgcDpudGgtY2hpbGQoMik6YmVmb3Jle2NvbnRlbnQ6J1wyNjEwJ30KICAvKiA1LiBjb3JyZWN0ZWQgKi8KICBib2R5PmRpdj5kaXY+ZGl2Om50aC1jaGlsZCgyKT5kaXY6bnRoLWNoaWxkKDIpPgogICAgcDpudGgtY2hpbGQoMik6YmVmb3Jle2NvbnRlbnQ6J1wyNjEwJ30gIAogIGJvZHk+ZGl2PmRpdj5kaXY6bnRoLWNoaWxkKDIpPmRpdjpudGgtY2hpbGQoMik+CiAgICBwOm50aC1jaGlsZCgyKTphZnRlcntjb250ZW50OidcMjcxMyd9CiAgLyogNi4gYXR0ZW1wdGVkIGNvcnJlY3RlZCBhbmQKICAgICA1LiB1bmNvcnJlY3RlZCAqLwogIGJvZHk+ZGl2PmRpdj5kaXY6bnRoLWNoaWxkKDMpPgogICAgcDpudGgtb2YtdHlwZSgyKTpiZWZvcmV7Y29udGVudDonXDI2MTAnfQogIC8qIDYuIHVuY29ycmVjdGVkICovCiAgYm9keT5kaXY+ZGl2PmRpdjpudGgtY2hpbGQoMik+ZGl2Om50aC1jaGlsZCgyKT4KICAgIHA6bnRoLWNoaWxkKDMpOmJlZm9yZXtjb250ZW50OidcMjYxMCd9CiAgLyogNi4gY29ycmVjdGVkICovCiAgYm9keT5kaXY+ZGl2Om50aC1jaGlsZCg1KT5kaXY6bnRoLWNoaWxkKDIpPgogICAgcDpiZWZvcmV7Y29udGVudDonXDI2MTAnfQogIGJvZHk+ZGl2PmRpdjpudGgtY2hpbGQoNSk+ZGl2Om50aC1jaGlsZCgyKT4KICAgIHA6YWZ0ZXJ7Y29udGVudDonXDI3MTMnfQogIC8qIDcuIHVuY29ycmVjdGVkIGFuZAogICAgIDYuIGF0dGVtcHRlZCBjb3JyZWN0ZWQgYW5kCiAgICAgNS4gdW5jb3JyZWN0ZWQgKi8KICBib2R5PmRpdj5kaXY+ZGl2Om50aC1jaGlsZCg1KT5wOmJlZm9yZXtjb250ZW50OidcMjYxMCd9CiAgLyogNy4gY29ycmVjdGVkIGFuZAogICAgIDYuIGF0dGVtcHRlZCBjb3JyZWN0ZWQgYW5kCiAgICAgNS4gdW5jb3JyZWN0ZWQgKi8KICBib2R5PmRpdj5kaXY+ZGl2Om50aC1jaGlsZCg1KVtjaGVja21hcmtdCiAgICA+cDphZnRlcntjb250ZW50OidcMjcxMyd9CiAgLyogNy4gdW5jb3JyZWN0ZWQgb3IKICAgICAgICBjb3JyZWN0ZWQgYW5kIDUuIGFuZCA2LiB1bmNvcnJlY3RlZCAqLwogIGRpdj5kaXY+ZGl2PmRpdjpsYXN0LW9mLXR5cGU+cDpiZWZvcmV7Y29udGVudDonXDI2MTAnfQogIC8qIDcuIGNvcnJlY3RlZCBvciA1IGFuZCA2LiB1bmNvcnJlY3RlZCAqLwogIGJvZHk+ZGl2PmRpdj5kaXY+ZGl2Omxhc3QtY2hpbGRbY2hlY2ttYXJrXT5wOmFmdGVyewogICAgY29udGVudDonXDI3MTMnfQogIGZvb3RlcnttYXJnaW46MS41cmVtIDRyZW0gMCAzcmVtO3RleHQtYWxpZ246Y2VudGVyfQoiIiI=").trim()
};
var firstRun = true;
var resizing = false;
var everResized = false;
var multiDialog = false;
var automaticIndent = false;
var awaitingDoublePressEsc = false;
var inputText = "";
var rateLimiting = false;
var scrollPosRateLimiting = false;
var x, y;
var iframe, blobURL;
var cookieDuration = 30;
var themeCookies = ["--theme-warmth", "--theme-wheel", "--theme-saturation", "--theme-contrast"];
document.documentElement.dataset.version = appVersion;
document.querySelector("the-version the-string").textContent = new ParserTriv().api_version;
let removeBlankSpaceNodes = ()=>{document.querySelectorAll("body *").forEach(el=>getComputedStyle(el).whiteSpace !== "pre"?el.childNodes.forEach(n=>n.nodeType===Node.TEXT_NODE && n.nodeValue.length && !n.nodeValue.trim().length?el.removeChild(n):null):null);};
removeBlankSpaceNodes();
let setCookie = (name, value) => document.cookie = name+"~"+appVersion+"="+encodeURIComponent(value)+"; cookieDuration="+ 60 * 60 * 24 * cookieDuration + ";" + "samesite=strict;";
let getCookie = (name) => {
let toReturn = "";
if (document.cookie.length) {
let found = document.cookie.match("[\s]*" + name+"~"+appVersion + "=([^;]*)");
if (found) {
toReturn = decodeURIComponent(found[1]);
}
}
return toReturn;
};
function loadOptions() {
document.querySelectorAll("the-dialog[theme] input[type=range][data-default]").forEach(el=>document.querySelector(":root").style.setProperty(el.dataset.var, el.dataset.default));
setTimeout( ()=> {
themeCookies.forEach(option=>{
document.documentElement.style.setProperty(option, getCookie(option));
});
}, 50);
let theRootCookie= getCookie("html");
if (theRootCookie) {
theRoot = document.querySelector("html");
theRoot.removeAttribute("class");
theRoot.classList = theRootCookie;
}
firstRun = getCookie("firstRun") !== "0";
if (!document.querySelector(":root").classList.contains("icons") && !document.querySelector(":root").classList.contains("captions")) {
document.querySelector(":root").classList.add(window.devicePixelRatio > 1? "vector" : "raster");
document.querySelector(":root").classList.add("icons");
document.querySelector(":root").classList.add("captions");
}
nullishCoalescing = (theIf, theElse) => theIf? theIf : theElse;
document.querySelector("the-dialog[theme] select").value = nullishCoalescing(Object.values(document.querySelector("the-dialog[theme] select").options).map(el=>el.value).filter(v=>document.querySelector(":root").classList.contains(v))[0],"none");
document.querySelector("the-dialog[theme] [checkbox][captions] input[type=checkbox]").checked = document.querySelector(":root").classList.contains("captions");
}
loadOptions();
let bindIFrameFocus = iframe=>{
iframe.contentWindow.addEventListener("focus", e=>{
var evt=new CustomEvent("focus", {bubbles: true, cancelable: false});
iframe.dispatchEvent(evt);
});
iframe.contentWindow.addEventListener("blur", e=>{
var evt=new CustomEvent("blur", {bubbles: true, cancelable: false});
iframe.dispatchEvent(evt);
});
iframe.contentWindow.addEventListener("keyup", e=>{
var evt=new CustomEvent("keyup", {bubbles: true, cancelable: false, detail: {key: e.key, altKey: e.altKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey}});
iframe.dispatchEvent(evt);
});
};
bindIFrameFocus(document.querySelector("iframe"));
document.querySelectorAll("the-panel *").forEach(el=>el.addEventListener("focus", function(e) {
e.target.parentElement.firstElementChild.classList.add("focused");
}));
document.querySelector("iframe").addEventListener("focus", function(e) {
e.target.parentElement.parentElement.firstElementChild.classList.add("focused");
});
document.querySelector("iframe").addEventListener("blur", function(e) {
e.target.parentElement.parentElement.firstElementChild.classList.remove("focused");
});
document.querySelectorAll("the-panel *").forEach(el=>el.addEventListener("blur", function(e) {
e.target.parentElement.firstElementChild.classList.remove("focused");
}));
document.querySelectorAll("the-label[data-focus]").forEach(el=>el.addEventListener("click", function(e) {
e.target.parentElement.querySelector(e.target.dataset.focus).focus();
}));
document.documentElement.style.setProperty("--input-height", document.querySelector("the-input").offsetHeight + "px");
document.querySelector("the-input textarea").focus();
deviceInputMove = function(clientX, clientY) {
if (resizing) {
if (!everResized) {
document.documentElement.style.setProperty("--panel-width", "calc(var(--panel-width-no-px) * 1px)");
everResized = true;
}
var panel = document.querySelector("the-panel");
var labelHeight = document.documentElement.style.getPropertyValue("--label-height");
var footerHeight = document.documentElement.style.getPropertyValue("--footer-height");
document.documentElement.style.setProperty("--panel-width-no-px", (Math.max(0,clientX+12)));
if (resizing === "the-input") {
document.documentElement.style.setProperty("--input-height", (Math.max(0,clientY-48)) + "px");
} else if (resizing === "the-output") {
inputHeight = parseInt(document.documentElement.style.getPropertyValue("--input-height").slice(0,-2));
document.documentElement.style.setProperty("--output-height", (Math.min(panel.offsetHeight - 52,Math.max(0,clientY-48-inputHeight))) + "px");
}
}
}
deviceInputDown = function(e) {
resizing = e.target.parentElement.tagName.toLowerCase();
document.body.classList.add("resizing");
}
deviceInputUp = function() {
resizing = false;
document.body.classList.remove("resizing");
}
if (!window.PointerEvent) {
document.documentElement.addEventListener("mousemove", e=>deviceInputMove(e.clientX, e.clientY));
document.querySelector("the-input resizing-grip").addEventListener("mousedown", deviceInputDown);
document.querySelector("the-output resizing-grip").addEventListener("mousedown", deviceInputDown);
document.documentElement.addEventListener("mouseup", deviceInputUp);
document.querySelector("iframe").contentWindow.addEventListener("mouseup", deviceInputUp);
} else {
// e.target.setPointerCapture(e.pointerId);
document.documentElement.addEventListener("pointermove", e=>deviceInputMove(e.clientX, e.clientY));
document.querySelector("the-input resizing-grip").addEventListener("mousedown", deviceInputDown);
document.querySelector("the-output resizing-grip").addEventListener("mousedown", deviceInputDown);
document.documentElement.addEventListener("mouseup", deviceInputUp);
document.querySelector("iframe").contentWindow.addEventListener("mouseup", deviceInputUp);
}
document.querySelectorAll("resizing-grip").forEach(el=>el.addEventListener("dragstart", function(e) {
e.preventDefault();
}));
document.documentElement.addEventListener("touchmove", e=>deviceInputMove(e.touches[0].clientX, e.touches[0].clientY));
document.querySelector("the-input resizing-grip").addEventListener("touchstart", deviceInputDown);
document.querySelector("the-output resizing-grip").addEventListener("touchstart", deviceInputDown);
document.querySelector("the-input resizing-grip").addEventListener("touchend", deviceInputUp);
document.querySelector("the-output resizing-grip").addEventListener("touchend", deviceInputUp);
document.querySelector("the-input the-label").addEventListener("click", function(e) {
let height = e.target.parentElement.offsetHeight;
if (parseInt(height) < e.target.offsetHeight + 20) {
document.documentElement.style.setProperty("--input-height", "40%");
document.documentElement.style.setProperty("--input-height", e.target.parentElement.offsetHeight+"px");
}
});
document.querySelector("the-output the-label").addEventListener("click", function(e) {
let height = e.target.parentElement.offsetHeight;
if (parseInt(height) < e.target.offsetHeight + 20) {
document.documentElement.style.setProperty("--input-height", "40%");
document.documentElement.style.setProperty("--input-height", document.querySelector("the-input").offsetHeight+"px");
document.documentElement.style.setProperty("--output-height", "40%");
document.documentElement.style.setProperty("--output-height", e.target.parentElement.offsetHeight+"px");
}
});
document.querySelector("the-console the-label").addEventListener("click", function(e) {
let height = e.target.parentElement.offsetHeight;
if (parseInt(height) < e.target.offsetHeight + 20) {
let inputHeight = document.querySelector("the-input").offsetHeight;
let outputHeight = document.querySelector("the-output").offsetHeight;
let panelHeight = document.querySelector("the-panel").offsetHeight
let recommendedHeight = panelHeight / 5;
if (outputHeight > recommendedHeight + e.target.offsetHeight + 20) {
document.documentElement.style.setProperty("--output-height", (outputHeight - recommendedHeight)+"px");
} else {
document.documentElement.style.setProperty("--input-height", "40%");
document.documentElement.style.setProperty("--input-height", document.querySelector("the-input").offsetHeight+"px");
document.documentElement.style.setProperty("--output-height", "40%");
document.documentElement.style.setProperty("--output-height", document.querySelector("the-output").offsetHeight+"px");
}
}
});
document.querySelectorAll("button[data-dialog]").forEach(el=>el.addEventListener("click", function(e) {
var el = e.target;
while (!el.dataset.dialog) {
el = el.parentElement;
}
el = document.querySelector(el.dataset.dialog);
document.querySelectorAll("main *").forEach(function(el) {if (el.tabIndex > -1) {el.tabIndex = -1}});
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
multiDialog = false;
el.style.display = "block";
el.querySelector("button[data-autofocus]").focus();
el.querySelectorAll("input[data-var]").forEach(el=>{
currValue = document.documentElement.style.getPropertyValue(el.dataset.var);
if (currValue === "") {
currValue = el.dataset.default;
document.documentElement.style.setProperty(el.dataset.var, currValue);
}
currValue = parseFloat(currValue);
el.value = currValue;
});
awaitingDoublePressEsc = false;
}));
document.querySelectorAll("a-modal the-dialog the-heading").forEach(el=>{
var heading = el;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
if (el.dataset.title) {
heading.appendChild(document.createTextNode(el.dataset.title));
}
});
document.querySelectorAll("a-modal").forEach(el=>el.addEventListener("keyup", function(e) {
if (!multiDialog) {
var el = e.target;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
if (e.key === "Escape" && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
let selectFocused = document.querySelector("the-dialog select:focus");
if (!selectFocused || awaitingDoublePressEsc) {
awaitingDoublePressEsc = false;
el.querySelector("button[data-type=close]").click();
}
if (selectFocused) {
awaitingDoublePressEsc = true;
}
} else {
awaitingDoublePressEsc = false;
}
}
}));
document.querySelectorAll("the-buttons button").forEach(el=>el.addEventListener("keyup", function(e) {
var el = e.target;
while (el.tagName.toLowerCase() !== "the-buttons") {
el = el.parentElement;
}
if (e.key === "ArrowRight") {
if (e.target === el.lastElementChild) {
el.firstElementChild.focus();
} else {
e.target.nextElementSibling.focus();
}
} else if (e.key === "ArrowLeft") {
if (e.target === el.firstElementChild) {
el.lastElementChild.focus();
} else {
e.target.previousElementSibling.focus();
}
}
}));
document.querySelectorAll("label.button[checkbox]").forEach(el=>el.addEventListener("keyup", function(e) {
if ((e.key === "Enter" || e.key === " ") && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
e.target.click();
}
}));
document.querySelector(".button[for=autoComp]").addEventListener("click", function(e) {
if (!document.getElementById("autoComp").checked) {
compileAndDisplay(true);
}
});
window.addEventListener("keyup", function (e) {
if (e.key === "Pause" && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
document.querySelector(".button[for=autoComp]").click();
}
});
document.querySelector("iframe").addEventListener("keyup", function(event) {
let e = event.detail;
if (e.key === "Pause" && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
document.querySelector(".button[for=autoComp]").click();
}
});
document.querySelectorAll("a-modal > *").forEach(el=>el.addEventListener("click", function(e) {
var el = e.target;
var normTagName = el.tagName.toLowerCase();
if (normTagName !== "input" && normTagName !== "label" && normTagName !== "select") {
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
el.querySelector("button[data-autofocus]").focus();
}
awaitingDoublePressEsc = false;
}));
document.querySelectorAll("a-modal button[data-type=close]").forEach(el=>el.addEventListener("click", function(e) {
document.querySelectorAll("main *[tabIndex]").forEach(function(el) {el.tabIndex = el.dataset.tabindex||0});
var el = e.target;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
el.style.display = "none";
document.querySelector("the-input textarea").focus();
}));
document.querySelectorAll("a-modal the-heading close-button").forEach(el=>el.addEventListener("click", function(e) {
var el = e.target;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
el.querySelector("button[data-type=close]").click();
}));
document.querySelector("the-dialog[new] button[yes]").addEventListener("click", function() {
document.querySelector("the-input textarea").value = "";
document.querySelector("the-output textarea").value = "";
document.querySelector("the-console the-warnings").innerHTML = "";
document.querySelector("the-preview the-title").style.visibility = "hidden";
document.querySelector("the-preview the-title").textContent = "";
if (iframe) {
for (let i of [0,1]) {
if (i > 0) {
clearIFrameError();
}
try {
iframe.contentWindow.document.documentElement.innerHTML = "";
break;
} catch {
//
}
}
}
document.querySelectorAll("main *[tabIndex]").forEach(function(el) {el.tabIndex = el.dataset.tabindex||0});
document.querySelector("a-modal").style.display = "none";
document.querySelector("the-input textarea").focus();
});
document.querySelector("the-toolbar button[save]").addEventListener("click", function() {
let fileName = prompt("Enter a file name:");
if (!fileName) {
document.querySelector("the-input textarea").focus();
return;
}
if (blobURL) {
URL.revokeObjectURL(blobURL);
}
let np = new ParserTriv();
let input = document.querySelector("the-input textarea").value;
let {configMatter, source} = np.configMatterAndSource(input);
let browserInstruction = "";
if (np.lenJsLn > 0) {
browserInstruction = input.split("\n").slice(0,np.lenJsLn).join("\n") + "\n";
}
if (!configMatter) {
configMatter = "api-version=" + np.api_version + "\n===\n"
}
let fileSource = browserInstruction + configMatter + source;
fileName = fileName + ".3v"
let array = [fileSource];
fileBlob = new Blob(array, {type: "text/plain"});
blobURL = URL.createObjectURL(fileBlob);
link = document.createElement("a");
link.href = blobURL;
link.download = fileName;
link.style.display = "none";
document.body.appendChild(link);
document.querySelector("the-input textarea").focus();
link.click();
try {
document.removeChild(link);
} catch {
//
}
});
document.querySelectorAll("the-dialog[theme] label[checkbox]").forEach(el=>el.addEventListener("click", function(e) {
if (e.target.tagName.toLowerCase() === "label") {
e.preventDefault();
e.target.querySelector("input[type=checkbox]").click();
}
}));
document.querySelector("the-dialog[theme] button[data-type=close]").addEventListener("click", function(e) {
themeCookies.forEach(option=>{
setCookie(option,document.documentElement.style.getPropertyValue(option));
});
setCookie("html",Object.values(document.querySelector(":root").classList).sort((a,b)=>a < b).join(" "));
});
document.querySelector("the-dialog[theme] [checkbox][preview] input[type=checkbox]").addEventListener("click", function(e) {
var el = e.target;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
el.querySelector("the-overlay").classList.toggle("hidden");
e.target.checked = el.querySelector("the-overlay").classList.contains("hidden");
});
let loadInput = source => {
document.querySelector("the-input textarea").value = source;
document.querySelector("the-output textarea").value = "";
document.querySelector("the-console the-warnings").innerHTML = "";
if (iframe) {
for (let i of [0,1]) {
if (i > 0) {
clearIFrameError();
}
try {
iframe.contentWindow.document.documentElement.innerHTML = "";
break;
} catch {
//
}
}
}
document.querySelector("the-input textarea").selectionStart = 0;
document.querySelector("the-input textarea").selectionEnd = 0;
document.querySelector("the-input textarea").focus();
x = 0;
y = 0;
compileAndDisplay(true);
};
let sourceFromFile = fileObj => {
let reader = new FileReader();
reader.addEventListener("load", () => {
loadInput(reader.result);
}, false);
if (fileObj) {
reader.readAsText(fileObj);
}
};
let fetchSource = url => {
fetch(url)
.then(response=>{
if (response.ok) {
return response.text();
} else {
throw new Error(response.status.toString() + ": " + response.statusText);
}
})
.then(fileSource=>{
loadInput(fileSource);
})
.catch(err=>alert("Browser reported:\n" +err));
}
let returningWindowFocus = ()=> {
multiDialog = true;
setTimeout(()=>{
multiDialog = false;
window.removeEventListener("focus", returningWindowFocus);
}, 300);
}
document.querySelector("the-dialog[load] input[type=file]").addEventListener("click", function(e) {
if (multiDialog) { e.preventDefault(); }
multiDialog = true;
window.addEventListener("focus", returningWindowFocus);
e.target.parentElement.click();
});
document.querySelectorAll("the-dialog[load] input[name=load][type=radio]").forEach(el=>el.addEventListener("keyup", function(e) {
if (e.key === "Enter" && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
var el = e.target;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
el.querySelector("button[data-autofocus]").click();
}
}));
document.querySelector("the-dialog[load] button[load]").addEventListener("click", function(e) {
var el = e.target;
while (el.tagName.toLowerCase() !== "a-modal") {
el = el.parentElement;
}
if (document.querySelector("the-dialog[load] input[name=load][type=radio]").checked
&& document.querySelector("the-dialog[load] [type=file]").files.length) {
sourceFromFile(document.querySelector("the-dialog[load] [type=file]").files[0]);
} else if (document.querySelector("the-dialog[load] li[data-example] [type=radio]:checked")) {
loadInput(exampleDocuments[document.querySelector("the-dialog[load] li[data-example] [type=radio]:checked").parentElement.parentElement.dataset.example]);
} else if (document.querySelector("the-dialog[load] input[type=radio]:checked").dataset.url) {
fetchSource(document.querySelector("the-dialog[load] input[type=radio]:checked").dataset.url);
}
document.querySelectorAll("main *[tabIndex]").forEach(function(el) {el.tabIndex = el.dataset.tabindex||0});
el.style.display = "none";
});
document.querySelector("the-input textarea").addEventListener("keyup", function(e) {
if (e.key === "Insert" && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
var textarea = document.querySelector("the-input textarea");
var text = textarea.value;
var s1 = textarea.selectionStart;
var s2 = textarea.selectionEnd;
var a1 = text.slice(0,textarea.selectionStart);
var a2 = text.slice(textarea.selectionStart,textarea.selectionEnd);
var a3 = text.slice(textarea.selectionEnd);
var lines = text.split("\n");
l1 = Object.entries(lines).reduce(([i1,s1],[i2,s2])=>s1.includes(a1)?[i1,s1]:[i2,s1+"\n"+s2]);
l1 = parseInt(l1[0]);
if (s1 !== s2 || lines[l1] !== "") {
l2 = Object.entries(lines.slice(l1)).reduce(([i1,s1],[i2,s2])=>s1.includes(a2)?[i1,s1]:[i2,s1+"\n"+s2]);
l2 = parseInt(l2[0]);
l2 = l2 + l1;
indentedText = lines.slice(0,l1).concat(lines.slice(l1,l2+1).map(l=>l?" "+l:"").concat(lines.slice(l2+1))).join("\n");
textarea.value = indentedText;
textarea.selectionStart = s1 + 2;
if (s1 !== s2) {
textarea.selectionEnd = s2 + 2 + 2*(l2-l1);
} else {
textarea.selectionEnd = s1 + 2;
}
} else {
indentedText = lines.slice(0,l1+1).join("\n") + " " + lines.slice(l1).join("\n");
textarea.value = indentedText;
textarea.selectionStart = s1+2;
textarea.selectionEnd = s1+2;
}
} else if (e.key.toLowerCase() === "z" && e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey) {
var textarea = document.querySelector("the-input textarea");
textarea.blur();
textarea.focus()
} else if (e.key.toLowerCase() === "z" && e.ctrlKey && e.shiftKey && !e.altKey && !e.metaKey) {
var textarea = document.querySelector("the-input textarea");
textarea.blur();
textarea.focus()
} else if (e.key.toLowerCase() === "y" && e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey) {
var textarea = document.querySelector("the-input textarea");
textarea.blur();
textarea.focus()
} else if (e.key === "Insert" && e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey ) {
var textarea = document.querySelector("the-input textarea");
var text = textarea.value;
var s1 = textarea.selectionStart;
var s2 = textarea.selectionEnd;
var a1 = text.slice(0,textarea.selectionStart);
var a2 = text.slice(textarea.selectionStart,textarea.selectionEnd);
var a3 = text.slice(textarea.selectionEnd);
var lines = text.split("\n");
l1 = Object.entries(lines).reduce(([i1,s1],[i2,s2])=>s1.includes(a1)?[i1,s1]:[i2,s1+"\n"+s2]);
l1 = parseInt(l1[0]);
l2 = Object.entries(lines.slice(l1)).reduce(([i1,s1],[i2,s2])=>s1.includes(a2)?[i1,s1]:[i2,s1+"\n"+s2]);
l2 = parseInt(l2[0]);
l2 = l2 + l1;
var firstLineDeindents = Math.min(2, lines[l1].length - lines[l1].trimLeft().length);
var deindents = 0;
indentedText = lines.slice(0,l1).concat(lines.slice(l1,l2+1).map(l=>{ d=l?Math.min(2, l.length - l.trimLeft().length):0; deindents+=d; return l?( l.slice( d ) ):""}).concat(lines.slice(l2+1))).join("\n");
textarea.value = indentedText;
textarea.selectionStart = s1 - firstLineDeindents;
textarea.selectionEnd = s2 - deindents
} else if (automaticIndent && e.key === "Enter" && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
var textarea = document.querySelector("the-input textarea");
var text = textarea.value;
var s1 = textarea.selectionStart;
var a1 = text.slice(0,textarea.selectionStart);
var a2 = text.slice(textarea.selectionStart);
var prevLine = a1.split("\n").slice(-2,-1)[0];
var ltLine = prevLine.trimLeft();
var numSpaces = parseInt(prevLine.length - ltLine.length);
textarea.value = a1 + " ".repeat(numSpaces) + a2;
}
if (document.getElementById("autoComp").checked) {
compileAndDisplay();
}
});
let clearIFrameError = ()=>{
iframe = document.querySelector("iframe");
let newIFrame = document.createElement("iframe");
iframe.parentElement.insertBefore(newIFrame, iframe);
iframe.parentElement.removeChild(iframe);
bindIFrameFocus(document.querySelector("iframe"));
}
function compileAndDisplay(manual) {
if (!rateLimiting) {
rateLimiting = true;
} else {
return;
}
setTimeout(()=>rateLimiting = false, 50);
let prevFocused = document.querySelector(":focus");
let changedInputText = document.querySelector("the-input textarea").value;
if (inputText !== changedInputText || manual) {
inputText = changedInputText;
let p = new ParserTriv();
p.opt.of.stderr.warnings.verbosity = 4;
p.configMatterAndSource(changedInputText);
result = p.compileWithoutWarnings(changedInputText);
let np = new ParserTriv();
np.configMatterAndSource(result);
if (np.lenJsLn) {
// if input is:
// script: "interpretive"
// script[src="https://triv.co/3v.js"]:
result = result.split("\n").slice(np.lenJsLn).join("\n");
}
document.querySelector("the-output textarea").value = result;
document.querySelector("the-console the-warnings").innerHTML = "";
var warnings = p.outputFromWarnings();
if (p.opt.of.stderr.warnings.verbosity === 1) {
document.querySelector("the-console the-warnings").textContent = "Warnings: {1}".replace("{1}", p.warnings.length);
} else if (p.opt.of.stderr.warnings.verbosity === 2) {
warnings = warnings.map(w=>({...w, warningStatement: w.warningStatement.startsWith("Warnings: ")? w.warningStatement.slice("Warnings: ".length) : w.warningStatement.startsWith(", ")? w.warningStatement.slice(", ".length) : w.warningStatement}));
}
document.querySelector("the-console the-warnings").tabIndex = warnings.length? -1 : 0;
document.querySelector("the-console the-warnings").dataset.tabindex = warnings.length? -1 : 0;
warnings.forEach(warning=>{
warningElement = document.createElement("a-warning");
warningElement.tabIndex = 0;
warningElement.innerHTML = warning.warningStatement.split("\n").join("
");
warningElement.dataset.lineNum = warning.lineNum;
goToLine = function(e) {
let textarea = document.querySelector("the-input textarea");
let text = textarea.value;
let lines = text.split("\n");
let lineNum = e.target.dataset.lineNum;
let sr1 =0;
try {
sr1 = lines.slice(0,lineNum-1).reduce((a,b)=>a+"\n"+b).length+1;
} catch {
//
}
textarea.setSelectionRange(sr1, sr1);
textarea.blur() /* chromium */
textarea.focus();
textarea.setSelectionRange(sr1, textarea.selectionStart + lines[lineNum-1].length);
};
warningElement.addEventListener("click", goToLine);
warningElement.addEventListener("keyup", function (e) {
if (e.key === "Enter") {
goToLine(e);
}
});
warningElement.addEventListener("focus", function(e) {
e.target.parentElement.parentElement.firstElementChild.classList.add("focused");
});
warningElement.addEventListener("blur", function(e) {
e.target.parentElement.parentElement.firstElementChild.classList.remove("focused");
});
document.querySelector("the-console the-warnings").appendChild(warningElement);
});
for (let i of [0,1]) {
if (i > 0) {
clearIFrameError();
}
try {
iframe = document.querySelector("iframe");
if (!scrollPosRateLimiting) {
scrollPosRateLimiting = true;
let newX = iframe.contentWindow.scrollX;
let newY = iframe.contentWindow.scrollY
if (newX || newY) {
x = newX;
y = newY;
}
}
setTimeout(()=>scrollPosRateLimiting = false, 50);
let previousContents = iframe.contentWindow.document.documentElement.outerHTML;
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(result);
iframe.contentWindow.document.close();
let scrollReturn = ()=>{
iframe.contentWindow.scrollTo({
left: Math.min(x, iframe.contentWindow.scrollMaxX||x),
top: Math.min(y, iframe.contentWindow.scrollMaxY||y),
behavior: "instant"
});
};
if (iframe.contentWindow.scrollMaxX !== undefined) {
iframe.contentWindow.scrollTo({
left: Math.min(x, iframe.contentWindow.scrollMaxX),
top: Math.min(y, iframe.contentWindow.scrollMaxY),
behavior: "instant"
});
setTimeout(()=>{
if (iframe.contentWindow.scrollX === 0 && iframe.contentWindow.scrollY == 0) {
jitterScrollReturn();
}
}, 1);
}
jitterScrollReturn = () => {
setTimeout(()=>{
if (iframe.contentWindow.scrollMaxX !== undefined && iframe.contentWindow.document.documentElement.outerHTML !== previousContents && (x !== iframe.contentWindow.scrollX || y !== iframe.contentWindow.scrollY)) {
scrollReturn();
setTimeout(()=>{
if (true) {
scrollReturn();
setTimeout(()=>{
if (true) {
scrollReturn();
setTimeout(()=>{
if (true) {
scrollReturn();
setTimeout(()=>{
if (true) {
scrollReturn();
setTimeout(()=>{
if (true) {
scrollReturn();
setTimeout(()=>{
if (true) {
scrollReturn();
setTimeout(()=>{
scrollReturn();
}, 1);
}
}, 1);
}
}, 1);
}
}, 1);
}
}, 1);
}
}, 1);
}
}, 1);
}
}, 1);
};
break;
} catch (e) {
//
}
}
bindIFrameFocus(document.querySelector("iframe"));
try {
document.querySelector("the-preview the-title").textContent = Object.values(iframe.contentWindow.document.head.children).filter(el=>el.tagName.toLowerCase()==="title")[0].textContent
document.querySelector("the-preview the-title").style.visibility = "visible";
} catch {
document.querySelector("the-preview the-title").style.visibility = "hidden";
document.querySelector("the-preview the-title").textContent = "";
}
setTimeout( ()=>{
if (prevFocused) {
prevFocused.focus();
}
}, 50);
}
}
if (firstRun) {
setCookie("firstRun", 0);
loadInput(exampleDocuments.welcome);
}
}
})();
"""
body:
header: """
"""
[[-]]/main
[-]/the-chrome & theming
the-menu:
the-toolbar:
button[new title="New" data-dialog="the-dialog[new]"]:
toolbar-icon[raster]:img[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADAFBMVEUAAAD/AAAA/wD//wAAAP//AP8A///////b29u2traSkpJtbW1JSUkkJCTbAAC2AACSAABtAABJAAAkAAAA2wAAtgAAkgAAbQAASQAAJADb2wC2tgCSkgBtbQBJSQAkJAAAANsAALYAAJIAAG0AAEkAACTbANu2ALaSAJJtAG1JAEkkACQA29sAtrYAkpIAbW0ASUkAJCT/29vbtra2kpKSbW1tSUlJJCT/trbbkpK2bW2SSUltJCT/kpLbbW22SUmSJCT/bW3bSUm2JCT/SUnbJCT/JCTb/9u227aStpJtkm1JbUkkSSS2/7aS25Jttm1JkkkkbSSS/5Jt221JtkkkkiRt/21J20kktiRJ/0kk2yQk/yTb2/+2ttuSkrZtbZJJSW0kJEm2tv+SktttbbZJSZIkJG2Skv9tbdtJSbYkJJJtbf9JSdskJLZJSf8kJNskJP///9vb27a2tpKSkm1tbUlJSST//7bb25K2tm2SkkltbST//5Lb2222tkmSkiT//23b20m2tiT//0nb2yT//yT/2//bttu2kraSbZJtSW1JJEn/tv/bktu2bbaSSZJtJG3/kv/bbdu2SbaSJJL/bf/bSdu2JLb/Sf/bJNv/JP/b//+229uStrZtkpJJbW0kSUm2//+S29tttrZJkpIkbW2S//9t29tJtrYkkpJt//9J29sktrZJ//8k29sk////27bbtpK2km2SbUltSSRJJAD/tpLbkm22bUmSSSRtJAD/ttvbkra2bZKSSW1tJElJACT/krbbbZK2SW2SJEltACTbtv+2ktuSbbZtSZJJJG0kAEm2kv+SbdttSbZJJJIkAG222/+SttttkrZJbZIkSW0AJEmStv9tkttJbbYkSZIAJG22/9uS27ZttpJJkm0kbUkASSSS/7Zt25JJtm0kkkkAbSTb/7a225KStm1tkklJbSQkSQC2/5KS221ttklJkiQkbQD/tgDbkgC2bQCSSQD/ALbbAJK2AG2SAEkAtv8AktsAbbYASZIAAAAAAADPKgIEAAAArElEQVQ4y6VT2w2EMAyzKyZgi06CWqkjMQM7sELHYRjfBwoXOEA9iBT1lTq2q1ISXoUkSEIpRQAucxxHWa3PYEC1VkjiWQJA3/eY51mXDNbpbwd/Nk2Taq27uq5FZikFJOWbWtAWJGV07+JYFx6YvmvyN4CX0gxwvGSRc1bXStuD+Hl4qj3GuAK3vsKZDEls9mAYho2FjSS/HqSUmun7vQ1gWZZLt++A+PY7fwAq4qyWrauzvAAAAABJRU5ErkJggg=="]/
toolbar-icon[system]: 📄
toolbar-icon[vector]: '''
'''
toolbar-caption: New
button[save title="Save"]:
toolbar-icon[raster]:img[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADAFBMVEUAAAD/AAAA/wD//wAAAP//AP8A///////b29u2traSkpJtbW1JSUkkJCTbAAC2AACSAABtAABJAAAkAAAA2wAAtgAAkgAAbQAASQAAJADb2wC2tgCSkgBtbQBJSQAkJAAAANsAALYAAJIAAG0AAEkAACTbANu2ALaSAJJtAG1JAEkkACQA29sAtrYAkpIAbW0ASUkAJCT/29vbtra2kpKSbW1tSUlJJCT/trbbkpK2bW2SSUltJCT/kpLbbW22SUmSJCT/bW3bSUm2JCT/SUnbJCT/JCTb/9u227aStpJtkm1JbUkkSSS2/7aS25Jttm1JkkkkbSSS/5Jt221JtkkkkiRt/21J20kktiRJ/0kk2yQk/yTb2/+2ttuSkrZtbZJJSW0kJEm2tv+SktttbbZJSZIkJG2Skv9tbdtJSbYkJJJtbf9JSdskJLZJSf8kJNskJP///9vb27a2tpKSkm1tbUlJSST//7bb25K2tm2SkkltbST//5Lb2222tkmSkiT//23b20m2tiT//0nb2yT//yT/2//bttu2kraSbZJtSW1JJEn/tv/bktu2bbaSSZJtJG3/kv/bbdu2SbaSJJL/bf/bSdu2JLb/Sf/bJNv/JP/b//+229uStrZtkpJJbW0kSUm2//+S29tttrZJkpIkbW2S//9t29tJtrYkkpJt//9J29sktrZJ//8k29sk////27bbtpK2km2SbUltSSRJJAD/tpLbkm22bUmSSSRtJAD/ttvbkra2bZKSSW1tJElJACT/krbbbZK2SW2SJEltACTbtv+2ktuSbbZtSZJJJG0kAEm2kv+SbdttSbZJJJIkAG222/+SttttkrZJbZIkSW0AJEmStv9tkttJbbYkSZIAJG22/9uS27ZttpJJkm0kbUkASSSS/7Zt25JJtm0kkkkAbSTb/7a225KStm1tkklJbSQkSQC2/5KS221ttklJkiQkbQD/tgDbkgC2bQCSSQD/ALbbAJK2AG2SAEkAtv8AktsAbbYASZIAAAAAAADPKgIEAAAA6UlEQVQ4y6VTuw2FMAy8IKChggYqegaALegYgAGyjvsMwABUDMAMVAxARZXGr3lGfPUeykmRTrZzcs6OYma4wBeitea+75EkCQDAWnspXtcV0zSpQ5CZ8e2ChQdBsPH9AcBFURxyG4miaEvUdX0rIMJlWfJFII7jLbgvOHcgXDrxn8zJsuzgrrUWRPRs4h7jOKpf7odhCADw4Aj/rNi2LXddhzzPL8XzPKNpGhhj1GWMaZqyTIOIbk0kIpZpidG3AneXz+MWAe/8hLfw9mv6BsuyAACUfCatNQ/D8LdAVVUwxijl+hud9+ADXa8B5N/LLowAAAAASUVORK5CYII="]/
toolbar-icon[system]: 💾
toolbar-icon[vector]: '''
'''
toolbar-caption: Save
button[load title="Load" data-dialog="the-dialog[load]" onClick="if (window.location.protocol === 'file:') { document.querySelectorAll('the-dialog[load] li[file] input').forEach(el=>{el.disabled = true; el.title='Not permitted by browser for a Web application running from a file'})}"]:
toolbar-icon[raster]:img[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADAFBMVEUAAAD/AAAA/wD//wAAAP//AP8A///////b29u2traSkpJtbW1JSUkkJCTbAAC2AACSAABtAABJAAAkAAAA2wAAtgAAkgAAbQAASQAAJADb2wC2tgCSkgBtbQBJSQAkJAAAANsAALYAAJIAAG0AAEkAACTbANu2ALaSAJJtAG1JAEkkACQA29sAtrYAkpIAbW0ASUkAJCT/29vbtra2kpKSbW1tSUlJJCT/trbbkpK2bW2SSUltJCT/kpLbbW22SUmSJCT/bW3bSUm2JCT/SUnbJCT/JCTb/9u227aStpJtkm1JbUkkSSS2/7aS25Jttm1JkkkkbSSS/5Jt221JtkkkkiRt/21J20kktiRJ/0kk2yQk/yTb2/+2ttuSkrZtbZJJSW0kJEm2tv+SktttbbZJSZIkJG2Skv9tbdtJSbYkJJJtbf9JSdskJLZJSf8kJNskJP///9vb27a2tpKSkm1tbUlJSST//7bb25K2tm2SkkltbST//5Lb2222tkmSkiT//23b20m2tiT//0nb2yT//yT/2//bttu2kraSbZJtSW1JJEn/tv/bktu2bbaSSZJtJG3/kv/bbdu2SbaSJJL/bf/bSdu2JLb/Sf/bJNv/JP/b//+229uStrZtkpJJbW0kSUm2//+S29tttrZJkpIkbW2S//9t29tJtrYkkpJt//9J29sktrZJ//8k29sk////27bbtpK2km2SbUltSSRJJAD/tpLbkm22bUmSSSRtJAD/ttvbkra2bZKSSW1tJElJACT/krbbbZK2SW2SJEltACTbtv+2ktuSbbZtSZJJJG0kAEm2kv+SbdttSbZJJJIkAG222/+SttttkrZJbZIkSW0AJEmStv9tkttJbbYkSZIAJG22/9uS27ZttpJJkm0kbUkASSSS/7Zt25JJtm0kkkkAbSTb/7a225KStm1tkklJbSQkSQC2/5KS221ttklJkiQkbQD/tgDbkgC2bQCSSQD/ALbbAJK2AG2SAEkAtv8AktsAbbYASZIAAAAAAADPKgIEAAAAuklEQVQ4y6WTsQ2DMBRE71B2YAF6JvkewI07xmAo6NmBFaioXLm/FBFGIkHB8KWTrC/5/M7fpiQ8qQoAuq4Tyaymaa67mpkk4ai6rn/2j3qdGa/rSufcF8k0TUgp8S/BmQAohJD30Mw0DAMBoO97xRixLAtu3QGAYprqYFY0QjNDdXf+zrlP9C1C27bF+JJ2gnmeiwhCCACwv4OS/Bl/MyApSbxqMI5jXlMSvPdKKV0m2E7PBo9/45N6A+UT75LiTrO9AAAAAElFTkSuQmCC"]/
toolbar-icon[system]: 📂
toolbar-icon[vector]: '''
'''
toolbar-caption: Load
button[theme title="Theme" data-dialog="the-dialog[theme]"]:
toolbar-icon[raster]:img[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADAFBMVEUAAAD/AAAA/wD//wAAAP//AP8A///////b29u2traSkpJtbW1JSUkkJCTbAAC2AACSAABtAABJAAAkAAAA2wAAtgAAkgAAbQAASQAAJADb2wC2tgCSkgBtbQBJSQAkJAAAANsAALYAAJIAAG0AAEkAACTbANu2ALaSAJJtAG1JAEkkACQA29sAtrYAkpIAbW0ASUkAJCT/29vbtra2kpKSbW1tSUlJJCT/trbbkpK2bW2SSUltJCT/kpLbbW22SUmSJCT/bW3bSUm2JCT/SUnbJCT/JCTb/9u227aStpJtkm1JbUkkSSS2/7aS25Jttm1JkkkkbSSS/5Jt221JtkkkkiRt/21J20kktiRJ/0kk2yQk/yTb2/+2ttuSkrZtbZJJSW0kJEm2tv+SktttbbZJSZIkJG2Skv9tbdtJSbYkJJJtbf9JSdskJLZJSf8kJNskJP///9vb27a2tpKSkm1tbUlJSST//7bb25K2tm2SkkltbST//5Lb2222tkmSkiT//23b20m2tiT//0nb2yT//yT/2//bttu2kraSbZJtSW1JJEn/tv/bktu2bbaSSZJtJG3/kv/bbdu2SbaSJJL/bf/bSdu2JLb/Sf/bJNv/JP/b//+229uStrZtkpJJbW0kSUm2//+S29tttrZJkpIkbW2S//9t29tJtrYkkpJt//9J29sktrZJ//8k29sk////27bbtpK2km2SbUltSSRJJAD/tpLbkm22bUmSSSRtJAD/ttvbkra2bZKSSW1tJElJACT/krbbbZK2SW2SJEltACTbtv+2ktuSbbZtSZJJJG0kAEm2kv+SbdttSbZJJJIkAG222/+SttttkrZJbZIkSW0AJEmStv9tkttJbbYkSZIAJG22/9uS27ZttpJJkm0kbUkASSSS/7Zt25JJtm0kkkkAbSTb/7a225KStm1tkklJbSQkSQC2/5KS221ttklJkiQkbQD/tgDbkgC2bQCSSQD/ALbbAJK2AG2SAEkAtv8AktsAbbYASZIAAAAAAADPKgIEAAABEklEQVQ4y6WTrZGHMBDFX5jDUQAKEwyKGsCgUFHEgKEGaqALMLRBIygUigIw71S4hI+b/9ztzIrs/vI22WQFSbyZEOJMkhSPjC3QNA0BIAxD9H1/g7uuw7ZtAIBhGIRRBklIKQngY5dSkiQ8ox4EgVOtqiqQFMbbtnXyJ29OkGXZqW5iT26YLMtIEreEUuoUKMuSRVEwSZIzVhQFAdD3/R8B+242aFdO05TXYgDovT3htSdhGD5yrwL7vjvrdV2fwd96kKYppZROD5RS9x7YiU9fwRTyno4shGCe584f11rT/tqG/zKB4zicq83z7MzC1QzvzILWmnEcY11XjON421TXNaIowrIsmKZJ3AT+PY1/sW/t7hpnMNe6+gAAAABJRU5ErkJggg=="]/
toolbar-icon[system]: 🛠
toolbar-icon[vector]: '''
'''
toolbar-caption: Theme
input.button#autoComp[type="checkbox" checked]/
label.button[checkbox for="autoComp" title="Automatic compilation" tabIndex=0 role="button"]:div:span:
toolbar-icon[raster]:img[src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADAFBMVEUAAAD/AAAA/wD//wAAAP//AP8A///////b29u2traSkpJtbW1JSUkkJCTbAAC2AACSAABtAABJAAAkAAAA2wAAtgAAkgAAbQAASQAAJADb2wC2tgCSkgBtbQBJSQAkJAAAANsAALYAAJIAAG0AAEkAACTbANu2ALaSAJJtAG1JAEkkACQA29sAtrYAkpIAbW0ASUkAJCT/29vbtra2kpKSbW1tSUlJJCT/trbbkpK2bW2SSUltJCT/kpLbbW22SUmSJCT/bW3bSUm2JCT/SUnbJCT/JCTb/9u227aStpJtkm1JbUkkSSS2/7aS25Jttm1JkkkkbSSS/5Jt221JtkkkkiRt/21J20kktiRJ/0kk2yQk/yTb2/+2ttuSkrZtbZJJSW0kJEm2tv+SktttbbZJSZIkJG2Skv9tbdtJSbYkJJJtbf9JSdskJLZJSf8kJNskJP///9vb27a2tpKSkm1tbUlJSST//7bb25K2tm2SkkltbST//5Lb2222tkmSkiT//23b20m2tiT//0nb2yT//yT/2//bttu2kraSbZJtSW1JJEn/tv/bktu2bbaSSZJtJG3/kv/bbdu2SbaSJJL/bf/bSdu2JLb/Sf/bJNv/JP/b//+229uStrZtkpJJbW0kSUm2//+S29tttrZJkpIkbW2S//9t29tJtrYkkpJt//9J29sktrZJ//8k29sk////27bbtpK2km2SbUltSSRJJAD/tpLbkm22bUmSSSRtJAD/ttvbkra2bZKSSW1tJElJACT/krbbbZK2SW2SJEltACTbtv+2ktuSbbZtSZJJJG0kAEm2kv+SbdttSbZJJJIkAG222/+SttttkrZJbZIkSW0AJEmStv9tkttJbbYkSZIAJG22/9uS27ZttpJJkm0kbUkASSSS/7Zt25JJtm0kkkkAbSTb/7a225KStm1tkklJbSQkSQC2/5KS221ttklJkiQkbQD/tgDbkgC2bQCSSQD/ALbbAJK2AG2SAEkAtv8AktsAbbYASZIAAAAAAADPKgIEAAAAvUlEQVQ4y6VTsQ2DMBC8tyL3uKIxK1BR0bECzOAZPBTDMACVKyoPQHMpohiiJJINL730Ounff/dnIYk78QCAaZoYQshqaJoG8zxLArquI0mU5DiOqUdprYvX3rYt1WKtZV3XxQNCCC8a53Vys6qqg0KMsZiCMSbVat/34gHruqYrqIJX6b3/Nk3f91kaAOA7z7i64j4RoTGGlzUAAOfcYeVhGPhP7Q/bAmjbFsuyHFju7a21P7WSu79R4WY8ATxo4W1b1oKgAAAAAElFTkSuQmCC"]/
toolbar-icon[system]: ⏯
toolbar-icon[vector]: '''
'''
toolbar-caption: Comp.
[-]/the-contents
the-panel:
the-input:
the-label[data-focus="textarea" theming]:
textarea[id="theInput" spellcheck="false" wrap="off"]:
resizing-grip[theming]:
the-output[theming]:
the-label[data-focus="textarea"]:
textarea[readonly id="theOutput" wrap="off"]:
resizing-grip:
the-console[theming]:
the-label[data-focus="the-warnings"]:
the-warnings[tabIndex=0]:
the-preview:
the-label[data-focus="iframe" theming]:the-title[style="visibility:hidden"]:
the-display:
iframe:
[]*
[New Document]/a-modal data-title
the-overlay:
the-dialog[new]:
the-heading[theming]:
close-button:
the-prompt: Are you sure you want to create a new document?
the-buttons[theming]:
[]*
[Load]/a-modal data-title
the-overlay:
the-dialog[load]:
the-heading[theming]:
close-button:
the-prompt: Select a file to load:
ul:
li[file]:
label:
input[type="radio" name="load"]/
span:input[type="file"]/
a-line: or
the-grid:
li[data-example="welcome"]:
label:
input[type="radio" name="load" checked]/
span: Welcome
docu-preview:img[src=""]/
li[data-example="features"]:
label:
input[type="radio" name="load" data-url="./features.html"]/
span: Features
docu-preview:img[src=""]/
li[data-example="tutorial"]:
label:
input[type="radio" name="load"]/
span: Tutorial
docu-preview:
li:
label:
input[type="radio" name="load" data-url="./advanced.html" disabled]/
span: Advanced
docu-preview:
the-buttons[theming]:
button[load data-autofocus="true"]: Load
button[cancel data-type="close"]: Cancel
[]*
[Theme]/a-modal data-title
the-overlay:
the-dialog[theme]:
the-heading[theming]:
close-button:
div:label[range]:
span: Warmth
input[type="range" value="0" min="0" max="1" step="0.01" data-var="--theme-warmth" data-default="0" onInput="document.querySelector(':root').style.setProperty(this.dataset.var, this.value)"]/
div:label[range]:
span: Hue
input[type="range" value="0" min="0" max="180" data-var="--theme-wheel" data-default="0deg" onInput="document.querySelector(':root').style.setProperty(this.dataset.var, this.value.toString()+'deg')"]/
div:label[range]:
span: Saturation
input[type="range" value="1" min="0" max="30" step="0.01" data-var="--theme-saturation" data-default="1" onInput="document.querySelector(':root').style.setProperty(this.dataset.var, this.value)"]/
div:label[range]:
span: Contrast
input[type="range" value="100" min="100" max="600" step="1" data-var="--theme-contrast" data-default="100%" onInput="document.querySelector(':root').style.setProperty(this.dataset.var, (this.value).toString()+'%')"]/
label[icons]: Icons
< select[onChange="document.querySelectorAll('toolbar-icon').forEach(el=>{el.attributes.hasOwnProperty(this.value)?el.style.display = 'block' : el.style.display = 'none'; this.value === 'none'? document.documentElement.style.setProperty('--chrome-height', document.documentElement.style.getPropertyValue('--one-label-chrome-height')) : document.documentElement.style.setProperty('--chrome-height', document.documentElement.style.getPropertyValue('--two-label-chrome-height'))})"]: >
select[onChange="let theRoot = document.querySelector(':root'), captions=document.querySelector('the-dialog[theme] [captions] input[type=checkbox]'); if (this.value === 'none' && !captions.checked) { captions.click(); } captions.disabled = this.value === 'none'; { this.value === 'none'? theRoot.classList.remove('icons') : theRoot.classList.add('icons'); ['raster', 'vector', 'system'].forEach(iconStyle=>this.value === iconStyle? document.querySelector(':root').classList.add(iconStyle) : theRoot.classList.remove(iconStyle)); }"]:
option[value="none"]: --- none ---
option[value="raster" selected]: Raster
option[value="vector"]: Vector
option[value="system"]: System
label[checkbox captions]:
input[type="checkbox" checked onclick='document.documentElement.classList.toggle("captions"); document.querySelector("the-dialog[theme] [checkbox][captions] input[type=checkbox]").checked = document.documentElement.classList.contains("captions");']/
span: Button captions
label[checkbox preview]:
input[type="checkbox"]/
span: Preview theme
the-buttons[theming]:
button[reset onClick="document.querySelectorAll('the-dialog[theme] input[type=range]').forEach(el=>{el.value=parseFloat(el.dataset.default); document.documentElement.style.setProperty(el.dataset.var, el.dataset.default)})"]: Reset
button[close data-type="close" data-autofocus="true"]: Close
[]*
footer[theming]:
the-version:
span: API version
the-link:
a[href="https://www.triv.co" target="_blank" tabIndex="-1"]: www.triv.co