@fretfall/player 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -10
- package/highway.js +1 -1
- package/index.html +170 -120
- package/mount.d.ts +50 -0
- package/mount.js +170 -120
- package/music.js +1 -1
- package/package.json +1 -1
- package/player.js +1 -1
- package/sync.js +1 -1
- package/themes.js +1 -1
package/mount.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
let l=null;const d=e=>l??=i(e);async function i(e){const a=Object.assign(document.createElement("style"),{textContent:'[data-fretfall]{--bg: #0e1014;--ink: #0e1014;--text: #e8eaef;--muted: #7b8190;--accent: #c8f04a;--chip: #171a20;--chip-border: #2a2f38;--done: #e8eaef;--todo: #23272f;--ui: system-ui, sans-serif;--num: system-ui, sans-serif;--lyric: system-ui, sans-serif;--lyric-style: normal}:where([data-fretfall]) *{box-sizing:border-box}:where([data-fretfall]) [hidden]{display:none!important}[data-fretfall]:not([data-fretfall-dock]){height:100%}[data-fretfall]:not([data-fretfall-dock]){margin:0;overflow:hidden;background:var(--bg);color:var(--text);font:14px/1.4 var(--ui);accent-color:var(--accent)}:where([data-fretfall]) canvas{position:fixed;inset:0;width:100%;height:100%;display:block}:where([data-fretfall]) button{font:inherit;color:inherit}:where([data-fretfall]) .bar{position:fixed;z-index:3;left:32px;right:32px;top:18px;height:40px;display:flex;align-items:center;justify-content:space-between;gap:24px;transition:transform .25s ease,opacity .25s ease,visibility .25s}:where([data-fretfall]) .group{display:flex;align-items:center;gap:10px;min-width:0}:where([data-fretfall]) .group:last-child{flex:none}:where([data-fretfall]) .wordmark{display:flex;align-items:center;gap:7px;font:700 15px var(--num);letter-spacing:.22em}:where([data-fretfall]) :is(.wordmark,.welcome-mark) .fall{transform-box:fill-box;transform-origin:center;transform:rotate(14deg);animation:fall .75s .8s both}@keyframes fall{0%{transform:translate(-3.5px,-1.42px) rotate(0);animation-timing-function:cubic-bezier(.55,0,.85,.35)}40%{transform:translate(0) rotate(18deg);animation-timing-function:cubic-bezier(.2,.7,.4,1)}56%{transform:translateY(-.35px) rotate(11.5deg);animation-timing-function:ease-in-out}74%{transform:translateY(.08px) rotate(15.2deg);animation-timing-function:ease-in-out}88%{transform:translate(0) rotate(13.6deg);animation-timing-function:ease-in-out}to{transform:translate(0) rotate(14deg)}}@media(prefers-reduced-motion:reduce){:where([data-fretfall]) .wordmark .fall{animation:none}}:where([data-fretfall]) .seg{display:flex;gap:2px;padding:3px;border-radius:9px;background:var(--chip);border:1px solid var(--chip-border);overflow-x:auto;scrollbar-width:none}:where([data-fretfall]) .seg button{border:0;background:none;cursor:pointer;padding:5px 12px;border-radius:6px;font:500 13px var(--ui);color:var(--muted);white-space:nowrap}:where([data-fretfall]) .seg button[aria-pressed=true]{background:var(--text);color:var(--ink);font-weight:600}:where([data-fretfall]) .seg select{max-width:22cqw;border:0;padding:4px 6px;background:none;color:var(--text);font:600 13px var(--ui)}:where([data-fretfall]) .seg option{background:var(--ink);color:var(--text)}:where([data-fretfall]) .icon{flex:none;cursor:pointer;width:36px;height:36px;display:grid;place-items:center;padding:0;border-radius:8px;background:var(--chip);border:1px solid var(--chip-border);color:var(--text)}:where([data-fretfall]) .icon[aria-pressed=true],:where([data-fretfall]) .icon[aria-expanded=true]{background:var(--accent);border-color:var(--accent);color:var(--ink)}:where([data-fretfall]) button:focus-visible,:where([data-fretfall]) input:focus-visible{outline:2px solid var(--accent);outline-offset:2px}:where([data-fretfall]) .speed{height:36px;display:flex;align-items:center;padding:0 2px;border-radius:8px;background:var(--chip);border:1px solid var(--chip-border);color:var(--muted)}:where([data-fretfall]) .speed button{cursor:pointer;width:28px;height:32px;display:grid;place-items:center;padding:0;border:0;background:none;color:inherit}:where([data-fretfall]) .speed #speed{width:auto;min-width:46px;font:600 14px var(--num);color:var(--text)}:where([data-fretfall]) .time{margin-right:6px;font:14px var(--num);color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}:where([data-fretfall]) .divider{width:1px;height:24px;margin:0 4px;background:var(--chip-border)}:where([data-fretfall]) .menu{display:contents}:where([data-fretfall]) #menuButton{display:none}:where([data-fretfall]) #phrases{position:fixed;left:32px;right:32px;top:74px;height:54px;cursor:pointer;touch-action:none;-webkit-user-select:none;user-select:none}:where([data-fretfall]) #phrases div{position:absolute;bottom:0;min-width:2px;border-radius:2px;background:var(--todo)}:where([data-fretfall]) #phrases div.done{background:var(--done)}:where([data-fretfall]) #phraseTime{position:absolute;top:calc(100% + 16px);transform:translate(-50%);padding:2px 7px;border-radius:6px;background:var(--ink);border:1px solid var(--chip-border);font:600 11px var(--num);font-variant-numeric:tabular-nums;color:var(--text);pointer-events:none}:where([data-fretfall]) #loopBox{position:absolute;top:-6px;bottom:-17px;border:1.5px solid var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);box-shadow:0 0 18px color-mix(in srgb,var(--accent) 22%,transparent)}:where([data-fretfall]) #loopBox:before,:where([data-fretfall]) #loopBox:after{content:"";position:absolute;top:-11px;bottom:-11px;width:4px;border:4px solid transparent;border-radius:6px;background:var(--accent) padding-box;cursor:ew-resize}:where([data-fretfall]) #loopBox:before{left:-6.75px}:where([data-fretfall]) #loopBox:after{right:-6.75px}:where([data-fretfall]) #progress{position:fixed;left:32px;right:32px;top:134px;height:5px;border-radius:3px;overflow:hidden;background:var(--todo)}:where([data-fretfall]) #progress div{width:0;height:100%;background:var(--accent);opacity:.9}[data-fretfall][data-docked] #phrases{top:18px}[data-fretfall][data-docked] #progress{top:78px}[data-fretfall][data-docked] #lyrics{top:108px}[data-fretfall][data-docked] .sheet{top:18px}:where([data-fretfall]) #lyrics{position:fixed;left:40px;top:164px;max-width:min(560px,46cqw);display:flex;flex-direction:column;gap:8px;pointer-events:none;font-family:var(--lyric);font-style:var(--lyric-style);text-shadow:0 2px 14px var(--ink),0 0 4px var(--ink)}:where([data-fretfall]) #section{min-height:16px;font:600 12px var(--num);letter-spacing:.18em;color:var(--accent)}:where([data-fretfall]) #lines{position:relative;height:2.45em;font-size:clamp(20px,2.3cqw,32px);line-height:1.15}:where([data-fretfall]) #lines div{position:absolute;top:0;left:0;white-space:nowrap;color:var(--muted);transition:transform .45s cubic-bezier(.22,1,.36,1),opacity .35s ease}:where([data-fretfall]) #lines .low{transform:translateY(1.3em);opacity:.5}:where([data-fretfall]) #lines .gone{opacity:0;transition-duration:.45s,.25s}:where([data-fretfall]) #lines .gone.up{transform:translateY(-.8em)}:where([data-fretfall]) #lines span{transition:color .15s}:where([data-fretfall]) #lines .sung{color:var(--text)}@media(prefers-reduced-motion:reduce){:where([data-fretfall]) #lines div{transition-property:opacity}}:where([data-fretfall]) #info{position:fixed;left:40px;right:226px;bottom:14px;display:flex;align-items:center;font-size:13px;white-space:nowrap;color:var(--muted);pointer-events:none}:where([data-fretfall]) #info b{color:var(--text);font-weight:600}:where([data-fretfall]) #info>span+span:before{content:"";display:inline-block;width:1px;height:12px;margin:0 14px;vertical-align:-1px;background:var(--chip-border)}:where([data-fretfall]) #info .tuning{position:relative;pointer-events:auto;cursor:help}:where([data-fretfall]) #info .tuning>b{text-decoration:underline dotted var(--muted);text-underline-offset:3px}:where([data-fretfall]) #info .tip{left:0;right:auto;white-space:normal}:where([data-fretfall]) #info .tuning:is(:hover,:focus)>.tip{opacity:1;visibility:visible;transform:none}:where([data-fretfall]) .pegs{display:flex;align-items:flex-start;gap:4px;margin:10px 0 8px}:where([data-fretfall]) .peg{display:flex;flex-direction:column;align-items:center;min-width:26px;gap:2px;font:600 13px var(--num)}:where([data-fretfall]) .peg i{font-style:normal;font-size:11px;color:var(--muted)}:where([data-fretfall]) .peg .move:before{content:"";display:block;width:3px;height:calc(6px + var(--d) * 3px);margin:2px auto 3px;border-radius:2px;background:var(--c)}:where([data-fretfall]) .peg strong{color:var(--c)}:where([data-fretfall]) .peg.same{opacity:.45}:where([data-fretfall]) .tip small{display:block;font-size:11px}[data-fretfall]:fullscreen .bar{transform:translateY(calc(-100% - 18px));opacity:0;visibility:hidden;transition-delay:.4s}[data-fretfall]:fullscreen:has(#phrases:hover,#progress:hover,.bar:hover) .bar{transform:none;opacity:1;visibility:visible;transition-delay:0s}:where([data-fretfall]) #tools{position:fixed;z-index:3;right:32px;bottom:6px}:where([data-fretfall]) #tools .icon{position:relative}:where([data-fretfall]) .icon:disabled{cursor:default;color:var(--muted)}:where([data-fretfall]) .icon:disabled svg{opacity:.5}:where([data-fretfall]) #loopTools{position:fixed;z-index:4;display:flex;transform:translate(-50%,calc(-50% + 3px))}:where([data-fretfall]) #loopTools .icon{width:32px;height:26px;background:var(--ink);border-color:var(--accent)}:where([data-fretfall]) #loopTools svg{width:15px;height:15px}:where([data-fretfall]) #trainer{border-radius:13px 0 0 13px}:where([data-fretfall]) #clearLoop{border-left:0;border-radius:0 13px 13px 0;color:var(--muted)}:where([data-fretfall]) #clearLoop:hover{color:var(--text)}:where([data-fretfall]) #loopTools .icon[aria-pressed=true]{background:var(--accent);color:var(--ink)}:where([data-fretfall]) .tip{position:absolute;right:0;bottom:calc(100% + 10px);width:max-content;max-width:250px;padding:8px 10px;border-radius:8px;background:var(--ink);border:1px solid var(--chip-border);box-shadow:0 12px 30px #00000073;color:var(--muted);font:12px/1.45 var(--ui);text-align:left;pointer-events:none;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .12s ease,transform .12s ease,visibility .12s}:where([data-fretfall]) .tip b{display:flex;justify-content:space-between;gap:12px;margin-bottom:2px;color:var(--text);font-weight:600}:where([data-fretfall]) .tip kbd{padding:0 5px;border:1px solid var(--chip-border);border-radius:4px;color:var(--muted);font:inherit}:where([data-fretfall]) :is(.icon,.speed):hover>.tip,:where([data-fretfall]) .icon:focus-visible>.tip,:where([data-fretfall]) .speed:focus-within>.tip{opacity:1;visibility:visible;transform:none}[data-fretfall]:where([data-fretfall-dock]){display:flex;align-items:center;gap:10px}:where([data-fretfall]) .bar :is(.icon,.speed),[data-fretfall]:where([data-fretfall-dock]) :is(.icon,.speed){position:relative}:where([data-fretfall]) .bar .tip,[data-fretfall]:where([data-fretfall-dock]) .tip{top:calc(100% + 10px);bottom:auto;transform:translateY(-4px)}:where([data-fretfall]) .bar [aria-expanded=true]>.tip,[data-fretfall]:where([data-fretfall-dock]) [aria-expanded=true]>.tip{display:none}:where([data-fretfall]) #loopTools .tip{top:calc(100% + 10px);bottom:auto;left:var(--tip, 50%);right:auto;transform:translate(calc(-1 * var(--tip, 50%)),-4px)}:where([data-fretfall]) #loopTools .icon:hover>.tip,:where([data-fretfall]) #loopTools .icon:focus-visible>.tip{transform:translate(calc(-1 * var(--tip, 50%)))}[data-fretfall]:fullscreen :is(#info,#tools>:not(#minimal)){display:none}[data-fretfall].minimal :is(.bar,#phrases,#progress,#loopTools,#info,#tools>:not(#minimal)){display:none}[data-fretfall].tab2d .only-3d,[data-fretfall]:not(.tab2d) .only-2d{display:none}[data-fretfall].tab2d .only-3d+.only-3d+h3{padding-top:0;border-top:0}[data-fretfall].minimal #lyrics{top:24px}:where([data-fretfall]) #status{position:fixed;left:50%;top:42%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:12px;max-width:min(560px,90cqw);padding:10px 16px;border-radius:10px;background:var(--chip);border:1px solid var(--chip-border);backdrop-filter:blur(10px);text-align:center}[data-fretfall].banding :is(#highway,#phrases,#progress,#loopTools,#lyrics,#info,#intro,#time){display:none}:where([data-fretfall]) #bandNote{position:fixed;left:50%;top:56%;transform:translate(-50%,-50%);display:grid;justify-items:center;gap:8px;max-width:min(440px,90cqw);padding:14px 20px;border-radius:10px;background:var(--chip);border:1px solid var(--chip-border);text-align:center}:where([data-fretfall]) #bandNote .text-button{justify-self:center}:where([data-fretfall]) #status:not(.loading) .bars{display:none}:where([data-fretfall]) .bars{flex:none;display:inline-flex;align-items:flex-end;gap:3px;height:16px}:where([data-fretfall]) .bars i{width:3px;height:100%;border-radius:2px;background:var(--accent);transform:scaleY(.3);transform-origin:bottom}:where([data-fretfall]) .bars.moving i{animation:bars .8s ease-in-out infinite alternate}:where([data-fretfall]) .bars.moving i:nth-child(2){animation-duration:1.1s;animation-delay:-.5s}:where([data-fretfall]) .bars.moving i:nth-child(3){animation-duration:.7s;animation-delay:-.2s}:where([data-fretfall]) .bars.moving i:nth-child(4){animation-duration:1s;animation-delay:-.7s}@keyframes bars{0%{transform:scaleY(.2)}to{transform:scaleY(1)}}@media(prefers-reduced-motion:reduce){:where([data-fretfall]) .bars.moving i{animation:none;transform:scaleY(.6)}}:where([data-fretfall]) #intro{position:fixed;left:50%;top:36%;transform:translate(-50%,-50%);display:grid;justify-items:center;gap:6px;max-width:min(640px,90cqw);padding:22px 30px;border-radius:16px;background:color-mix(in srgb,var(--ink) 72%,transparent);border:1px solid var(--chip-border);text-align:center;pointer-events:none;opacity:0;visibility:hidden;transition:opacity .5s ease,visibility .5s}:where([data-fretfall]) #intro.show{opacity:1;visibility:visible}:where([data-fretfall]) #introTitle{font:700 clamp(22px,3cqw,38px) / 1.15 var(--num);color:var(--text)}:where([data-fretfall]) #introFacts{font-size:14px;color:var(--muted)}:where([data-fretfall]) #introState{display:flex;align-items:center;gap:10px;margin-top:10px;font:600 12px var(--num);letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}:where([data-fretfall]) .sheet{position:fixed;right:32px;top:66px;z-index:2;width:min(400px,calc(100cqw - 32px));max-height:calc(100cqh - 118px);display:flex;flex-direction:column;border-radius:14px;overflow:hidden;background:color-mix(in srgb,var(--ink) 94%,transparent);backdrop-filter:blur(18px);border:1px solid var(--chip-border);box-shadow:0 24px 60px #0000008c}:where([data-fretfall]) .sheet-head{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 10px 18px}:where([data-fretfall]) .sheet-head h2{margin:0;font:600 15px var(--ui)}:where([data-fretfall]) .close{width:30px;height:30px;display:grid;place-items:center;padding:0;border:0;border-radius:8px;background:none;color:var(--muted);cursor:pointer}:where([data-fretfall]) .close:hover{background:var(--chip);color:var(--text)}:where([data-fretfall]) .tabs{display:grid;grid-template-columns:repeat(5,1fr);gap:2px;margin:0 14px;padding:3px;border-radius:9px;background:var(--chip);border:1px solid var(--chip-border)}:where([data-fretfall]) .tabs button{padding:6px 0;border:0;border-radius:6px;background:none;font:500 13px var(--ui);color:var(--muted);cursor:pointer}:where([data-fretfall]) .tabs button:hover{color:var(--text)}:where([data-fretfall]) .tabs button[aria-selected=true]{background:var(--text);color:var(--ink);font-weight:600}:where([data-fretfall]) .pane{display:grid;align-content:start;gap:18px;padding:18px 18px 20px;overflow:hidden auto}:where([data-fretfall]) .pane h3{margin:0 0 -6px;font:600 11px var(--num);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}:where([data-fretfall]) .pane h3~h3{padding-top:16px;border-top:1px solid var(--chip-border)}:where([data-fretfall]) .setting{display:grid;gap:8px}:where([data-fretfall]) .pair{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:18px 20px}:where([data-fretfall]) .setting-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;font-size:13px;font-weight:500}:where([data-fretfall]) .setting-head output{font:600 12px var(--num);color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}:where([data-fretfall]) .setting .seg{overflow:visible}:where([data-fretfall]) .setting .seg button{flex:1}:where([data-fretfall]) .scale{display:flex;justify-content:space-between;margin-top:-4px;font-size:11px;color:var(--muted)}:where([data-fretfall]) .hint{margin:-2px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}:where([data-fretfall]) .text-button{justify-self:start;padding:4px 0;border:0;background:none;font:500 12px var(--ui);color:var(--muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}:where([data-fretfall]) .text-button:hover{color:var(--text)}:where([data-fretfall]) :is(#settings,.volume) input[type=range]{-webkit-appearance:none;appearance:none;height:18px;margin:0;background:none;cursor:pointer}:where([data-fretfall]) #settings input[type=range]{width:100%}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(90deg,var(--accent) var(--fill, 50%),var(--chip-border) var(--fill, 50%))}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;margin-top:-6px;border-radius:50%;background:var(--text);border:3px solid var(--accent);box-shadow:0 1px 4px #0006}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-moz-range-track{height:4px;border-radius:2px;background:var(--chip-border)}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-moz-range-progress{height:4px;border-radius:2px;background:var(--accent)}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-moz-range-thumb{width:10px;height:10px;border-radius:50%;background:var(--text);border:3px solid var(--accent)}:where([data-fretfall]) .toggle{display:flex;align-items:center;justify-content:space-between;gap:16px;font-size:13px;font-weight:500;cursor:pointer}:where([data-fretfall]) .toggle small{display:block;margin-top:2px;font-size:12px;font-weight:400;line-height:1.4;color:var(--muted)}:where([data-fretfall]) .toggle input{-webkit-appearance:none;appearance:none;flex:none;position:relative;width:36px;height:20px;margin:0;border-radius:10px;background:var(--chip-border);cursor:pointer;transition:background .15s}:where([data-fretfall]) .toggle input:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--text);transition:transform .15s}:where([data-fretfall]) .toggle input:checked{background:var(--accent)}:where([data-fretfall]) .toggle input:checked:after{transform:translate(16px);background:var(--ink)}:where([data-fretfall]) .cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}:where([data-fretfall]) .cards.three{grid-template-columns:repeat(3,minmax(0,1fr))}:where([data-fretfall]) .cards button{display:grid;gap:8px;justify-items:start;padding:10px;border-radius:9px;border:1px solid var(--chip-border);background:var(--chip);font:500 12px var(--ui);color:var(--muted);text-align:left;cursor:pointer}:where([data-fretfall]) .cards button:hover{color:var(--text)}:where([data-fretfall]) .cards button[aria-pressed=true]{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);color:var(--text)}:where([data-fretfall]) .dots{display:flex;gap:4px}:where([data-fretfall]) .dots i{width:10px;height:10px;border-radius:50%;box-shadow:inset 0 0 0 1px #ffffff2e}:where([data-fretfall]) .headstock{width:100%;height:52px}:where([data-fretfall]) .order{font:600 12px var(--num);letter-spacing:.12em;color:var(--text)}:where([data-fretfall]) #legend{width:min(430px,calc(100cqw - 32px))}:where([data-fretfall]) .legend-find{padding:0 14px 6px}:where([data-fretfall]) .legend-find input{width:100%;height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--chip-border);background:var(--chip);color:var(--text);font:13px var(--ui)}:where([data-fretfall]) .legend-find input::placeholder{color:var(--muted)}:where([data-fretfall]) .legend{gap:4px;padding-top:10px}:where([data-fretfall]) .legend h3{margin:14px 0 4px}:where([data-fretfall]) .legend h3:first-child{margin-top:0}:where([data-fretfall]) .legend-item{display:grid;grid-template-columns:64px 1fr;gap:12px;align-items:center;padding:4px 0}:where([data-fretfall]) .legend-item b{display:block;font-size:13px;font-weight:500}:where([data-fretfall]) .legend-item span{display:block;font-size:12px;line-height:1.4;color:var(--muted)}:where([data-fretfall]) .legend-item .keys{display:flex;justify-content:center;gap:4px}:where([data-fretfall]) .legend-item kbd{min-width:22px;padding:2px 6px;border:1px solid var(--chip-border);border-bottom-width:2px;border-radius:5px;background:var(--chip);font:600 12px var(--num);text-align:center;white-space:nowrap}:where([data-fretfall]) .legend-item svg{width:64px;height:36px;border-radius:8px;background:var(--chip);border:1px solid var(--chip-border);fill:none;stroke-linecap:round;stroke-linejoin:round}:where([data-fretfall]) .legend-item text{font-family:var(--num);font-weight:700;text-anchor:middle;dominant-baseline:central}:where([data-fretfall]) .legend-empty{margin:8px 0;font-size:13px;color:var(--muted)}:where([data-fretfall]) .f0{fill:var(--s0)}:where([data-fretfall]) .f1{fill:var(--s1)}:where([data-fretfall]) .f2{fill:var(--s2)}:where([data-fretfall]) .f3{fill:var(--s3)}:where([data-fretfall]) .f4{fill:var(--s4)}:where([data-fretfall]) .l0{stroke:var(--s0)}:where([data-fretfall]) .l1{stroke:var(--s1)}:where([data-fretfall]) .l2{stroke:var(--s2)}:where([data-fretfall]) .l3{stroke:var(--s3)}:where([data-fretfall]) .l4{stroke:var(--s4)}:where([data-fretfall]) .lm{stroke:var(--muted)}:where([data-fretfall]) .li{stroke:var(--ink)}:where([data-fretfall]) .ft{fill:var(--text)}:where([data-fretfall]) .lt{stroke:var(--text)}:where([data-fretfall]) .fi{fill:var(--ink)}:where([data-fretfall]) .fa{fill:var(--accent)}:where([data-fretfall]) .fl{fill:var(--lane)}:where([data-fretfall]) .ll{stroke:var(--lane)}:where([data-fretfall]) .lw{stroke:#fff}:where([data-fretfall]) .fm{fill:var(--muted)}:where([data-fretfall]) .la{stroke:var(--accent)}:where([data-fretfall]) .fw{fill:#fff}:where([data-fretfall]) .volume{position:relative}:where([data-fretfall]) .volume .icon.muted{color:var(--muted)}:where([data-fretfall]) .volume-panel{position:absolute;top:calc(100% + 8px);left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;padding:6px 14px 6px 6px;border-radius:10px;background:var(--ink);border:1px solid var(--chip-border);box-shadow:0 12px 30px #00000073}:where([data-fretfall]) .volume-panel input{width:150px}:where([data-fretfall]) .volume-panel output{min-width:36px;font:600 12px var(--num);color:var(--muted);text-align:right;font-variant-numeric:tabular-nums}:where([data-fretfall]) .volume-mute{flex:none;width:30px;height:30px;display:grid;place-items:center;padding:0;border:0;border-radius:7px;background:none;color:var(--text);cursor:pointer}:where([data-fretfall]) .volume-mute:hover{background:var(--chip)}:where([data-fretfall]) .volume-mute[aria-pressed=true]{color:var(--muted)}:where([data-fretfall]) #drop{position:fixed;inset:12px;z-index:5;display:grid;place-items:center;border:2px dashed var(--accent);border-radius:16px;background:#00000073;font:600 20px var(--num)}:where([data-fretfall]) #tab{position:fixed;left:-10000px;top:0;width:1000px}@media(max-width:900px){:where([data-fretfall]) .time{display:none}[data-fretfall]:where([data-fretfall-dock]) .time{display:block}:where([data-fretfall]) #menuButton{display:grid}:where([data-fretfall]) .volume{position:static}:where([data-fretfall]) .volume-panel{left:auto;right:0;transform:none}:where([data-fretfall]) .menu{display:none;position:absolute;top:calc(100% + 8px);right:0;width:230px;flex-direction:column;gap:2px;padding:6px;border-radius:12px;background:var(--ink);border:1px solid var(--chip-border);box-shadow:0 12px 30px #00000073}:where([data-fretfall]) #menuButton[aria-expanded=true]+.menu{display:flex}:where([data-fretfall]) .menu .icon{width:100%;height:38px;display:flex;justify-content:flex-start;gap:12px;padding:0 10px;border:0;border-radius:7px;background:none;font:500 13px var(--ui)}:where([data-fretfall]) .menu .icon:after{content:attr(data-label)}:where([data-fretfall]) .menu .icon:hover{background:var(--chip)}:where([data-fretfall]) .menu .icon[aria-pressed=true],:where([data-fretfall]) .menu .icon[aria-expanded=true]{background:none;color:var(--accent)}:where([data-fretfall]) .menu .tip{display:none}:where([data-fretfall]) .menu .divider{width:auto;height:1px;margin:4px}}@media(max-width:560px){:where([data-fretfall]) .bar{flex-wrap:wrap;height:auto;row-gap:8px}:where([data-fretfall]) .bar>.group:first-child,:where([data-fretfall]) .bar>.group:last-child{flex:1 1 100%;height:40px}:where([data-fretfall]) .speed{margin-left:auto}:where([data-fretfall]) #menuButton{position:absolute;top:2px;right:0}:where([data-fretfall]) .menu{top:48px}:where([data-fretfall]) #phrases{top:122px}:where([data-fretfall]) #info{flex-direction:column;align-items:flex-start;gap:2px;font-size:12px}:where([data-fretfall]) #info>span+span:before{display:none}:where([data-fretfall]) #info>span:first-child{max-width:100%;overflow:hidden;text-overflow:ellipsis}:where([data-fretfall]) #progress{top:182px}:where([data-fretfall]) #lyrics{top:212px}:where([data-fretfall]) .sheet{top:114px;max-height:calc(100cqh - 166px)}}@media(max-width:520px){:where([data-fretfall]) .sheet{right:16px}}[data-fretfall]:not([data-fretfall-dock]){contain:layout;container-type:size}'}),n=Object.assign(document.createElement("link"),{id:"fonts",rel:"stylesheet"});if(!e.isConnected)throw new Error("mount(element): the element has to be in the page");e.innerHTML=`<div data-fretfall><canvas id="highway"></canvas>
|
|
1
|
+
let l=null;const d=e=>l??=i(e);async function i(e){const a=Object.assign(document.createElement("style"),{textContent:'[data-fretfall]:not([data-fretfall-dock]),:where([data-fretfall-dock]){--bg: #0e1014;--ink: #0e1014;--text: #e8eaef;--muted: #7b8190;--accent: #c8f04a;--chip: #171a20;--chip-border: #2a2f38;--done: #e8eaef;--todo: #23272f;--ui: system-ui, sans-serif;--num: system-ui, sans-serif;--lyric: system-ui, sans-serif;--lyric-style: normal}:where([data-fretfall]) *{box-sizing:border-box}:where([data-fretfall]) [hidden]{display:none!important}[data-fretfall]:not([data-fretfall-dock]){height:100%}[data-fretfall]:not([data-fretfall-dock]){margin:0;overflow:hidden;background:var(--bg);color:var(--text);font:14px/1.4 var(--ui);accent-color:var(--accent)}:where([data-fretfall]) canvas{position:fixed;inset:0;width:100%;height:100%;display:block}:where([data-fretfall]) button{font:inherit;color:inherit}:where([data-fretfall]) .bar{position:fixed;z-index:3;left:32px;right:32px;top:18px;height:40px;display:flex;align-items:center;justify-content:space-between;gap:24px;transition:transform .25s ease,opacity .25s ease,visibility .25s}:where([data-fretfall]) .group{display:flex;align-items:center;gap:10px;min-width:0}:where([data-fretfall]) .group:last-child{flex:none}:where([data-fretfall]) .wordmark{display:flex;align-items:center;gap:7px;font:700 15px var(--num);letter-spacing:.22em}:where([data-fretfall]) :is(.wordmark,.welcome-mark) .fall{transform-box:fill-box;transform-origin:center;transform:rotate(14deg);animation:fall .75s .8s both}@keyframes fall{0%{transform:translate(-3.5px,-1.42px) rotate(0);animation-timing-function:cubic-bezier(.55,0,.85,.35)}40%{transform:translate(0) rotate(18deg);animation-timing-function:cubic-bezier(.2,.7,.4,1)}56%{transform:translateY(-.35px) rotate(11.5deg);animation-timing-function:ease-in-out}74%{transform:translateY(.08px) rotate(15.2deg);animation-timing-function:ease-in-out}88%{transform:translate(0) rotate(13.6deg);animation-timing-function:ease-in-out}to{transform:translate(0) rotate(14deg)}}@media(prefers-reduced-motion:reduce){:where([data-fretfall]) .wordmark .fall{animation:none}}:where([data-fretfall]) .seg{display:flex;gap:2px;padding:3px;border-radius:9px;background:var(--chip);border:1px solid var(--chip-border);overflow-x:auto;scrollbar-width:none}:where([data-fretfall]) .seg button{border:0;background:none;cursor:pointer;padding:5px 12px;border-radius:6px;font:500 13px var(--ui);color:var(--muted);white-space:nowrap}:where([data-fretfall]) .seg button[aria-pressed=true]{background:var(--text);color:var(--ink);font-weight:600}:where([data-fretfall]) .seg select{max-width:22cqw;border:0;padding:4px 6px;background:none;color:var(--text);font:600 13px var(--ui)}:where([data-fretfall]) .seg option{background:var(--ink);color:var(--text)}:where([data-fretfall]) .icon{flex:none;cursor:pointer;width:36px;height:36px;display:grid;place-items:center;padding:0;border-radius:8px;background:var(--chip);border:1px solid var(--chip-border);color:var(--text)}:where([data-fretfall]) .icon[aria-pressed=true],:where([data-fretfall]) .icon[aria-expanded=true]{background:var(--accent);border-color:var(--accent);color:var(--ink)}:where([data-fretfall]) button:focus-visible,:where([data-fretfall]) input:focus-visible{outline:2px solid var(--accent);outline-offset:2px}:where([data-fretfall]) .speed{height:36px;display:flex;align-items:center;padding:0 2px;border-radius:8px;background:var(--chip);border:1px solid var(--chip-border);color:var(--muted)}:where([data-fretfall]) .speed button{cursor:pointer;width:28px;height:32px;display:grid;place-items:center;padding:0;border:0;background:none;color:inherit}:where([data-fretfall]) .speed #speed{width:auto;min-width:46px;font:600 14px var(--num);color:var(--text)}:where([data-fretfall]) .time{margin-right:6px;font:14px var(--num);color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}:where([data-fretfall]) .divider{width:1px;height:24px;margin:0 4px;background:var(--chip-border)}:where([data-fretfall]) .menu{display:contents}:where([data-fretfall]) #menuButton{display:none}:where([data-fretfall]) #phrases{position:fixed;left:32px;right:32px;top:74px;height:54px;cursor:pointer;touch-action:none;-webkit-user-select:none;user-select:none}:where([data-fretfall]) #phrases div{position:absolute;bottom:0;min-width:2px;border-radius:2px;background:var(--todo)}:where([data-fretfall]) #phrases div.done{background:var(--done)}:where([data-fretfall]) #phraseTime{position:absolute;top:calc(100% + 16px);transform:translate(-50%);padding:2px 7px;border-radius:6px;background:var(--ink);border:1px solid var(--chip-border);font:600 11px var(--num);font-variant-numeric:tabular-nums;color:var(--text);pointer-events:none}:where([data-fretfall]) #loopBox{position:absolute;top:-6px;bottom:-17px;border:1.5px solid var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);box-shadow:0 0 18px color-mix(in srgb,var(--accent) 22%,transparent)}:where([data-fretfall]) #loopBox:before,:where([data-fretfall]) #loopBox:after{content:"";position:absolute;top:-11px;bottom:-11px;width:4px;border:4px solid transparent;border-radius:6px;background:var(--accent) padding-box;cursor:ew-resize}:where([data-fretfall]) #loopBox:before{left:-6.75px}:where([data-fretfall]) #loopBox:after{right:-6.75px}:where([data-fretfall]) #progress{position:fixed;left:32px;right:32px;top:134px;height:5px;border-radius:3px;overflow:hidden;background:var(--todo)}:where([data-fretfall]) #progress div{width:0;height:100%;background:var(--accent);opacity:.9}[data-fretfall][data-docked] #phrases{top:18px}[data-fretfall][data-docked] #progress{top:78px}[data-fretfall][data-docked] #lyrics{top:108px}[data-fretfall][data-docked] .sheet{top:18px}:where([data-fretfall]) #lyrics{position:fixed;left:40px;top:164px;max-width:min(560px,46cqw);display:flex;flex-direction:column;gap:8px;pointer-events:none;font-family:var(--lyric);font-style:var(--lyric-style);text-shadow:0 2px 14px var(--ink),0 0 4px var(--ink)}:where([data-fretfall]) #section{min-height:16px;font:600 12px var(--num);letter-spacing:.18em;color:var(--accent)}:where([data-fretfall]) #lines{position:relative;height:2.45em;font-size:clamp(20px,2.3cqw,32px);line-height:1.15}:where([data-fretfall]) #lines div{position:absolute;top:0;left:0;white-space:nowrap;color:var(--muted);transition:transform .45s cubic-bezier(.22,1,.36,1),opacity .35s ease}:where([data-fretfall]) #lines .low{transform:translateY(1.3em);opacity:.5}:where([data-fretfall]) #lines .gone{opacity:0;transition-duration:.45s,.25s}:where([data-fretfall]) #lines .gone.up{transform:translateY(-.8em)}:where([data-fretfall]) #lines span{transition:color .15s}:where([data-fretfall]) #lines .sung{color:var(--text)}@media(prefers-reduced-motion:reduce){:where([data-fretfall]) #lines div{transition-property:opacity}}:where([data-fretfall]) #info{position:fixed;left:40px;right:226px;bottom:14px;display:flex;align-items:center;font-size:13px;white-space:nowrap;color:var(--muted);pointer-events:none}:where([data-fretfall]) #info b{color:var(--text);font-weight:600}:where([data-fretfall]) #info>span+span:before{content:"";display:inline-block;width:1px;height:12px;margin:0 14px;vertical-align:-1px;background:var(--chip-border)}:where([data-fretfall]) #info .tuning{position:relative;pointer-events:auto;cursor:help}:where([data-fretfall]) #info .tuning>b{text-decoration:underline dotted var(--muted);text-underline-offset:3px}:where([data-fretfall]) #info .tip{left:0;right:auto;white-space:normal}:where([data-fretfall]) #info .tuning:is(:hover,:focus)>.tip{opacity:1;visibility:visible;transform:none}:where([data-fretfall]) .pegs{display:flex;align-items:flex-start;gap:4px;margin:10px 0 8px}:where([data-fretfall]) .peg{display:flex;flex-direction:column;align-items:center;min-width:26px;gap:2px;font:600 13px var(--num)}:where([data-fretfall]) .peg i{font-style:normal;font-size:11px;color:var(--muted)}:where([data-fretfall]) .peg .move:before{content:"";display:block;width:3px;height:calc(6px + var(--d) * 3px);margin:2px auto 3px;border-radius:2px;background:var(--c)}:where([data-fretfall]) .peg strong{color:var(--c)}:where([data-fretfall]) .peg.same{opacity:.45}:where([data-fretfall]) .tip small{display:block;font-size:11px}[data-fretfall]:fullscreen .bar{transform:translateY(calc(-100% - 18px));opacity:0;visibility:hidden;transition-delay:.4s}[data-fretfall]:fullscreen:has(#phrases:hover,#progress:hover,.bar:hover) .bar{transform:none;opacity:1;visibility:visible;transition-delay:0s}:where([data-fretfall]) .seg.views{margin-left:4px}:where([data-fretfall]) .seg.views button{padding:5px 11px;font-size:12px}:where([data-fretfall]) .icon:disabled{cursor:default;color:var(--muted)}:where([data-fretfall]) .icon:disabled svg{opacity:.5}:where([data-fretfall]) #loopTools{position:fixed;z-index:4;display:flex;transform:translate(-50%,calc(-50% + 3px))}:where([data-fretfall]) #loopTools .icon{width:32px;height:26px;background:var(--ink);border-color:var(--accent)}:where([data-fretfall]) #loopTools svg{width:15px;height:15px}:where([data-fretfall]) #trainer{border-radius:13px 0 0 13px}:where([data-fretfall]) #clearLoop{border-left:0;border-radius:0 13px 13px 0;color:var(--muted)}:where([data-fretfall]) #clearLoop:hover{color:var(--text)}:where([data-fretfall]) #loopTools .icon[aria-pressed=true]{background:var(--accent);color:var(--ink)}:where([data-fretfall]) .tip{position:absolute;right:0;bottom:calc(100% + 10px);width:max-content;max-width:250px;padding:8px 10px;border-radius:8px;background:var(--ink);border:1px solid var(--chip-border);box-shadow:0 12px 30px #00000073;color:var(--muted);font:12px/1.45 var(--ui);text-align:left;pointer-events:none;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .12s ease,transform .12s ease,visibility .12s}:where([data-fretfall]) .tip b{display:flex;justify-content:space-between;gap:12px;margin-bottom:2px;color:var(--text);font-weight:600}:where([data-fretfall]) .tip kbd{padding:0 5px;border:1px solid var(--chip-border);border-radius:4px;color:var(--muted);font:inherit}:where([data-fretfall]) :is(.icon,.speed):hover>.tip,:where([data-fretfall]) .icon:focus-visible>.tip,:where([data-fretfall]) .speed:focus-within>.tip{opacity:1;visibility:visible;transform:none}[data-fretfall]:where([data-fretfall-dock]){display:flex;align-items:center;gap:10px}:where([data-fretfall]) .bar :is(.icon,.speed),[data-fretfall]:where([data-fretfall-dock]) :is(.icon,.speed){position:relative}:where([data-fretfall]) .bar .tip,[data-fretfall]:where([data-fretfall-dock]) .tip{top:calc(100% + 10px);bottom:auto;transform:translateY(-4px)}:where([data-fretfall]) .bar [aria-expanded=true]>.tip,[data-fretfall]:where([data-fretfall-dock]) [aria-expanded=true]>.tip{display:none}:where([data-fretfall]) #loopTools .tip{top:calc(100% + 10px);bottom:auto;left:var(--tip, 50%);right:auto;transform:translate(calc(-1 * var(--tip, 50%)),-4px)}:where([data-fretfall]) #loopTools .icon:hover>.tip,:where([data-fretfall]) #loopTools .icon:focus-visible>.tip{transform:translate(calc(-1 * var(--tip, 50%)))}[data-fretfall]:fullscreen #info{display:none}[data-fretfall].minimal :is(.bar>:not(#minimalBack),#phrases,#progress,#loopTools,#info){display:none}[data-fretfall].minimal .bar{background:none;border:0;box-shadow:none;pointer-events:none}[data-fretfall].minimal #minimalBack{display:inline-flex;pointer-events:auto;margin-left:auto}:where([data-fretfall]) #minimalBack{display:none}[data-fretfall].tab2d .only-3d,[data-fretfall]:not(.tab2d) .only-2d{display:none}[data-fretfall].tab2d .only-3d+.only-3d+h3{padding-top:0;border-top:0}[data-fretfall].notation .not-notation,[data-fretfall]:not(.notation) .only-notation{display:none}[data-fretfall].minimal #lyrics{top:24px}:where([data-fretfall]) #status{position:fixed;left:50%;top:42%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:12px;max-width:min(560px,90cqw);padding:10px 16px;border-radius:10px;background:var(--chip);border:1px solid var(--chip-border);backdrop-filter:blur(10px);text-align:center}[data-fretfall].banding :is(#highway,#phrases,#progress,#loopTools,#lyrics,#info,#intro,#time){display:none}:where([data-fretfall]) #bandNote{position:fixed;left:50%;top:56%;transform:translate(-50%,-50%);display:grid;justify-items:center;gap:8px;max-width:min(440px,90cqw);padding:14px 20px;border-radius:10px;background:var(--chip);border:1px solid var(--chip-border);text-align:center}:where([data-fretfall]) #bandNote .text-button{justify-self:center}:where([data-fretfall]) #status:not(.loading) .bars{display:none}:where([data-fretfall]) .bars{flex:none;display:inline-flex;align-items:flex-end;gap:3px;height:16px}:where([data-fretfall]) .bars i{width:3px;height:100%;border-radius:2px;background:var(--accent);transform:scaleY(.3);transform-origin:bottom}:where([data-fretfall]) .bars.moving i{animation:bars .8s ease-in-out infinite alternate}:where([data-fretfall]) .bars.moving i:nth-child(2){animation-duration:1.1s;animation-delay:-.5s}:where([data-fretfall]) .bars.moving i:nth-child(3){animation-duration:.7s;animation-delay:-.2s}:where([data-fretfall]) .bars.moving i:nth-child(4){animation-duration:1s;animation-delay:-.7s}@keyframes bars{0%{transform:scaleY(.2)}to{transform:scaleY(1)}}@media(prefers-reduced-motion:reduce){:where([data-fretfall]) .bars.moving i{animation:none;transform:scaleY(.6)}}:where([data-fretfall]) #intro{position:fixed;left:50%;top:36%;transform:translate(-50%,-50%);display:grid;justify-items:center;gap:6px;max-width:min(640px,90cqw);padding:22px 30px;border-radius:16px;background:color-mix(in srgb,var(--ink) 72%,transparent);border:1px solid var(--chip-border);text-align:center;pointer-events:none;opacity:0;visibility:hidden;transition:opacity .5s ease,visibility .5s}:where([data-fretfall]) #intro.show{opacity:1;visibility:visible}:where([data-fretfall]) #introTitle{font:700 clamp(22px,3cqw,38px) / 1.15 var(--num);color:var(--text)}:where([data-fretfall]) #introFacts{font-size:14px;color:var(--muted)}:where([data-fretfall]) #introState{display:flex;align-items:center;gap:10px;margin-top:10px;font:600 12px var(--num);letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}:where([data-fretfall]) .sheet{position:fixed;right:32px;top:66px;z-index:2;width:min(400px,calc(100cqw - 32px));max-height:calc(100cqh - 118px);display:flex;flex-direction:column;border-radius:14px;overflow:hidden;background:color-mix(in srgb,var(--ink) 94%,transparent);backdrop-filter:blur(18px);border:1px solid var(--chip-border);box-shadow:0 24px 60px #0000008c}:where([data-fretfall]) .sheet-head{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 10px 18px}:where([data-fretfall]) .sheet-head h2{margin:0;font:600 15px var(--ui)}:where([data-fretfall]) .close{width:30px;height:30px;display:grid;place-items:center;padding:0;border:0;border-radius:8px;background:none;color:var(--muted);cursor:pointer}:where([data-fretfall]) .close:hover{background:var(--chip);color:var(--text)}:where([data-fretfall]) .tabs{display:grid;grid-template-columns:repeat(5,1fr);gap:2px;margin:0 14px;padding:3px;border-radius:9px;background:var(--chip);border:1px solid var(--chip-border)}:where([data-fretfall]) .tabs button{padding:6px 0;border:0;border-radius:6px;background:none;font:500 13px var(--ui);color:var(--muted);cursor:pointer}:where([data-fretfall]) .tabs button:hover{color:var(--text)}:where([data-fretfall]) .tabs button[aria-selected=true]{background:var(--text);color:var(--ink);font-weight:600}:where([data-fretfall]) .pane{display:grid;align-content:start;gap:18px;padding:18px 18px 20px;overflow:hidden auto}:where([data-fretfall]) .pane h3{margin:0 0 -6px;font:600 11px var(--num);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}:where([data-fretfall]) .pane h3~h3{padding-top:16px;border-top:1px solid var(--chip-border)}:where([data-fretfall]) .setting{display:grid;gap:8px}:where([data-fretfall]) .pair{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:18px 20px}:where([data-fretfall]) .setting-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;font-size:13px;font-weight:500}:where([data-fretfall]) .setting-head output{font:600 12px var(--num);color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}:where([data-fretfall]) .setting .seg{overflow:visible}:where([data-fretfall]) .setting .seg button{flex:1}:where([data-fretfall]) .scale{display:flex;justify-content:space-between;margin-top:-4px;font-size:11px;color:var(--muted)}:where([data-fretfall]) .hint{margin:-2px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}:where([data-fretfall]) .text-button{justify-self:start;padding:4px 0;border:0;background:none;font:500 12px var(--ui);color:var(--muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}:where([data-fretfall]) .text-button:hover{color:var(--text)}:where([data-fretfall]) :is(#settings,.volume) input[type=range]{-webkit-appearance:none;appearance:none;height:18px;margin:0;background:none;cursor:pointer}:where([data-fretfall]) #settings input[type=range]{width:100%}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(90deg,var(--accent) var(--fill, 50%),var(--chip-border) var(--fill, 50%))}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;margin-top:-6px;border-radius:50%;background:var(--text);border:3px solid var(--accent);box-shadow:0 1px 4px #0006}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-moz-range-track{height:4px;border-radius:2px;background:var(--chip-border)}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-moz-range-progress{height:4px;border-radius:2px;background:var(--accent)}:where([data-fretfall]) :is(#settings,.volume) input[type=range]::-moz-range-thumb{width:10px;height:10px;border-radius:50%;background:var(--text);border:3px solid var(--accent)}:where([data-fretfall]) .toggle{display:flex;align-items:center;justify-content:space-between;gap:16px;font-size:13px;font-weight:500;cursor:pointer}:where([data-fretfall]) .toggle small{display:block;margin-top:2px;font-size:12px;font-weight:400;line-height:1.4;color:var(--muted)}:where([data-fretfall]) .toggle input{-webkit-appearance:none;appearance:none;flex:none;position:relative;width:36px;height:20px;margin:0;border-radius:10px;background:var(--chip-border);cursor:pointer;transition:background .15s}:where([data-fretfall]) .toggle input:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--text);transition:transform .15s}:where([data-fretfall]) .toggle input:checked{background:var(--accent)}:where([data-fretfall]) .toggle input:checked:after{transform:translate(16px);background:var(--ink)}:where([data-fretfall]) .cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}:where([data-fretfall]) .cards.three{grid-template-columns:repeat(3,minmax(0,1fr))}:where([data-fretfall]) .cards button{display:grid;gap:8px;justify-items:start;padding:10px;border-radius:9px;border:1px solid var(--chip-border);background:var(--chip);font:500 12px var(--ui);color:var(--muted);text-align:left;cursor:pointer}:where([data-fretfall]) .cards button:hover{color:var(--text)}:where([data-fretfall]) .cards button[aria-pressed=true]{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);color:var(--text)}:where([data-fretfall]) .dots{display:flex;gap:4px}:where([data-fretfall]) .dots i{width:10px;height:10px;border-radius:50%;box-shadow:inset 0 0 0 1px #ffffff2e}:where([data-fretfall]) .headstock{width:100%;height:52px}:where([data-fretfall]) .order{font:600 12px var(--num);letter-spacing:.12em;color:var(--text)}:where([data-fretfall]) #legend{width:min(430px,calc(100cqw - 32px))}:where([data-fretfall]) .legend-find{padding:0 14px 6px}:where([data-fretfall]) .legend-find input{width:100%;height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--chip-border);background:var(--chip);color:var(--text);font:13px var(--ui)}:where([data-fretfall]) .legend-find input::placeholder{color:var(--muted)}:where([data-fretfall]) .legend{gap:4px;padding-top:10px}:where([data-fretfall]) .legend h3{margin:14px 0 4px}:where([data-fretfall]) .legend h3:first-child{margin-top:0}:where([data-fretfall]) .legend-item{display:grid;grid-template-columns:64px 1fr;gap:12px;align-items:center;padding:4px 0}:where([data-fretfall]) .legend-item b{display:block;font-size:13px;font-weight:500}:where([data-fretfall]) .legend-item span{display:block;font-size:12px;line-height:1.4;color:var(--muted)}:where([data-fretfall]) .legend-item .keys{display:flex;justify-content:center;gap:4px}:where([data-fretfall]) .legend-item kbd{min-width:22px;padding:2px 6px;border:1px solid var(--chip-border);border-bottom-width:2px;border-radius:5px;background:var(--chip);font:600 12px var(--num);text-align:center;white-space:nowrap}:where([data-fretfall]) .legend-item svg{width:64px;height:36px;border-radius:8px;background:var(--chip);border:1px solid var(--chip-border);fill:none;stroke-linecap:round;stroke-linejoin:round}:where([data-fretfall]) .legend-item text{font-family:var(--num);font-weight:700;text-anchor:middle;dominant-baseline:central}:where([data-fretfall]) .legend-empty{margin:8px 0;font-size:13px;color:var(--muted)}:where([data-fretfall]) .f0{fill:var(--s0)}:where([data-fretfall]) .f1{fill:var(--s1)}:where([data-fretfall]) .f2{fill:var(--s2)}:where([data-fretfall]) .f3{fill:var(--s3)}:where([data-fretfall]) .f4{fill:var(--s4)}:where([data-fretfall]) .l0{stroke:var(--s0)}:where([data-fretfall]) .l1{stroke:var(--s1)}:where([data-fretfall]) .l2{stroke:var(--s2)}:where([data-fretfall]) .l3{stroke:var(--s3)}:where([data-fretfall]) .l4{stroke:var(--s4)}:where([data-fretfall]) .lm{stroke:var(--muted)}:where([data-fretfall]) .li{stroke:var(--ink)}:where([data-fretfall]) .ft{fill:var(--text)}:where([data-fretfall]) .lt{stroke:var(--text)}:where([data-fretfall]) .fi{fill:var(--ink)}:where([data-fretfall]) .fa{fill:var(--accent)}:where([data-fretfall]) .fl{fill:var(--lane)}:where([data-fretfall]) .ll{stroke:var(--lane)}:where([data-fretfall]) .lw{stroke:#fff}:where([data-fretfall]) .fm{fill:var(--muted)}:where([data-fretfall]) .la{stroke:var(--accent)}:where([data-fretfall]) .fw{fill:#fff}:where([data-fretfall]) .volume{position:relative}:where([data-fretfall]) .volume .icon.muted{color:var(--muted)}:where([data-fretfall]) .volume-panel{position:absolute;top:calc(100% + 8px);left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;padding:6px 14px 6px 6px;border-radius:10px;background:var(--ink);border:1px solid var(--chip-border);box-shadow:0 12px 30px #00000073}:where([data-fretfall]) .volume-panel input{width:150px}:where([data-fretfall]) .volume-panel output{min-width:36px;font:600 12px var(--num);color:var(--muted);text-align:right;font-variant-numeric:tabular-nums}:where([data-fretfall]) .volume-mute{flex:none;width:30px;height:30px;display:grid;place-items:center;padding:0;border:0;border-radius:7px;background:none;color:var(--text);cursor:pointer}:where([data-fretfall]) .volume-mute:hover{background:var(--chip)}:where([data-fretfall]) .volume-mute[aria-pressed=true]{color:var(--muted)}:where([data-fretfall]) #drop{position:fixed;inset:12px;z-index:5;display:grid;place-items:center;border:2px dashed var(--accent);border-radius:16px;background:#00000073;font:600 20px var(--num)}:where([data-fretfall]) #tab{position:fixed;left:-10000px;top:0;width:1000px}@media(max-width:900px){:where([data-fretfall]) .time{display:none}[data-fretfall]:where([data-fretfall-dock]) .time{display:block}:where([data-fretfall]) #menuButton{display:grid}:where([data-fretfall]) .volume{position:static}:where([data-fretfall]) .volume-panel{left:auto;right:0;transform:none}:where([data-fretfall]) .menu{display:none;position:absolute;top:calc(100% + 8px);right:0;width:230px;flex-direction:column;gap:2px;padding:6px;border-radius:12px;background:var(--ink);border:1px solid var(--chip-border);box-shadow:0 12px 30px #00000073}:where([data-fretfall]) #menuButton[aria-expanded=true]+.menu{display:flex}:where([data-fretfall]) .menu .icon{width:100%;height:38px;display:flex;justify-content:flex-start;gap:12px;padding:0 10px;border:0;border-radius:7px;background:none;font:500 13px var(--ui)}:where([data-fretfall]) .menu .icon:after{content:attr(data-label)}:where([data-fretfall]) .menu .icon:hover{background:var(--chip)}:where([data-fretfall]) .menu .icon[aria-pressed=true],:where([data-fretfall]) .menu .icon[aria-expanded=true]{background:none;color:var(--accent)}:where([data-fretfall]) .menu .tip{display:none}:where([data-fretfall]) .menu .divider{width:auto;height:1px;margin:4px}}@media(max-width:560px){:where([data-fretfall]) .bar{flex-wrap:wrap;height:auto;row-gap:8px}:where([data-fretfall]) .bar>.group:first-child,:where([data-fretfall]) .bar>.group:last-child{flex:1 1 100%;height:40px}:where([data-fretfall]) .speed{margin-left:auto}:where([data-fretfall]) #menuButton{position:absolute;top:2px;right:0}:where([data-fretfall]) .menu{top:48px}:where([data-fretfall]) #phrases{top:122px}:where([data-fretfall]) #info{flex-direction:column;align-items:flex-start;gap:2px;font-size:12px}:where([data-fretfall]) #info>span+span:before{display:none}:where([data-fretfall]) #info>span:first-child{max-width:100%;overflow:hidden;text-overflow:ellipsis}:where([data-fretfall]) #progress{top:182px}:where([data-fretfall]) #lyrics{top:212px}:where([data-fretfall]) .sheet{top:114px;max-height:calc(100cqh - 166px)}}@media(max-width:520px){:where([data-fretfall]) .sheet{right:16px}}[data-fretfall]:not([data-fretfall-dock]){contain:layout;container-type:size}'}),n=Object.assign(document.createElement("link"),{id:"fonts",rel:"stylesheet"});if(!e.isConnected)throw new Error("mount(element): the element has to be in the page");e.innerHTML=`<div data-fretfall><canvas id="highway"></canvas>
|
|
2
2
|
<header class="bar">
|
|
3
3
|
<div class="group" style="gap: 20px">
|
|
4
4
|
<div class="wordmark">
|
|
@@ -28,6 +28,16 @@ id="arrangements"
|
|
|
28
28
|
role="group"
|
|
29
29
|
aria-label="Arrangement"
|
|
30
30
|
></div>
|
|
31
|
+
<div
|
|
32
|
+
class="seg views"
|
|
33
|
+
id="view"
|
|
34
|
+
role="group"
|
|
35
|
+
aria-label="View"
|
|
36
|
+
>
|
|
37
|
+
<button value="highway" aria-pressed="true">Highway</button>
|
|
38
|
+
<button value="tablature" aria-pressed="false">Tablature</button>
|
|
39
|
+
<button value="notation" aria-pressed="false">Notation</button>
|
|
40
|
+
</div>
|
|
31
41
|
</div>
|
|
32
42
|
<div class="group">
|
|
33
43
|
<span class="time" id="time">0:00 / 0:00</span>
|
|
@@ -110,6 +120,14 @@ aria-label="Volume"
|
|
|
110
120
|
</div>
|
|
111
121
|
<button
|
|
112
122
|
class="icon"
|
|
123
|
+
id="minimalBack"
|
|
124
|
+
aria-label="Back from the minimal view"
|
|
125
|
+
title="Back from the minimal view (H)"
|
|
126
|
+
>
|
|
127
|
+
<svg width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M3 10s2.5-4.5 7-4.5 7 4.5 7 4.5-2.5 4.5-7 4.5-7-4.5-7-4.5z"/><circle cx="10" cy="10" r="2"/></svg>
|
|
128
|
+
</button>
|
|
129
|
+
<button
|
|
130
|
+
class="icon"
|
|
113
131
|
id="menuButton"
|
|
114
132
|
aria-expanded="false"
|
|
115
133
|
aria-controls="menu"
|
|
@@ -196,6 +214,93 @@ can also drop them anywhere</span
|
|
|
196
214
|
<div class="divider"></div>
|
|
197
215
|
<button
|
|
198
216
|
class="icon"
|
|
217
|
+
id="metronome"
|
|
218
|
+
data-label="Metronome"
|
|
219
|
+
aria-pressed="false"
|
|
220
|
+
aria-label="Metronome"
|
|
221
|
+
aria-describedby="metronomeTip"
|
|
222
|
+
>
|
|
223
|
+
<svg
|
|
224
|
+
width="18"
|
|
225
|
+
height="18"
|
|
226
|
+
viewBox="0 0 20 20"
|
|
227
|
+
fill="none"
|
|
228
|
+
stroke="currentColor"
|
|
229
|
+
stroke-width="1.6"
|
|
230
|
+
stroke-linecap="round"
|
|
231
|
+
stroke-linejoin="round"
|
|
232
|
+
>
|
|
233
|
+
<path d="M7.8 3h4.4l3.3 13.5h-11z" />
|
|
234
|
+
<path d="M5.6 12.5h8.8M10 12.5l4-7" />
|
|
235
|
+
</svg>
|
|
236
|
+
<span class="tip" role="tooltip" id="metronomeTip"
|
|
237
|
+
><b>Metronome <kbd>K</kbd></b
|
|
238
|
+
>A click on every beat, higher on the first of each
|
|
239
|
+
bar</span
|
|
240
|
+
>
|
|
241
|
+
</button>
|
|
242
|
+
<button
|
|
243
|
+
class="icon"
|
|
244
|
+
id="band"
|
|
245
|
+
data-label="Play as a band"
|
|
246
|
+
aria-label="Play as a band"
|
|
247
|
+
aria-describedby="bandTip"
|
|
248
|
+
disabled
|
|
249
|
+
>
|
|
250
|
+
<svg
|
|
251
|
+
width="18"
|
|
252
|
+
height="18"
|
|
253
|
+
viewBox="0 0 20 20"
|
|
254
|
+
fill="none"
|
|
255
|
+
stroke="currentColor"
|
|
256
|
+
stroke-width="1.6"
|
|
257
|
+
stroke-linecap="round"
|
|
258
|
+
stroke-linejoin="round"
|
|
259
|
+
>
|
|
260
|
+
<circle cx="7.5" cy="7" r="2.5" />
|
|
261
|
+
<path d="M3 16.5a4.5 4.5 0 0 1 9 0" />
|
|
262
|
+
<circle cx="13.8" cy="7.5" r="2" />
|
|
263
|
+
<path d="M13.5 12.2a3.8 3.8 0 0 1 4 4.3" />
|
|
264
|
+
</svg>
|
|
265
|
+
<span class="tip" role="tooltip" id="bandTip"
|
|
266
|
+
><b>Play as a band</b>Opens every part in a window of its
|
|
267
|
+
own, side by side, all in time. Play, pause, jump and loop
|
|
268
|
+
from any of them; the sound comes from this window, which
|
|
269
|
+
stays open behind them</span
|
|
270
|
+
>
|
|
271
|
+
</button>
|
|
272
|
+
<button
|
|
273
|
+
class="icon"
|
|
274
|
+
id="minimal"
|
|
275
|
+
data-label="Minimal view"
|
|
276
|
+
aria-pressed="false"
|
|
277
|
+
aria-label="Minimal view"
|
|
278
|
+
aria-describedby="minimalTip"
|
|
279
|
+
>
|
|
280
|
+
<svg
|
|
281
|
+
width="18"
|
|
282
|
+
height="18"
|
|
283
|
+
viewBox="0 0 20 20"
|
|
284
|
+
fill="none"
|
|
285
|
+
stroke="currentColor"
|
|
286
|
+
stroke-width="1.6"
|
|
287
|
+
stroke-linecap="round"
|
|
288
|
+
stroke-linejoin="round"
|
|
289
|
+
>
|
|
290
|
+
<path
|
|
291
|
+
d="M2.5 10s2.8-5 7.5-5 7.5 5 7.5 5-2.8 5-7.5 5-7.5-5-7.5-5z"
|
|
292
|
+
/>
|
|
293
|
+
<circle cx="10" cy="10" r="2.2" />
|
|
294
|
+
</svg>
|
|
295
|
+
<span class="tip" role="tooltip" id="minimalTip"
|
|
296
|
+
><b>Minimal view <kbd>H</kbd></b
|
|
297
|
+
>Just the highway and the lyrics: the header, phrase bars
|
|
298
|
+
and song info make way. Press again to bring them back</span
|
|
299
|
+
>
|
|
300
|
+
</button>
|
|
301
|
+
<div class="divider"></div>
|
|
302
|
+
<button
|
|
303
|
+
class="icon"
|
|
199
304
|
id="legendButton"
|
|
200
305
|
data-label="Notation and shortcuts"
|
|
201
306
|
aria-expanded="false"
|
|
@@ -332,117 +437,6 @@ stroke-linecap="round"
|
|
|
332
437
|
<div id="lines"></div>
|
|
333
438
|
</div>
|
|
334
439
|
<div id="info"></div>
|
|
335
|
-
<div id="tools" class="group" role="group" aria-label="Practice tools">
|
|
336
|
-
<button
|
|
337
|
-
class="icon"
|
|
338
|
-
id="metronome"
|
|
339
|
-
aria-pressed="false"
|
|
340
|
-
aria-label="Metronome"
|
|
341
|
-
aria-describedby="metronomeTip"
|
|
342
|
-
>
|
|
343
|
-
<svg
|
|
344
|
-
width="18"
|
|
345
|
-
height="18"
|
|
346
|
-
viewBox="0 0 20 20"
|
|
347
|
-
fill="none"
|
|
348
|
-
stroke="currentColor"
|
|
349
|
-
stroke-width="1.6"
|
|
350
|
-
stroke-linecap="round"
|
|
351
|
-
stroke-linejoin="round"
|
|
352
|
-
>
|
|
353
|
-
<path d="M7.8 3h4.4l3.3 13.5h-11z" />
|
|
354
|
-
<path d="M5.6 12.5h8.8M10 12.5l4-7" />
|
|
355
|
-
</svg>
|
|
356
|
-
<span class="tip" role="tooltip" id="metronomeTip"
|
|
357
|
-
><b>Metronome <kbd>K</kbd></b
|
|
358
|
-
>A click on every beat, higher on the first of each
|
|
359
|
-
bar</span
|
|
360
|
-
>
|
|
361
|
-
</button>
|
|
362
|
-
<button
|
|
363
|
-
class="icon"
|
|
364
|
-
id="band"
|
|
365
|
-
aria-label="Play as a band"
|
|
366
|
-
aria-describedby="bandTip"
|
|
367
|
-
disabled
|
|
368
|
-
>
|
|
369
|
-
<svg
|
|
370
|
-
width="18"
|
|
371
|
-
height="18"
|
|
372
|
-
viewBox="0 0 20 20"
|
|
373
|
-
fill="none"
|
|
374
|
-
stroke="currentColor"
|
|
375
|
-
stroke-width="1.6"
|
|
376
|
-
stroke-linecap="round"
|
|
377
|
-
stroke-linejoin="round"
|
|
378
|
-
>
|
|
379
|
-
<circle cx="7.5" cy="7" r="2.5" />
|
|
380
|
-
<path d="M3 16.5a4.5 4.5 0 0 1 9 0" />
|
|
381
|
-
<circle cx="13.8" cy="7.5" r="2" />
|
|
382
|
-
<path d="M13.5 12.2a3.8 3.8 0 0 1 4 4.3" />
|
|
383
|
-
</svg>
|
|
384
|
-
<span class="tip" role="tooltip" id="bandTip"
|
|
385
|
-
><b>Play as a band</b>Opens every part in a window of its
|
|
386
|
-
own, side by side, all in time. Play, pause, jump and loop
|
|
387
|
-
from any of them; the sound comes from this window, which
|
|
388
|
-
stays open behind them</span
|
|
389
|
-
>
|
|
390
|
-
</button>
|
|
391
|
-
<button
|
|
392
|
-
class="icon"
|
|
393
|
-
id="tabView"
|
|
394
|
-
aria-pressed="false"
|
|
395
|
-
aria-label="2D tab view"
|
|
396
|
-
aria-describedby="tabViewTip"
|
|
397
|
-
>
|
|
398
|
-
<svg
|
|
399
|
-
width="18"
|
|
400
|
-
height="18"
|
|
401
|
-
viewBox="0 0 20 20"
|
|
402
|
-
fill="none"
|
|
403
|
-
stroke="currentColor"
|
|
404
|
-
stroke-width="1.6"
|
|
405
|
-
stroke-linecap="round"
|
|
406
|
-
>
|
|
407
|
-
<path d="M2.5 5h15M2.5 10h15M2.5 15h15" />
|
|
408
|
-
<path d="M7 3v14" stroke-width="2.2" />
|
|
409
|
-
</svg>
|
|
410
|
-
<span class="tip" role="tooltip" id="tabViewTip"
|
|
411
|
-
><b>2D tab view <kbd>D</kbd></b
|
|
412
|
-
>The notes as tab: fret numbers on flat strings, coming in
|
|
413
|
-
from the right to the play line. Press again for the 3D
|
|
414
|
-
highway</span
|
|
415
|
-
>
|
|
416
|
-
</button>
|
|
417
|
-
<button
|
|
418
|
-
class="icon"
|
|
419
|
-
id="minimal"
|
|
420
|
-
aria-pressed="false"
|
|
421
|
-
aria-label="Minimal view"
|
|
422
|
-
aria-describedby="minimalTip"
|
|
423
|
-
>
|
|
424
|
-
<svg
|
|
425
|
-
width="18"
|
|
426
|
-
height="18"
|
|
427
|
-
viewBox="0 0 20 20"
|
|
428
|
-
fill="none"
|
|
429
|
-
stroke="currentColor"
|
|
430
|
-
stroke-width="1.6"
|
|
431
|
-
stroke-linecap="round"
|
|
432
|
-
stroke-linejoin="round"
|
|
433
|
-
>
|
|
434
|
-
<path
|
|
435
|
-
d="M2.5 10s2.8-5 7.5-5 7.5 5 7.5 5-2.8 5-7.5 5-7.5-5-7.5-5z"
|
|
436
|
-
/>
|
|
437
|
-
<circle cx="10" cy="10" r="2.2" />
|
|
438
|
-
</svg>
|
|
439
|
-
<span class="tip" role="tooltip" id="minimalTip"
|
|
440
|
-
><b>Minimal view <kbd>H</kbd></b
|
|
441
|
-
>Just the highway and the lyrics: the header, phrase bars
|
|
442
|
-
and song info make way. Press again to bring them back</span
|
|
443
|
-
>
|
|
444
|
-
</button>
|
|
445
|
-
</div>
|
|
446
440
|
<div
|
|
447
441
|
id="settings"
|
|
448
442
|
class="sheet"
|
|
@@ -602,8 +596,8 @@ step="0.05"
|
|
|
602
596
|
</div>
|
|
603
597
|
</div>
|
|
604
598
|
</div>
|
|
605
|
-
<h3>Notes</h3>
|
|
606
|
-
<div class="pair">
|
|
599
|
+
<h3 class="not-notation">Notes</h3>
|
|
600
|
+
<div class="pair not-notation">
|
|
607
601
|
<div class="setting">
|
|
608
602
|
<div class="setting-head">
|
|
609
603
|
<label for="noteSpeed">Note speed</label
|
|
@@ -655,11 +649,11 @@ aria-labelledby="tab-highway"
|
|
|
655
649
|
hidden
|
|
656
650
|
>
|
|
657
651
|
<div
|
|
658
|
-
class="setting only-2d"
|
|
652
|
+
class="setting only-2d not-notation"
|
|
659
653
|
title="Notes scrolling in to the play line, or a page of bars that holds still while the play line moves across it"
|
|
660
654
|
>
|
|
661
655
|
<div class="setting-head">
|
|
662
|
-
<span id="tabLayoutLabel">
|
|
656
|
+
<span id="tabLayoutLabel">Tablature</span>
|
|
663
657
|
</div>
|
|
664
658
|
<div
|
|
665
659
|
class="seg"
|
|
@@ -668,7 +662,63 @@ role="group"
|
|
|
668
662
|
aria-labelledby="tabLayoutLabel"
|
|
669
663
|
></div>
|
|
670
664
|
</div>
|
|
671
|
-
<div
|
|
665
|
+
<div
|
|
666
|
+
class="setting only-notation"
|
|
667
|
+
title="The page the notation is written on: the theme's dark card, or white paper"
|
|
668
|
+
>
|
|
669
|
+
<div class="setting-head">
|
|
670
|
+
<span id="paperLabel">Paper</span>
|
|
671
|
+
</div>
|
|
672
|
+
<div
|
|
673
|
+
class="seg"
|
|
674
|
+
data-setting="paper"
|
|
675
|
+
role="group"
|
|
676
|
+
aria-labelledby="paperLabel"
|
|
677
|
+
></div>
|
|
678
|
+
</div>
|
|
679
|
+
<label class="toggle only-notation"
|
|
680
|
+
><span
|
|
681
|
+
>Beat highlight<small
|
|
682
|
+
>The beat being played, filled across the system</small
|
|
683
|
+
></span
|
|
684
|
+
><input id="beatBox" type="checkbox" role="switch"
|
|
685
|
+
/></label>
|
|
686
|
+
<label class="toggle only-notation"
|
|
687
|
+
><span
|
|
688
|
+
>Notes<small
|
|
689
|
+
>The notes on a staff over each system, as guitar music is written</small
|
|
690
|
+
></span
|
|
691
|
+
><input id="sheetNotes" type="checkbox" role="switch"
|
|
692
|
+
/></label>
|
|
693
|
+
<div
|
|
694
|
+
class="setting only-notation"
|
|
695
|
+
title="Whether the page turns with the beat, keeping the system being played second from the top, or only when you scroll it"
|
|
696
|
+
>
|
|
697
|
+
<div class="setting-head">
|
|
698
|
+
<span id="sheetScrollLabel">Scroll</span>
|
|
699
|
+
</div>
|
|
700
|
+
<div
|
|
701
|
+
class="seg"
|
|
702
|
+
data-setting="sheetScroll"
|
|
703
|
+
role="group"
|
|
704
|
+
aria-labelledby="sheetScrollLabel"
|
|
705
|
+
></div>
|
|
706
|
+
</div>
|
|
707
|
+
<div
|
|
708
|
+
class="setting only-2d"
|
|
709
|
+
title="What is written around a note: the finger to press with, and the techniques, chord names and hand positions over and under the staff"
|
|
710
|
+
>
|
|
711
|
+
<div class="setting-head">
|
|
712
|
+
<span id="tabMarksLabel">Marks</span>
|
|
713
|
+
</div>
|
|
714
|
+
<div
|
|
715
|
+
class="seg"
|
|
716
|
+
data-setting="tabMarks"
|
|
717
|
+
role="group"
|
|
718
|
+
aria-labelledby="tabMarksLabel"
|
|
719
|
+
></div>
|
|
720
|
+
</div>
|
|
721
|
+
<div class="setting not-notation">
|
|
672
722
|
<div class="setting-head">
|
|
673
723
|
<span id="lookLabel">Notes</span>
|
|
674
724
|
</div>
|
|
@@ -747,8 +797,8 @@ step="0.05"
|
|
|
747
797
|
</div>
|
|
748
798
|
</div>
|
|
749
799
|
<div
|
|
750
|
-
class="setting"
|
|
751
|
-
title="The
|
|
800
|
+
class="setting not-notation"
|
|
801
|
+
title="The finger numbers on a note, and the fret numbers in the tab. The mutes' crosses are white either way"
|
|
752
802
|
>
|
|
753
803
|
<div class="setting-head">
|
|
754
804
|
<span id="markingsLabel">Markings on notes</span>
|
|
@@ -760,7 +810,7 @@ role="group"
|
|
|
760
810
|
aria-labelledby="markingsLabel"
|
|
761
811
|
></div>
|
|
762
812
|
</div>
|
|
763
|
-
<label class="toggle"
|
|
813
|
+
<label class="toggle not-notation"
|
|
764
814
|
><span
|
|
765
815
|
>Hand position guides<small
|
|
766
816
|
>Where your hand goes: a band down the highway, or
|
package/music.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const S=960;function b(i,o){const e=[{tick:0,tempo:o,ms:0}];for(const{tick:n,tempo:r}of i){const t=e.at(-1);e.push({tick:n,tempo:r,ms:t.ms+(n-t.tick)*6e4/(t.tempo*960)})}return e}function p(i,o,e){let n=0,r=i.length;for(;n<r;){const t=n+r>>1;i[t][o]<=e?n=t+1:r=t}return i[Math.max(0,n-1)]}function k(i,o){const e=p(i,"tick",o);return e.ms+(o-e.tick)*6e4/(e.tempo*960)}function E(i,o){const e=p(i,"ms",o);return e.tick+(o-e.ms)*e.tempo*960/6e4}const h=["C","D♭","D","E♭","E","F","G♭","G","A♭","A","B♭","B"],g={4:[28,33,38,43],5:[23,28,33,38,43],6:[40,45,50,55,59,64],7:[35,40,45,50,55,59,64]};function T(i){const o=g[i.length],e=o&&i.map((n,r)=>n-o[r]);return e?.every(n=>n===e[0])?`${h[i[0]%12]} Standard`:e&&e[0]===e[1]-2&&e.slice(1).every(n=>n===e[1])?`Drop ${h[i[0]%12]}`:i.map(n=>h[n%12]).join(" ")}const M=i=>h[i%12];function A(i){const o=g[i.length];if(!o)return null;const e=i.map((t,s)=>t-o[s]),r=e[0]===e[1]-2&&e.slice(1).every(t=>t===e[1])&&e[1]!==0?o.map((t,s)=>s?t:t-2):o;return{reference:T(r),open:r,shift:i.map((t,s)=>t-r[s])}}const R=new Set(["time","sustain","chord","repeat","heldFrom","tieTo","dynamicLabel","pick"]),y=i=>JSON.stringify(Object.entries(i).filter(([o,e])=>!R.has(o)&&e!==null&&e!==void 0&&e!==!1&&e!==0).sort());function C(i,o,e=1){let n=null;for(let r=0,t;r<i.length;r=t){for(t=r+1;t<i.length&&i[t].time-i[r].time<.005;t++);const s=i.slice(r,t),a=s.map(y).sort().join("|"),c=s[0].chord??null,u=!!n&&s[0].time-n.time<=e,d=c!==null&&u&&n.shape===a;for(const f of s){f.repeat=d;const m=u&&!f.mute&&n.group.some(l=>l.string===f.string&&l.fret===f.fret&&!l.mute&&!l.bend&&!l.bendCurve&&(l.slideTo??l.slideUnpitchTo??null)===null);f.heldFrom=m?n.time:null}d&&(o[c].highDensity=!0),n={shape:a,time:s[0].time,group:s}}}function U(i,o){const e={},n={};let r="f";i.forEach((t,s)=>{const a=e[t.string];if(a!==void 0){const c=i[a];c.letRing&&(c.sustain=Math.max(c.sustain,Math.min(t.time-c.time,4)));const u=m=>m.bendCurve?.at(-1)?.[1]??m.bend??0,d=m=>m.bendCurve?.[0]?.[1]??0;d(t)>0&&c.fret===t.fret&&u(c)===d(t)&&(c.sustain=Math.max(c.sustain,t.time-c.time)),c.linkNext&&(c.tieTo=s,t.tied=!0,(c.slideTo??c.slideUnpitchTo??null)!==null&&(c.slideSpan=t.time-c.time),c.sustain=Math.max(c.sustain,t.time-c.time));const f=m=>(m.slideTo??m.slideUnpitchTo??null)===null&&!m.bend&&!m.bendCurve&&!m.hammerOn&&!m.pullOff;!t.tied&&c.tied&&t.chord===null&&f(t)&&t.fret===n[t.string]&&t.time-(c.time+c.sustain)<.1&&(c.slideTo=t.fret,c.slideSpan=t.time-c.time,t.tied=!0)}t.dynamicLabel=t.dynamic&&t.dynamic!==r?t.dynamic:null,t.dynamic&&(r=t.dynamic),t.tied||(n[t.string]=t.fret),e[t.string]=s});for(const t of Object.values(e).map(s=>i[s]))t.letRing&&(t.sustain=Math.max(t.sustain,2));for(const t of o)t.barre??=x(t)}function _(i,o){for(const e of o){if(e.endTime-e.startTime<.6)continue;const n=i.findIndex(t=>t.time>=e.startTime-.005),r=[];for(let t=n;t>=0&&t<i.length&&i[t].time<e.endTime-.005;t++)i[t].chord===null&&e.frets[i[t].string]===i[t].fret&&r.push(t);if(!(new Set(r.map(t=>i[t].string)).size<2)){e.arpeggio=!0;for(const t of r){const s=i[t],a=i.find((c,u)=>u>t&&c.string===s.string&&c.time>s.time+.005);s.sustain=Math.max(s.sustain,Math.min(e.endTime,a?.time??1/0)-s.time),s.letRing=!0}}}}function x({frets:i=[],fingers:o=[]}){const e={};i.forEach((t,s)=>{t>0&&o[s]>=1&&(e[`${o[s]}:${t}`]??=[]).push(s)});const[n,r]=Object.entries(e).sort((t,s)=>s[1].length-t[1].length)[0]??[];return r?.length>=3?{fret:+n.split(":")[1],from:Math.min(...r),to:Math.max(...r)}:null}function D(i,o){const e=r=>r<i.length&&i[r].time-o<8;let n=i.findIndex(r=>o<r.end+.2);return n<0&&(n=i.length),e(n)||(n=n>0&&o<i[n-1].end+1.5?n-1:-1),{top:n,bottom:n>=0&&e(n+1)?n+1:-1}}export{U as annotate,D as lyricsShown,_ as markArpeggios,C as markRepeats,E as msToTick,M as noteName,b as tempoMap,k as tickToMs,T as tuningName,A as tuningReference};
|
package/package.json
CHANGED