wiki-plugin-file 0.1.0
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/LICENSE +9 -0
- package/README.md +30 -0
- package/client/file.js +85 -0
- package/client/file.js.map +7 -0
- package/factory.json +1 -0
- package/package.json +23 -0
- package/pages/about-file-plugin +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 David Bovill
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# wiki-plugin-file
|
|
2
|
+
|
|
3
|
+
Read a file from a federated wiki page's assets folder, inside the page.
|
|
4
|
+
|
|
5
|
+
Farms serve assets with whatever Content-Type their mime table guesses, so browsers download `.toml`, `.py`, `.rs` and even `.md`. This plugin fetches the bytes with `fetch()` (which ignores Content-Type) and renders them itself: markdown through the wiki's own markdown plugin (wikilinks resolve), TOML as one table per section, JSON pretty-printed, code with line numbers, images inline. Every text file gets **Raw** (opens a `text/plain` blob in a new tab, which every browser displays), **Download**, **Copy** and the asset URL.
|
|
6
|
+
|
|
7
|
+
## Item text
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
FILE BUGS.toml a file in this page's own assets folder
|
|
11
|
+
FILE assets/other-slug/notes.md a file in another folder on this site
|
|
12
|
+
FILE https://host/assets/x/y.md any absolute asset URL
|
|
13
|
+
FOLDER [slug | https://host/assets/path] list a folder; click a name to read it
|
|
14
|
+
LINES 60 collapse threshold (default 40)
|
|
15
|
+
SHOW start expanded
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
An empty item lists the page's own folder.
|
|
19
|
+
|
|
20
|
+
## Provenance and drift
|
|
21
|
+
|
|
22
|
+
If the folder carries a `SOURCES.toml` manifest (written by `asset-snapshot.py`), the viewer shows each file's role, source path, repo, commit and snapshot date, and hashes the fetched bytes: a green badge means the file still matches the manifest, red means it was edited in place or the manifest is stale.
|
|
23
|
+
|
|
24
|
+
## Build
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
npm install
|
|
28
|
+
npm run build # esbuild → client/file.js
|
|
29
|
+
npm test
|
|
30
|
+
```
|
package/client/file.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
(()=>{var I=e=>{let r={files:[],folders:[],lines:40,show:!1},t=String(e||"").split(/\r?\n/);for(let i of t){let n=i.trim();if(!n)continue;let o=n.match(/^([A-Z]+):?(?:\s+(.*))?$/);if(!o)continue;let[,s,l=""]=o;switch(s){case"FILE":l&&r.files.push(l.trim());break;case"FOLDER":r.folders.push(l.trim());break;case"LINES":{let a=parseInt(l,10);a>0&&(r.lines=a);break}case"SHOW":r.show=!0;break;default:break}}return!r.files.length&&!r.folders.length&&r.folders.push(""),r};var F=e=>/^https?:\/\//i.test(e),v=e=>e.replace(/\/+$/,""),z=e=>{let r=String(e).match(/^(https?:\/\/[^/]+)/i);return r?r[1]:""},M=(e,{base:r,slug:t})=>{let i;F(e)?i=e:e.startsWith("/assets/")?i=`${v(r)}${e.slice(7)}`:e.startsWith("assets/")?i=`${v(r)}/${e.slice(7)}`:i=`${v(r)}/${t}/${e}`;let n=i.lastIndexOf("/");return{url:i,folderUrl:i.slice(0,n),name:decodeURIComponent(i.slice(n+1))}},V=(e,{base:r,slug:t})=>{if(F(e)){let s=v(e),l=z(s),a=s.slice((l+"/assets/").length);return{folderUrl:s,path:a,listUrl:`${l}/plugin/assets/list?assets=${encodeURIComponent(a)}`}}let i=e?e.replace(/^\/?assets\//,"").replace(/^\/+/,""):t,n=`${v(r)}/${i}`,o=z(n);return{folderUrl:n,path:i,listUrl:`${o}/plugin/assets/list?assets=${encodeURIComponent(i)}`}};var se={md:"markdown",markdown:"markdown",toml:"toml",json:"json",png:"image",jpg:"image",jpeg:"image",gif:"image",svg:"image",webp:"image",pdf:"pdf"},U={py:"python",rs:"rust",sh:"bash",bash:"bash",zsh:"bash",js:"javascript",mjs:"javascript",ts:"typescript",coffee:"coffeescript",yaml:"yaml",yml:"yaml",toml:"ini",ini:"ini",cfg:"ini",json:"json",md:"markdown",html:"xml",css:"css",csv:"plaintext",txt:"plaintext",log:"plaintext"},T=e=>{let r=String(e).toLowerCase().match(/\.([a-z0-9]+)$/);return r?r[1]:""},Z=e=>se[T(e)]||"text",B=e=>{let r=Math.min(e.length,4096);if(r===0)return!1;let t=0;for(let i=0;i<r;i++){let n=e[i];if(n===0)return!0;(n<9||n>13&&n<32)&&t++}return t/r>.1};var le=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i,k=class e extends Date{#t=!1;#i=!1;#e=null;constructor(r){let t=!0,i=!0,n="Z";if(typeof r=="string"){let o=r.match(le);o?(o[1]||(t=!1,r=`0000-01-01T${r}`),i=!!o[2],i&&r[10]===" "&&(r=r.replace(" ","T")),o[2]&&+o[2]>23?r="":(n=o[3]||null,r=r.toUpperCase(),!n&&i&&(r+="Z"))):r=""}super(r),isNaN(this.getTime())||(this.#t=t,this.#i=i,this.#e=n)}isDateTime(){return this.#t&&this.#i}isLocal(){return!this.#t||!this.#i||!this.#e}isDate(){return this.#t&&!this.#i}isTime(){return this.#i&&!this.#t}isValid(){return this.#t||this.#i}toISOString(){let r=super.toISOString();if(this.isDate())return r.slice(0,10);if(this.isTime())return r.slice(11,23);if(this.#e===null)return r.slice(0,-1);if(this.#e==="Z")return r;let t=+this.#e.slice(1,3)*60+ +this.#e.slice(4,6);return t=this.#e[0]==="-"?t:-t,new Date(this.getTime()-t*6e4).toISOString().slice(0,-1)+this.#e}static wrapAsOffsetDateTime(r,t="Z"){let i=new e(r);return i.#e=t,i}static wrapAsLocalDateTime(r){let t=new e(r);return t.#e=null,t}static wrapAsLocalDate(r){let t=new e(r);return t.#i=!1,t.#e=null,t}static wrapAsLocalTime(r){let t=new e(r);return t.#t=!1,t.#e=null,t}};function ae(e,r){let t=e.slice(0,r).split(/\r\n|\n|\r/g);return[t.length,t.pop().length+1]}function fe(e,r,t){let i=e.split(/\r\n|\n|\r/g),n="",o=(Math.log10(r+1)|0)+1;for(let s=r-1;s<=r+1;s++){let l=i[s-1];l&&(n+=s.toString().padEnd(o," "),n+=": ",n+=l,n+=`
|
|
2
|
+
`,s===r&&(n+=" ".repeat(o+t+2),n+=`^
|
|
3
|
+
`))}return n}var f=class extends Error{line;column;codeblock;constructor(r,t){let[i,n]=ae(t.toml,t.ptr),o=fe(t.toml,i,n);super(`Invalid TOML document: ${r}
|
|
4
|
+
|
|
5
|
+
${o}`,t),this.line=i,this.column=n,this.codeblock=o}};function j(e,r=0){let t=e.indexOf(`
|
|
6
|
+
`,r);return e.charCodeAt(t-1)===13&&t--,t}function O(e){for(;e.p<e.s.length;e.p++){let r=e.s.charCodeAt(e.p);if(r===10)break;if(r===13&&e.s.charCodeAt(e.p+1)===10){e.p++;break}if(r<32&&r!==9||r===127)throw new f("control characters are not allowed in comments",{toml:e.s,ptr:e.p})}}function g(e,r,t){let i;for(;;){for(;(i=e.s.charCodeAt(e.p))===32||i===9||!r&&(i===10||i===13&&e.s.charCodeAt(e.p+1)===10);)e.p++;if(t||i!==35)break;O(e)}}function G(e,r,t){let i=e.p;if(!t){i=j(e.s,i),e.p=i<0?e.s.length:i;return}for(;e.p<e.s.length;e.p++){let n=e.s.charCodeAt(e.p);if(n===35)O(e);else if(n===t||n===r)return}throw new f("cannot find end of structure",{toml:e.s,ptr:i})}var pe=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,de=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,ce=/^[+-]?0[0-9_]/;function x(e){let r=e.p,t=e.s.charCodeAt(e.p++),i=t,n=t===39,o=t===e.s.charCodeAt(e.p)&&t===e.s.charCodeAt(e.p+1);o&&((t=e.s.charCodeAt(e.p+=2))===10?e.p++:t===13&&e.s.charCodeAt(e.p+1)===10&&(e.p+=2));let s="",l=e.p,a=0;for(;e.p<e.s.length;e.p++)if(t=e.s.charCodeAt(e.p),o&&(t===10||t===13&&e.s.charCodeAt(e.p+1)===10))a=a&&3;else{if(t<32&&t!==9||t===127)throw new f("control characters are not allowed in strings",{toml:e.s,ptr:e.p});if((!a||a===3)&&t===i&&(!o||e.s.charCodeAt(e.p+1)===i&&e.s.charCodeAt(e.p+2)===i))return o&&(e.s.charCodeAt(e.p+3)===i&&e.p++,e.s.charCodeAt(e.p+3)===i&&e.p++),a||(s+=e.s.slice(l,e.p)),e.p+=o?3:1,s;if(!a)!n&&t===92&&(s+=e.s.slice(l,l=e.p),a=1);else if(a===1)if(t===120||t===117||t===85){let p=0,u=t===120?2:t===117?4:8;for(let c=0;c<u;c++,e.p++){let m=e.s.charCodeAt(e.p+1),b=m>=48&&m<=57?m-48:m>=65&&m<=70?m-65+10:m>=97&&m<=102?m-97+10:-1;if(b<0)throw new f("invalid non-hex character in unicode escape",{toml:e.s,ptr:e.p+1});p=p<<4|b}if(p<0||p>1114111||p>=55296&&p<=57343)throw new f("invalid unicode escape",{toml:e.s,ptr:e.p});s+=String.fromCodePoint(p),l=e.p+1,a=0}else if(t===32||t===9)a=2;else{if(t===98)s+="\b";else if(t===116)s+=" ";else if(t===110)s+=`
|
|
7
|
+
`;else if(t===102)s+="\f";else if(t===114)s+="\r";else if(t===101)s+="\x1B";else if(t===34)s+='"';else if(t===92)s+="\\";else throw new f("unrecognized escape sequence",{toml:e.s,ptr:e.p});l=e.p+1,a=0}else if(t!==32&&t!==9){if(a===2)throw new f("invalid escape: only line-ending whitespace may be escaped",{toml:e.s,ptr:l});a=!n&&t===92?1:0,l=e.p}}throw new f("unfinished string",{toml:e.s,ptr:r})}function ue(e,r,t){let i=e.s.slice(r,t),n=i.indexOf("#");return n>0&&(O({s:i,p:n,d:0}),i=i.slice(0,n)),i.trimEnd()}function H(e,r,t){let i=e.p,n={toml:e.s,ptr:i};G(e,44,t);let o=ue(e,i,e.p);if(!o)throw new f("incomplete declaration: value expected",n);if(o==="-inf")return-1/0;if(o==="inf"||o==="+inf")return 1/0;if(o==="nan"||o==="+nan"||o==="-nan")return NaN;if(o==="-0")return r?0n:0;let s=pe.test(o);if(s||de.test(o)){if(ce.test(o))throw new f("leading zeroes are not allowed",n);o=o.replace(/_/g,"");let a=+o;if(isNaN(a))throw new f("invalid number",n);if(s){if((s=!Number.isSafeInteger(a))&&!r)throw new f("integer value cannot be represented losslessly",n);(s||r===!0)&&(a=BigInt(o))}return a}let l=new k(o);if(!l.isValid())throw new f("invalid value",n);return l}function A(e,r,t){let i=e.p,n=e.s.charCodeAt(i);if(n===91||n===123){if(!e.d--)throw new f("document contains excessively nested structures. aborting.",{toml:e.s,ptr:i});let o=n===91?J(e,t):K(e,t);return e.d++,o}if(n===34||n===39)return x(e);if(n===116){if(e.s.charCodeAt(++e.p)!==114||e.s.charCodeAt(++e.p)!==117||e.s.charCodeAt(++e.p)!==101)throw new f("invalid value",{toml:e.s,ptr:i});return e.p++,!0}if(n===102){if(e.s.charCodeAt(++e.p)!==97||e.s.charCodeAt(++e.p)!==108||e.s.charCodeAt(++e.p)!==115||e.s.charCodeAt(++e.p)!==101)throw new f("invalid value",{toml:e.s,ptr:i});return e.p++,!1}return H(e,t,r)}var me=/^[a-zA-Z0-9-_]+[ \t]*$/;function E(e,r="="){let t=e.p,i=t-1,n=[],o=e.s.indexOf(r,t);if(o<0)throw new f("incomplete key-value: cannot find end of key",{toml:e.s,ptr:t});do{let s=e.s.charCodeAt(e.p=++i);if(s!==32&&s!==9)if(s===34||s===39){if(s===e.s.charCodeAt(e.p+1)&&s===e.s.charCodeAt(e.p+2))throw new f("multiline strings are not allowed in keys",{toml:e.s,ptr:e.p});let l=x(e);i=e.s.indexOf(".",e.p);let a=e.s.slice(e.p,i<0||i>o?o:i),p=j(a);if(p>-1)throw new f("newlines are not allowed in keys",{toml:e.s,ptr:p});if(a.trimStart())throw new f("found extra tokens after the string part",{toml:e.s,ptr:e.p});if(o<e.p&&(o=e.s.indexOf(r,e.p),o<0))throw new f("incomplete key-value: cannot find end of key",{toml:e.s,ptr:t});n.push(l)}else{i=e.s.indexOf(".",e.p);let l=e.s.slice(e.p,i<0||i>o?o:i);if(!me.test(l))throw new f("only letter, numbers, dashes and underscores are allowed in keys",{toml:e.s,ptr:e.p});n.push(l.trimEnd())}}while(i+1&&i<o);return e.p=o+1,g(e,!0,!0),n}function K(e,r){let t={},i=new Set,n;for(e.p++;e.p<e.s.length;){if(g(e),(n=e.s.charCodeAt(e.p))===125)return e.p++,t;let o,s=t,l=!1,a=e.p,p=E(e);for(let c=0;c<p.length;c++){if(c&&(s=l?s[o]:s[o]={}),o=p[c],(l=Object.hasOwn(s,o))&&(typeof s[o]!="object"||i.has(s[o])))throw new f("trying to redefine an already defined value",{toml:e.s,ptr:a});!l&&o==="__proto__"&&Object.defineProperty(s,o,{enumerable:!0,configurable:!0,writable:!0})}if(l)throw new f("trying to redefine an already defined value",{toml:e.s,ptr:e.p});let u=A(e,125,r);if(i.add(s[o]=u),g(e),(n=e.s.charCodeAt(e.p++))===125)return t;if(n!==44)throw new f("expected comma or end of structure",{toml:e.s,ptr:e.p-1})}throw new f("unfinished table encountered",{toml:e.s,ptr:e.p})}function J(e,r){let t=[],i;for(e.p++;e.p<e.s.length;){if(g(e),(i=e.s.charCodeAt(e.p))===93)return e.p++,t;if(t.push(A(e,93,r)),g(e),(i=e.s.charCodeAt(e.p++))===93)return t;if(i!==44)throw new f("expected comma or end of structure",{toml:e.s,ptr:e.p-1})}throw new f("unfinished array encountered",{toml:e.s,ptr:e.p})}function W(e,r,t,i){let n=r,o=t,s,l=!1,a;for(let p=0;p<e.length;p++){if(p){if(n=l?n[s]:n[s]={},o=(a=o[s]).c,i===0&&(a.t===1||a.t===2))return null;if(a.t===2){let u=n.length-1;n=n[u],o=o[u].c}}if(s=e[p],(l=Object.hasOwn(n,s))&&o[s]?.t===0&&o[s]?.d)return null;l||(s==="__proto__"&&(Object.defineProperty(n,s,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(o,s,{enumerable:!0,configurable:!0,writable:!0})),o[s]={t:p<e.length-1&&i===2?3:i,d:!1,i:0,c:{}})}if(a=o[s],a.t!==i&&!(i===1&&a.t===3)||(i===2&&(a.d||(a.d=!0,n[s]=[]),n[s].push(n={}),a.c[a.i++]=a={t:1,d:!1,i:0,c:{}}),a.d))return null;if(a.d=!0,i===1)n=l?n[s]:n[s]={};else if(i===0&&l)return null;return[s,n,a.c]}function C(e,{maxDepth:r=1e3,integersAsBigInt:t}={}){let i={s:e,p:0,d:r},n={},o={},s,l=n,a=o;for(g(i);i.p<e.length;){if(e.charCodeAt(i.p)===91){let p=e.charCodeAt(++i.p)===91;s=i.p+=+p;let u=E(i,"]");if(p){if(e.charCodeAt(i.p-1)!==93)throw new f("expected end of table declaration",{toml:e,ptr:i.p-1});i.p++}let c=W(u,n,o,p?2:1);if(!c)throw new f("trying to redefine an already defined table or value",{toml:e,ptr:s});a=c[2],l=c[1]}else{s=i.p;let p=E(i),u=W(p,l,a,0);if(!u)throw new f("trying to redefine an already defined table or value",{toml:e,ptr:s});u[1][u[0]]=A(i,void 0,t)}if(g(i,!0),i.p<e.length&&(s=e.charCodeAt(i.p))!==10&&s!==13)throw new f("each key-value declaration must be followed by an end-of-line",{toml:e,ptr:i.p});g(i)}return n}var S=e=>e&&typeof e=="object"&&!Array.isArray(e)&&!(e instanceof Date),q=e=>typeof e=="string"?e.includes(`
|
|
8
|
+
`)?"multiline":"string":Array.isArray(e)?"array":e instanceof Date?"date":typeof e,N=e=>typeof e=="string"?e:e instanceof Date?e.toISOString():Array.isArray(e)?e.map(r=>S(r)?JSON.stringify(r):N(r)).join(", "):String(e),D=(e,r,t,i)=>{for(let[n,o]of Object.entries(e)){let s=r?`${r}.${n}`:n;S(o)?D(o,s,t,i):Array.isArray(o)&&o.length&&o.every(S)?o.forEach((l,a)=>{let p=[];D(l,"",p,i),i.push({name:`${s}[${a}]`,rows:p})}):t.push([s,N(o),q(o)])}},he=e=>{let r=[],t=[];for(let[i,n]of Object.entries(e))if(S(n)){let o=[],s=[];D(n,"",o,s),r.push({name:i,rows:o});for(let l of s)r.push({...l,name:`${i}.${l.name}`})}else Array.isArray(n)&&n.length&&n.every(S)?n.forEach((o,s)=>{let l=[];D(o,"",l,[]),r.push({name:`${i}[${s}]`,rows:l})}):t.push([i,N(n),q(n)]);return t.length&&r.unshift({name:"",rows:t}),r},X=e=>he(C(e));var d=e=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""),ge=`
|
|
9
|
+
.file-item { font-size: 13px; }
|
|
10
|
+
.file-item .file-list { margin: 0 0 6px 0; padding: 0; list-style: none; }
|
|
11
|
+
.file-item .file-list li { padding: 2px 0; }
|
|
12
|
+
.file-item .file-list a { cursor: pointer; }
|
|
13
|
+
.file-item .file-role { color: #777; }
|
|
14
|
+
.file-item .file-view { border: 1px solid #ddd; border-radius: 4px; margin: 6px 0; background: #fafafa; }
|
|
15
|
+
.file-item .file-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; padding: 4px 8px; border-bottom: 1px solid #e5e5e5; color: #555; }
|
|
16
|
+
.file-item .file-toolbar .file-name { font-weight: bold; color: #222; }
|
|
17
|
+
.file-item .file-toolbar button, .file-item .file-toolbar a.btn { font-size: 11px; padding: 1px 6px; border: 1px solid #bbb; border-radius: 3px; background: #fff; color: #333; text-decoration: none; cursor: pointer; }
|
|
18
|
+
.file-item .file-prov { font-size: 11px; color: #777; padding: 2px 8px 4px; border-bottom: 1px solid #eee; }
|
|
19
|
+
.file-item .file-badge { font-size: 11px; padding: 0 5px; border-radius: 8px; }
|
|
20
|
+
.file-item .file-badge.ok { background: #e3f5e3; color: #1e6b1e; }
|
|
21
|
+
.file-item .file-badge.drift { background: #fde8e8; color: #9b1c1c; }
|
|
22
|
+
.file-item .file-body { padding: 6px 8px; overflow-x: auto; }
|
|
23
|
+
.file-item .file-code { display: flex; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.45; }
|
|
24
|
+
.file-item .file-code pre { margin: 0; white-space: pre; }
|
|
25
|
+
.file-item .file-code .file-lines { color: #aaa; text-align: right; padding-right: 10px; user-select: none; }
|
|
26
|
+
.file-item .file-more { margin: 4px 0 0; }
|
|
27
|
+
.file-item table.file-toml { border-collapse: collapse; margin: 4px 0 10px; width: 100%; }
|
|
28
|
+
.file-item table.file-toml th, .file-item table.file-toml td { border: 1px solid #ddd; padding: 3px 6px; vertical-align: top; text-align: left; }
|
|
29
|
+
.file-item table.file-toml th { background: #f0f0f0; }
|
|
30
|
+
.file-item table.file-toml td.key { font-family: ui-monospace, Menlo, monospace; white-space: nowrap; color: #444; }
|
|
31
|
+
.file-item table.file-toml pre { margin: 0; white-space: pre-wrap; font-size: 12px; }
|
|
32
|
+
.file-item .file-section { font-weight: bold; margin: 8px 0 2px; font-family: ui-monospace, Menlo, monospace; }
|
|
33
|
+
.file-item .file-error { color: #9b1c1c; }
|
|
34
|
+
.file-item img { max-width: 100%; }
|
|
35
|
+
`,we=()=>{if(typeof document>"u"||document.getElementById("wiki-plugin-file-style"))return;let e=document.createElement("style");e.id="wiki-plugin-file-style",e.textContent=ge,document.head.appendChild(e)},ee=e=>e.parents(".page"),be=e=>ee(e)[0].id.split("_rev")[0],ye=e=>ee(e).data("site")||null,$e=e=>{let r=ye(e),t=typeof wiki<"u"?wiki:null;return{base:t&&t.site?t.site(r).getDirectURL("assets"):"/assets",slug:be(e),site:r}},te=async e=>{let r=await fetch(e,{mode:"cors"});if(!r.ok)throw new Error(`${r.status} ${r.statusText}`);let t=await r.arrayBuffer();return new Uint8Array(t)},ve=async e=>{if(!(globalThis.crypto&&crypto.subtle))return"";let r=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(r)).map(t=>t.toString(16).padStart(2,"0")).join("")},L=new Map,ie=async e=>{let r=`${e}/SOURCES.toml`;if(L.has(r))return L.get(r);let t=(async()=>{try{let i=await te(r),n=new TextDecoder().decode(i);return C(n)}catch{return null}})();return L.set(r,t),t},ke=async e=>{let r=await fetch(e,{mode:"cors"});if(!r.ok)throw new Error(`${r.status}`);let t=await r.json();if(t.error)throw new Error(t.error.code||"error");return t.files||[]},Y=e=>e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`,y=(e,r,t,i)=>{let n=e.replace(/\n$/,"").split(`
|
|
36
|
+
`),o=n.length,s=!i&&o>t,l=s?n.slice(0,t):n,a=l.map((u,c)=>c+1).join(`
|
|
37
|
+
`),p=s?`<div class="file-more"><button class="file-showall">Show all ${o} lines</button></div>`:"";return`<div class="file-code"><pre class="file-lines">${a}</pre><pre class="file-text"><code class="language-${d(r)}">${d(l.join(`
|
|
38
|
+
`))}</code></pre></div>${p}`},re=e=>{let r;try{r=X(e)}catch(i){return`<div class="file-error">TOML did not parse: ${d(i.message)}</div>`+y(e,"ini",1e9,!0)}let t=([i,n,o])=>`<tr><td class="key">${d(i)}</td><td>${o==="multiline"?`<pre>${d(n)}</pre>`:d(n)}</td></tr>`;return r.map(i=>`${i.name?`<div class="file-section">[${d(i.name)}]</div>`:""}<table class="file-toml">${i.rows.map(t).join("")}</table>`).join("")},Ae=(e,r)=>{if(!e)return"";let t=[];return e.source&&t.push(`source ${d(e.source)}`),e.repo&&t.push(`repo ${d(e.repo)}`),e.commit&&t.push(`commit ${d(e.commit)}`),e.snapshot&&t.push(`snapshot ${d(e.snapshot)}`),e.role&&t.unshift(`<i>${d(e.role)}</i>`),`<div class="file-prov">${t.join(" \xB7 ")}</div>`},_=e=>{let r=globalThis.hljs;!r||!r.highlightElement||e.find('code[class^="language-"]').each(function(){r.highlightElement(this)})},Q=async(e,r,t,i)=>{let{url:n,folderUrl:o,name:s}=M(r,t);e.html(`<div class="file-toolbar"><span class="file-name">${d(s)}</span><span>loading\u2026</span></div>`);let l;try{l=await te(n)}catch(h){e.html(`<div class="file-toolbar"><span class="file-name">${d(s)}</span><span class="file-error">could not fetch ${d(n)} (${d(h.message)})</span></div>`);return}let a=await ie(o),p=a&&a[s]?a[s]:null,u=Z(s),c=u==="image"||u==="pdf"||B(l),m=c?"":new TextDecoder().decode(l),b="";if(p&&p.sha256){let h=await ve(l);h&&(b=h===p.sha256?`<span class="file-badge ok" title="sha256 ${d(h)}">matches snapshot</span>`:`<span class="file-badge drift" title="fetched ${d(h)} vs recorded ${d(p.sha256)}">differs from SOURCES.toml</span>`)}let ne=new Blob([l],{type:c?"application/octet-stream":"text/plain;charset=utf-8"}),R=URL.createObjectURL(ne),oe=`<div class="file-toolbar">
|
|
39
|
+
<span class="file-name">${d(s)}</span><span>${Y(l.length)}</span>${b}
|
|
40
|
+
${c?"":`<a class="btn file-raw" href="${R}" target="_blank" rel="noopener">Raw</a>`}
|
|
41
|
+
<a class="btn" href="${R}" download="${d(s)}">Download</a>
|
|
42
|
+
${c?"":'<button class="file-copy">Copy</button>'}
|
|
43
|
+
<a class="btn" href="${d(n)}" target="_blank" rel="noopener" title="the asset URL on the site">URL</a>
|
|
44
|
+
</div>`,w;if(u==="image")w=`<img src="${d(n)}" alt="${d(s)}">`;else if(u==="pdf")w=`<a href="${d(n)}" target="_blank" rel="noopener">Open ${d(s)} in a new tab</a>`;else if(c)w=`<span class="file-role">binary file, ${Y(l.length)}</span>`;else if(u==="markdown")w='<div class="file-md"></div>';else if(u==="toml")w=`<div class="file-toml-view">${re(m)}</div><div class="file-more"><button class="file-rawtoggle">Show raw</button></div>`;else if(u==="json"){let h=m;try{h=JSON.stringify(JSON.parse(m),null,2)}catch{}w=y(h,"json",i.lines,i.show)}else w=y(m,U[T(s)]||"plaintext",i.lines,i.show);if(e.html(`${oe}${Ae(p,s)}<div class="file-body">${w}</div>`),e.data("file",{text:m,name:s,lang:U[T(s)]||"plaintext",spec:i}),u==="markdown"&&typeof wiki<"u"&&wiki.getPlugin){let h=e.find(".file-md");wiki.getPlugin("markdown",P=>{try{P.emit(h,{type:"markdown",id:`file-${s}`,text:m})}catch{h.html(y(m,"markdown",i.lines,i.show))}})}_(e)},Ce=async(e,r,t,i)=>{let{folderUrl:n,listUrl:o,path:s}=V(r,t);e.html(`<div class="file-toolbar"><span class="file-name">${d(s)}/</span><span>listing\u2026</span></div>`);let l=await ie(n),a=[],p="";try{a=await ke(o)}catch(c){a=l?Object.keys(l).filter(m=>l[m]&&typeof l[m]=="object"):[],p=a.length?" (from SOURCES.toml; the folder list route is not available on this site)":` (no listing: ${d(c.message)})`}a=a.filter(c=>c!=="SOURCES.toml").sort(),l&&a.push("SOURCES.toml");let u=a.map(c=>{let m=l&&l[c]&&typeof l[c]=="object"?l[c]:null,b=m&&m.role?` <span class="file-role">\u2014 ${d(m.role)}</span>`:"";return`<li><a class="file-open" data-url="${d(`${n}/${encodeURIComponent(c)}`)}">${d(c)}</a>${b}</li>`});e.html(`<div class="file-toolbar"><span class="file-name">${d(s)}/</span><span>${a.length} file${a.length===1?"":"s"}${p}</span></div>
|
|
45
|
+
<div class="file-body"><ul class="file-list">${u.join("")||'<li class="file-role">no files</li>'}</ul><div class="file-view file-folder-view" hidden></div></div>`)},Se=(e,r)=>{we(),e.addClass("file-item");let t=I(r.text),i=[];for(let n of t.folders)i.push(`<div class="file-view" data-folder="${d(n)}"><div class="file-toolbar"><span>folder\u2026</span></div></div>`);for(let n of t.files)i.push(`<div class="file-view" data-file="${d(n)}"><div class="file-toolbar"><span class="file-name">${d(n)}</span><span>\u2026</span></div></div>`);e.html(i.join(""))},Te=(e,r)=>{let t=I(r.text),i=$e(e);e.on("dblclick",n=>{n.target&&n.target.closest&&n.target.closest(".file-toolbar, .file-list, .file-more")||wiki.textEditor(e,r)}),e.on("click",".file-open",function(n){n.preventDefault(),n.stopPropagation();let o=this.dataset.url,s=$(this).closest(".file-body").find(".file-folder-view");s.prop("hidden",!1),Q(s,o,i,t)}),e.on("click",".file-showall",function(n){n.preventDefault(),n.stopPropagation();let o=$(this).closest(".file-view"),s=o.data("file");s&&(o.find(".file-body").html(y(s.text,s.lang,1e9,!0)),_(o))}),e.on("click",".file-rawtoggle",function(n){n.preventDefault(),n.stopPropagation();let o=$(this).closest(".file-view"),s=o.data("file");if(!s)return;let l=o.find(".file-body");this.textContent==="Show raw"?(l.html(y(s.text,"ini",1e9,!0)+'<div class="file-more"><button class="file-rawtoggle">Show tables</button></div>'),_(o)):l.html(`<div class="file-toml-view">${re(s.text)}</div><div class="file-more"><button class="file-rawtoggle">Show raw</button></div>`)}),e.on("click",".file-copy",function(n){n.preventDefault(),n.stopPropagation();let o=$(this).closest(".file-view").data("file");!o||!navigator.clipboard||navigator.clipboard.writeText(o.text).then(()=>{this.textContent="Copied",setTimeout(()=>{this.textContent="Copy"},1500)})}),e.find(".file-view[data-folder]").each(function(){Ce($(this),this.dataset.folder,i,t)}),e.find(".file-view[data-file]").each(function(){Q($(this),this.dataset.file,i,t)})};typeof window<"u"&&(window.plugins=window.plugins||{},window.plugins.file={emit:Se,bind:Te});})();
|
|
46
|
+
/*! Bundled license information:
|
|
47
|
+
|
|
48
|
+
smol-toml/dist/date.js:
|
|
49
|
+
smol-toml/dist/error.js:
|
|
50
|
+
smol-toml/dist/util.js:
|
|
51
|
+
smol-toml/dist/primitive.js:
|
|
52
|
+
smol-toml/dist/extract.js:
|
|
53
|
+
smol-toml/dist/struct.js:
|
|
54
|
+
smol-toml/dist/parse.js:
|
|
55
|
+
smol-toml/dist/stringify.js:
|
|
56
|
+
smol-toml/dist/index.js:
|
|
57
|
+
(*!
|
|
58
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
59
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
60
|
+
*
|
|
61
|
+
* Redistribution and use in source and binary forms, with or without
|
|
62
|
+
* modification, are permitted provided that the following conditions are met:
|
|
63
|
+
*
|
|
64
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
65
|
+
* list of conditions and the following disclaimer.
|
|
66
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
67
|
+
* this list of conditions and the following disclaimer in the
|
|
68
|
+
* documentation and/or other materials provided with the distribution.
|
|
69
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
70
|
+
* may be used to endorse or promote products derived from this software without
|
|
71
|
+
* specific prior written permission.
|
|
72
|
+
*
|
|
73
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
74
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
75
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
76
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
77
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
78
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
79
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
80
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
81
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
82
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
83
|
+
*)
|
|
84
|
+
*/
|
|
85
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client/lib/parse.js", "../src/client/lib/resolve.js", "../src/client/lib/detect.js", "../node_modules/smol-toml/dist/date.js", "../node_modules/smol-toml/dist/error.js", "../node_modules/smol-toml/dist/util.js", "../node_modules/smol-toml/dist/primitive.js", "../node_modules/smol-toml/dist/extract.js", "../node_modules/smol-toml/dist/struct.js", "../node_modules/smol-toml/dist/parse.js", "../src/client/lib/toml-view.js", "../src/client/file.js"],
|
|
4
|
+
"sourcesContent": ["// Item text DSL (fedwiki-dsl): UPPERCASE first word is a command, the rest is\n// its argument; an optional trailing colon on the keyword is allowed.\n//\n// FILE BUGS.toml a file in this page's own assets folder\n// FILE assets/other-slug/notes.md a file in another folder on this site\n// FILE https://host/assets/x/y.md any absolute URL\n// FOLDER [slug | https://host/assets/path] list a folder (default: this page's)\n// LINES 60 collapse files longer than this (default 40)\n// SHOW start expanded\n//\n// Empty text means FOLDER: a freshly added item lists the page's own folder.\n\nexport const DEFAULT_LINES = 40\n\nexport const parse = text => {\n const spec = { files: [], folders: [], lines: DEFAULT_LINES, show: false }\n const lines = String(text || '').split(/\\r?\\n/)\n for (const raw of lines) {\n const line = raw.trim()\n if (!line) continue\n const m = line.match(/^([A-Z]+):?(?:\\s+(.*))?$/)\n if (!m) continue\n const [, cmd, arg = ''] = m\n switch (cmd) {\n case 'FILE':\n if (arg) spec.files.push(arg.trim())\n break\n case 'FOLDER':\n spec.folders.push(arg.trim())\n break\n case 'LINES': {\n const n = parseInt(arg, 10)\n if (n > 0) spec.lines = n\n break\n }\n case 'SHOW':\n spec.show = true\n break\n default:\n break\n }\n }\n if (!spec.files.length && !spec.folders.length) spec.folders.push('')\n return spec\n}\n", "// Turn a FILE / FOLDER reference into URLs.\n// base \u2014 the site's assets base, e.g. https://site/assets ('' if unreachable)\n// slug \u2014 the enclosing page's slug (its own assets folder)\n// origin(base) \u2014 the site origin, for the plugin list route\n\nexport const isAbsolute = ref => /^https?:\\/\\//i.test(ref)\n\nconst trimSlash = s => s.replace(/\\/+$/, '')\n\nexport const originOf = url => {\n const m = String(url).match(/^(https?:\\/\\/[^/]+)/i)\n return m ? m[1] : ''\n}\n\n// A file reference \u2192 { url, folderUrl, name }\nexport const resolveFile = (ref, { base, slug }) => {\n let url\n if (isAbsolute(ref)) url = ref\n else if (ref.startsWith('/assets/')) url = `${trimSlash(base)}${ref.slice('/assets'.length)}`\n else if (ref.startsWith('assets/')) url = `${trimSlash(base)}/${ref.slice('assets/'.length)}`\n else url = `${trimSlash(base)}/${slug}/${ref}`\n const cut = url.lastIndexOf('/')\n return { url, folderUrl: url.slice(0, cut), name: decodeURIComponent(url.slice(cut + 1)) }\n}\n\n// A folder reference \u2192 { folderUrl, listUrl, path }\n// '' \u2192 this page's folder\n// 'other-slug' \u2192 a sibling folder on this site\n// 'https://host/assets/path' \u2192 a folder on another site\nexport const resolveFolder = (ref, { base, slug }) => {\n if (isAbsolute(ref)) {\n const folderUrl = trimSlash(ref)\n const origin = originOf(folderUrl)\n const path = folderUrl.slice((origin + '/assets/').length)\n return { folderUrl, path, listUrl: `${origin}/plugin/assets/list?assets=${encodeURIComponent(path)}` }\n }\n const path = ref ? ref.replace(/^\\/?assets\\//, '').replace(/^\\/+/, '') : slug\n const folderUrl = `${trimSlash(base)}/${path}`\n const origin = originOf(folderUrl)\n return { folderUrl, path, listUrl: `${origin}/plugin/assets/list?assets=${encodeURIComponent(path)}` }\n}\n", "// Which renderer a file gets, from its extension; and a cheap binary sniff.\n\nconst KINDS = {\n md: 'markdown', markdown: 'markdown',\n toml: 'toml',\n json: 'json',\n png: 'image', jpg: 'image', jpeg: 'image', gif: 'image', svg: 'image', webp: 'image',\n pdf: 'pdf',\n}\n\nexport const LANGS = {\n py: 'python', rs: 'rust', sh: 'bash', bash: 'bash', zsh: 'bash', js: 'javascript', mjs: 'javascript',\n ts: 'typescript', coffee: 'coffeescript', yaml: 'yaml', yml: 'yaml', toml: 'ini', ini: 'ini', cfg: 'ini',\n json: 'json', md: 'markdown', html: 'xml', css: 'css', csv: 'plaintext', txt: 'plaintext', log: 'plaintext',\n}\n\nexport const extOf = name => {\n const m = String(name).toLowerCase().match(/\\.([a-z0-9]+)$/)\n return m ? m[1] : ''\n}\n\nexport const kindOf = name => KINDS[extOf(name)] || 'text'\n\n// True when the first 4KB contain a NUL or are mostly non-printable.\nexport const looksBinary = bytes => {\n const n = Math.min(bytes.length, 4096)\n if (n === 0) return false\n let bad = 0\n for (let i = 0; i < n; i++) {\n const b = bytes[i]\n if (b === 0) return true\n if (b < 9 || (b > 13 && b < 32)) bad++\n }\n return bad / n > 0.1\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nlet DATE_TIME_RE = /^(\\d{4}-\\d{2}-\\d{2})?[T ]?(?:(\\d{2}):\\d{2}(?::\\d{2}(?:\\.\\d+)?)?)?(Z|[-+]\\d{2}:\\d{2})?$/i;\nexport class TomlDate extends Date {\n #hasDate = false;\n #hasTime = false;\n #offset = null;\n constructor(date) {\n let hasDate = true;\n let hasTime = true;\n let offset = 'Z';\n if (typeof date === 'string') {\n let match = date.match(DATE_TIME_RE);\n if (match) {\n if (!match[1]) {\n hasDate = false;\n date = `0000-01-01T${date}`;\n }\n hasTime = !!match[2];\n // Make sure to use T instead of a space. Breaks in case of extreme values otherwise.\n hasTime && date[10] === ' ' && (date = date.replace(' ', 'T'));\n // Do not allow rollover hours.\n if (match[2] && +match[2] > 23) {\n date = '';\n }\n else {\n offset = match[3] || null;\n date = date.toUpperCase();\n if (!offset && hasTime)\n date += 'Z';\n }\n }\n else {\n date = '';\n }\n }\n super(date);\n if (!isNaN(this.getTime())) {\n this.#hasDate = hasDate;\n this.#hasTime = hasTime;\n this.#offset = offset;\n }\n }\n isDateTime() {\n return this.#hasDate && this.#hasTime;\n }\n isLocal() {\n return !this.#hasDate || !this.#hasTime || !this.#offset;\n }\n isDate() {\n return this.#hasDate && !this.#hasTime;\n }\n isTime() {\n return this.#hasTime && !this.#hasDate;\n }\n isValid() {\n return this.#hasDate || this.#hasTime;\n }\n toISOString() {\n let iso = super.toISOString();\n // Local Date\n if (this.isDate())\n return iso.slice(0, 10);\n // Local Time\n if (this.isTime())\n return iso.slice(11, 23);\n // Local DateTime\n if (this.#offset === null)\n return iso.slice(0, -1);\n // Offset DateTime\n if (this.#offset === 'Z')\n return iso;\n // This part is quite annoying: JS strips the original timezone from the ISO string representation\n // Instead of using a \"modified\" date and \"Z\", we restore the representation \"as authored\"\n let offset = (+(this.#offset.slice(1, 3)) * 60) + +(this.#offset.slice(4, 6));\n offset = this.#offset[0] === '-' ? offset : -offset;\n let offsetDate = new Date(this.getTime() - (offset * 60e3));\n return offsetDate.toISOString().slice(0, -1) + this.#offset;\n }\n static wrapAsOffsetDateTime(jsDate, offset = 'Z') {\n let date = new TomlDate(jsDate);\n date.#offset = offset;\n return date;\n }\n static wrapAsLocalDateTime(jsDate) {\n let date = new TomlDate(jsDate);\n date.#offset = null;\n return date;\n }\n static wrapAsLocalDate(jsDate) {\n let date = new TomlDate(jsDate);\n date.#hasTime = false;\n date.#offset = null;\n return date;\n }\n static wrapAsLocalTime(jsDate) {\n let date = new TomlDate(jsDate);\n date.#hasDate = false;\n date.#offset = null;\n return date;\n }\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nfunction getLineColFromPtr(string, ptr) {\n let lines = string.slice(0, ptr).split(/\\r\\n|\\n|\\r/g);\n return [lines.length, lines.pop().length + 1];\n}\nfunction makeCodeBlock(string, line, column) {\n let lines = string.split(/\\r\\n|\\n|\\r/g);\n let codeblock = '';\n let numberLen = (Math.log10(line + 1) | 0) + 1;\n for (let i = line - 1; i <= line + 1; i++) {\n let l = lines[i - 1];\n if (!l)\n continue;\n codeblock += i.toString().padEnd(numberLen, ' ');\n codeblock += ': ';\n codeblock += l;\n codeblock += '\\n';\n if (i === line) {\n codeblock += ' '.repeat(numberLen + column + 2);\n codeblock += '^\\n';\n }\n }\n return codeblock;\n}\nexport class TomlError extends Error {\n line;\n column;\n codeblock;\n constructor(message, options) {\n const [line, column] = getLineColFromPtr(options.toml, options.ptr);\n const codeblock = makeCodeBlock(options.toml, line, column);\n super(`Invalid TOML document: ${message}\\n\\n${codeblock}`, options);\n this.line = line;\n this.column = column;\n this.codeblock = codeblock;\n }\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { TomlError } from './error.js';\n/** @internal */\nexport function indexOfNewline(str, start = 0) {\n let idx = str.indexOf('\\n', start);\n if (str.charCodeAt(idx - 1) === 0xd /* \\r */)\n idx--;\n return idx;\n}\n/** @internal */\nexport function skipComment(ctx) {\n for (; ctx.p < ctx.s.length; ctx.p++) {\n let c = ctx.s.charCodeAt(ctx.p);\n if (c === 0xa /* \\n */)\n break;\n if (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */) {\n ctx.p++;\n break;\n }\n if ((c < 0x20 && c !== 0x9 /* \\t */) || c === 0x7f) {\n throw new TomlError('control characters are not allowed in comments', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n }\n}\n/** @internal */\nexport function skipVoid(ctx, banNewLines, banComments) {\n let c;\n while (1) {\n while ((c = ctx.s.charCodeAt(ctx.p)) === 0x20 ||\n c === 0x9 /* \\t */ ||\n (!banNewLines &&\n (c === 0xa /* \\n */ || (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */))))\n ctx.p++;\n if (banComments || c !== 0x23 /* # */)\n break;\n skipComment(ctx);\n }\n}\n/** @internal */\nexport function skipUntil(ctx, sep, end) {\n let ptr = ctx.p;\n if (!end) {\n ptr = indexOfNewline(ctx.s, ptr);\n ctx.p = ptr < 0 ? ctx.s.length : ptr;\n return;\n }\n for (; ctx.p < ctx.s.length; ctx.p++) {\n let c = ctx.s.charCodeAt(ctx.p);\n if (c === 0x23 /* # */) {\n skipComment(ctx);\n }\n else if (c === end || c === sep) {\n return;\n }\n }\n throw new TomlError('cannot find end of structure', {\n toml: ctx.s,\n ptr,\n });\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { TomlDate } from './date.js';\nimport { TomlError } from './error.js';\nimport { skipComment, skipUntil } from './util.js';\n// let CTRL_REGEX = /[\\x00-\\x08\\x0f-\\x1f\\x7f]/\nlet INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\\d(_?\\d)*))$/;\nlet FLOAT_REGEX = /^[+-]?\\d(_?\\d)*(\\.\\d(_?\\d)*)?([eE][+-]?\\d(_?\\d)*)?$/;\nlet LEADING_ZERO = /^[+-]?0[0-9_]/;\n/** @internal */\nexport function parseString(ctx) {\n let start = ctx.p;\n let c = ctx.s.charCodeAt(ctx.p++);\n let first = c;\n let isLiteral = c === 0x27; /* ' */\n let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);\n if (isMultiline) {\n // Trim initial newline\n if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 0xa /* \\n */)\n ctx.p++;\n else if (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */)\n ctx.p += 2;\n }\n /*\n The fast path does not seem to bring significant performance gains, so it's commented out.\n Kept for reference and/or future fafoing.\n\n Without: spec 5.08 \u00B5s/iter 3.88 ipc (99.44% cache) 23.90 branch misses 28.61k cycles 111.01k instructions\n 5MB 115.73 ms/iter 2.51 ipc (98.36% cache) 3.12M branch misses 619.30M cycles 1.56G instructions\n\n With: spec 5.09 \u00B5s/iter 3.90 ipc (99.46% cache) 24.42 branch misses 28.57k cycles 111.49k instructions\n 5MB 113.89 ms/iter 2.47 ipc (98.38% cache) 3.12M branch misses 611.94M cycles 1.51G instructions\n\n if (c === \"'\") {\n // Literal strings fast path - no transform needs to occur; just grab the str and that's it\n let endPtr = str.indexOf(isMultiline ? \"'''\" : \"'\", ptr)\n if (endPtr < 0) {\n throw new TomlError(\"unfinished string literal\", { toml: str, ptr })\n }\n\n if (isMultiline) {\n // If the string ends with 4-5 quotes, then the first 1-2 are part of the string\n if (str[endPtr + 3] === \"'\") endPtr++\n if (str[endPtr + 3] === \"'\") endPtr++\n }\n\n let string = str.slice(ptr, endPtr)\n if (CTRL_REGEX.test(string)) {\n let match = string.match(CTRL_REGEX)!\n throw new TomlError('control characters are not allowed in strings', { toml: str, ptr: ptr + (match.index ?? 0) })\n }\n return [string, endPtr + (isMultiline ? 3 : 1)]\n }\n */\n let parsed = '';\n let sliceStart = ctx.p;\n // states:\n // 0 - decoding\n // 1 - decoding escape\n // 2 - whitespace escape (no newline encountered yet, must fail on non-whitespace)\n // 3 - whitespace escape (newline encountered, allowed to transition back to normal decode)\n let state = 0;\n for (; ctx.p < ctx.s.length; ctx.p++) {\n c = ctx.s.charCodeAt(ctx.p);\n // Deal with newlines first, since that simplifies control character checking and handling across all states\n if (isMultiline && (c === 0xa /* \\n */ || (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */))) {\n state = state && 3;\n }\n // Control characters are banned in TOML, so we throw an error if we encounter them\n else if ((c < 0x20 && c !== 0x9 /* \\t */) || c === 0x7f) {\n throw new TomlError('control characters are not allowed in strings', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n // The string might terminate while we're parsing through a newline escape.\n // It must have encountered a newline; otherwise, it'll simply fail in another branch.\n else if ((!state || state === 3) && c === first && (!isMultiline || (ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first))) {\n if (isMultiline) {\n // If the string ends with 4-5 quotes, then the first 1-2 are part of the string\n if (ctx.s.charCodeAt(ctx.p + 3) === first)\n ctx.p++;\n if (ctx.s.charCodeAt(ctx.p + 3) === first)\n ctx.p++;\n }\n // If we're in a newline escape still, then there's nothing to add.\n if (!state)\n parsed += ctx.s.slice(sliceStart, ctx.p);\n ctx.p += isMultiline ? 3 : 1;\n return parsed;\n }\n else if (!state) {\n if (!isLiteral && c === 0x5c /* \\ */) {\n parsed += ctx.s.slice(sliceStart, (sliceStart = ctx.p));\n state = 1;\n }\n }\n else if (state === 1) {\n if (c === 0x78 /* x */ || c === 0x75 /* u */ || c === 0x55 /* U */) { // Unicode escape\n let value = 0;\n let len = c === 0x78 /* x */ ? 2 : c === 0x75 /* u */ ? 4 : 8;\n for (let j = 0; j < len; j++, ctx.p++) {\n let hex = ctx.s.charCodeAt(ctx.p + 1);\n let digit = \n /* 0-9 */ hex >= 0x30 && hex <= 0x39 ? hex - 0x30 :\n /* A-F */ hex >= 0x41 && hex <= 0x46 ? hex - 0x41 + 10 :\n /* a-f */ hex >= 0x61 && hex <= 0x66 ? hex - 0x61 + 10 : -1;\n if (digit < 0)\n throw new TomlError('invalid non-hex character in unicode escape', { toml: ctx.s, ptr: ctx.p + 1 });\n value = (value << 4) | digit;\n }\n // Because JS does bitwise on signed 32bit integers, all 0xfzzzzzzz values are actually seen as negative\n if (value < 0 || value > 0x10ffff || (value >= 0xd800 && value <= 0xdfff)) {\n throw new TomlError('invalid unicode escape', { toml: ctx.s, ptr: ctx.p });\n }\n parsed += String.fromCodePoint(value);\n sliceStart = ctx.p + 1;\n state = 0;\n }\n else if (c === 0x20 || c === 0x9 /* \\t */) { // If it was a newline, it'd have been handled earlier\n state = 2;\n }\n else {\n if (c === 0x62 /* b */)\n parsed += '\\b';\n else if (c === 0x74 /* t */)\n parsed += '\\t';\n else if (c === 0x6e /* n */)\n parsed += '\\n';\n else if (c === 0x66 /* f */)\n parsed += '\\f';\n else if (c === 0x72 /* r */)\n parsed += '\\r';\n else if (c === 0x65 /* e */)\n parsed += '\\x1b';\n else if (c === 0x22 /* \" */)\n parsed += '\"';\n else if (c === 0x5c /* \\ */)\n parsed += '\\\\';\n else\n throw new TomlError('unrecognized escape sequence', { toml: ctx.s, ptr: ctx.p });\n sliceStart = ctx.p + 1;\n state = 0;\n }\n }\n else if (c !== 0x20 && c !== 0x9 /* \\t */) {\n if (state === 2) {\n throw new TomlError('invalid escape: only line-ending whitespace may be escaped', {\n toml: ctx.s,\n ptr: sliceStart,\n });\n }\n // State cannot be zero, or we'd have branched earlier already.\n // If it's a backslash, immediately transition to the escape state so it can be processed.\n state = !isLiteral && c === 0x5c /* \\ */ ? 1 : 0;\n sliceStart = ctx.p;\n }\n }\n throw new TomlError('unfinished string', { toml: ctx.s, ptr: start });\n}\nfunction sliceAndTrimEndOf(ctx, start, end) {\n let value = ctx.s.slice(start, end);\n let commentIdx = value.indexOf('#');\n if (commentIdx > 0) {\n // The call to skipComment allows to \"validate\" the comment\n // (absence of control characters)\n skipComment({ s: value, p: commentIdx, d: 0 });\n value = value.slice(0, commentIdx);\n }\n return value.trimEnd();\n}\n/** @internal */\nexport function parseValue(ctx, integersAsBigInt, end) {\n let ptr = ctx.p;\n let err = { toml: ctx.s, ptr };\n skipUntil(ctx, 0x2c /* , */, end);\n let value = sliceAndTrimEndOf(ctx, ptr, ctx.p);\n if (!value)\n throw new TomlError('incomplete declaration: value expected', err);\n if (value === '-inf')\n return -Infinity;\n if (value === 'inf' || value === '+inf')\n return Infinity;\n if (value === 'nan' || value === '+nan' || value === '-nan')\n return NaN;\n // Avoid FP representation of -0\n if (value === '-0')\n return integersAsBigInt ? 0n : 0;\n // Numbers\n let isInt = INT_REGEX.test(value);\n if (isInt || FLOAT_REGEX.test(value)) {\n if (LEADING_ZERO.test(value)) {\n throw new TomlError('leading zeroes are not allowed', err);\n }\n value = value.replace(/_/g, '');\n let numeric = +value;\n if (isNaN(numeric)) {\n throw new TomlError('invalid number', err);\n }\n if (isInt) {\n if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {\n throw new TomlError('integer value cannot be represented losslessly', err);\n }\n if (isInt || integersAsBigInt === true)\n numeric = BigInt(value);\n }\n return numeric;\n }\n const date = new TomlDate(value);\n if (!date.isValid())\n throw new TomlError('invalid value', err);\n return date;\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseString, parseValue } from './primitive.js';\nimport { parseArray, parseInlineTable } from './struct.js';\nimport { TomlError } from './error.js';\n/** @internal */\nexport function extractValue(ctx, end, integersAsBigInt) {\n let ptr = ctx.p;\n let c = ctx.s.charCodeAt(ptr);\n // Structs\n if (c === 0x5b /* [ */ || c === 0x7b /* { */) {\n if (!ctx.d--) {\n throw new TomlError('document contains excessively nested structures. aborting.', {\n toml: ctx.s,\n ptr,\n });\n }\n let value = c === 0x5b /* [ */\n ? parseArray(ctx, integersAsBigInt)\n : parseInlineTable(ctx, integersAsBigInt);\n ctx.d++;\n return value;\n }\n // Strings\n if (c === 0x22 /* \" */ || c === 0x27 /* ' */) {\n return parseString(ctx);\n }\n // Booleans\n // We can fast-path because the first character is enough to know the only possible value\n if (c === 0x74 /* t */) { // Only possible valid value is `true`\n if (ctx.s.charCodeAt(++ctx.p) !== 0x72 || ctx.s.charCodeAt(++ctx.p) !== 0x75 || ctx.s.charCodeAt(++ctx.p) !== 0x65)\n throw new TomlError('invalid value', { toml: ctx.s, ptr });\n ctx.p++;\n return true;\n }\n if (c === 0x66 /* f */) { // Only possible valid value is `false`\n if (ctx.s.charCodeAt(++ctx.p) !== 0x61 || ctx.s.charCodeAt(++ctx.p) !== 0x6c || ctx.s.charCodeAt(++ctx.p) !== 0x73 || ctx.s.charCodeAt(++ctx.p) !== 0x65)\n throw new TomlError('invalid value', { toml: ctx.s, ptr });\n ctx.p++;\n return false;\n }\n // Legacy logic for numbers and dates. Slow and needs to be rewritten.\n return parseValue(ctx, integersAsBigInt, end);\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseString } from './primitive.js';\nimport { extractValue } from './extract.js';\nimport { indexOfNewline, skipVoid } from './util.js';\nimport { TomlError } from './error.js';\nlet KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \\t]*$/;\n/** @internal */\nexport function parseKey(ctx, end = '=') {\n let start = ctx.p;\n let dot = start - 1;\n let parsed = [];\n let endPtr = ctx.s.indexOf(end, start);\n if (endPtr < 0) {\n throw new TomlError('incomplete key-value: cannot find end of key', {\n toml: ctx.s,\n ptr: start,\n });\n }\n do {\n let c = ctx.s.charCodeAt(ctx.p = ++dot);\n // If it's whitespace, ignore\n if (c !== 0x20 && c !== 0x9 /* \\t */) {\n // If it's a string\n if (c === 0x22 /* \" */ || c === 0x27 /* ' */) {\n if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) {\n throw new TomlError('multiline strings are not allowed in keys', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n let part = parseString(ctx);\n dot = ctx.s.indexOf('.', ctx.p);\n let strEnd = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);\n let newLine = indexOfNewline(strEnd);\n if (newLine > -1) {\n throw new TomlError('newlines are not allowed in keys', {\n toml: ctx.s,\n ptr: newLine,\n });\n }\n if (strEnd.trimStart()) {\n throw new TomlError('found extra tokens after the string part', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n if (endPtr < ctx.p) {\n endPtr = ctx.s.indexOf(end, ctx.p);\n if (endPtr < 0) {\n throw new TomlError('incomplete key-value: cannot find end of key', {\n toml: ctx.s,\n ptr: start,\n });\n }\n }\n parsed.push(part);\n }\n else {\n // Normal raw key part consumption and validation\n dot = ctx.s.indexOf('.', ctx.p);\n let part = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);\n if (!KEY_PART_RE.test(part)) {\n throw new TomlError('only letter, numbers, dashes and underscores are allowed in keys', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n parsed.push(part.trimEnd());\n }\n }\n // Until there's no more dot\n } while (dot + 1 && dot < endPtr);\n ctx.p = endPtr + 1;\n skipVoid(ctx, true, true);\n return parsed;\n}\n/** @internal */\nexport function parseInlineTable(ctx, integersAsBigInt) {\n let res = {};\n let seen = new Set();\n let c;\n ctx.p++;\n while (ctx.p < ctx.s.length) {\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p)) === 0x7d /* } */) {\n ctx.p++;\n return res;\n }\n let k;\n let t = res;\n let hasOwn = false;\n let p = ctx.p;\n let key = parseKey(ctx);\n for (let i = 0; i < key.length; i++) {\n if (i)\n t = hasOwn ? t[k] : (t[k] = {});\n k = key[i];\n if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== 'object' || seen.has(t[k]))) {\n throw new TomlError('trying to redefine an already defined value', {\n toml: ctx.s,\n ptr: p,\n });\n }\n if (!hasOwn && k === '__proto__') {\n Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });\n }\n }\n if (hasOwn) {\n throw new TomlError('trying to redefine an already defined value', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n let value = extractValue(ctx, 0x7d /* } */, integersAsBigInt);\n seen.add(t[k] = value);\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p++)) === 0x7d /* } */) {\n return res;\n }\n if (c !== 0x2c /* , */) {\n throw new TomlError('expected comma or end of structure', { toml: ctx.s, ptr: ctx.p - 1 });\n }\n }\n throw new TomlError('unfinished table encountered', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n}\n/** @internal */\nexport function parseArray(ctx, integersAsBigInt) {\n let res = [];\n let c;\n ctx.p++;\n while (ctx.p < ctx.s.length) {\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p)) === 0x5d /* ] */) {\n ctx.p++;\n return res;\n }\n res.push(extractValue(ctx, 0x5d /* ] */, integersAsBigInt));\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p++)) === 0x5d /* ] */) {\n return res;\n }\n if (c !== 0x2c /* , */) {\n throw new TomlError('expected comma or end of structure', { toml: ctx.s, ptr: ctx.p - 1 });\n }\n }\n throw new TomlError('unfinished array encountered', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseKey } from './struct.js';\nimport { extractValue } from './extract.js';\nimport { skipVoid } from './util.js';\nimport { TomlError } from './error.js';\nfunction peekTable(key, table, meta, type) {\n let t = table;\n let m = meta;\n let k;\n let hasOwn = false;\n let state;\n for (let i = 0; i < key.length; i++) {\n if (i) {\n t = hasOwn ? t[k] : (t[k] = {});\n m = (state = m[k]).c;\n if (type === 0 /* Type.DOTTED */ && (state.t === 1 /* Type.EXPLICIT */ || state.t === 2 /* Type.ARRAY */)) {\n return null;\n }\n if (state.t === 2 /* Type.ARRAY */) {\n let l = t.length - 1;\n t = t[l];\n m = m[l].c;\n }\n }\n k = key[i];\n if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 /* Type.DOTTED */ && m[k]?.d) {\n return null;\n }\n if (!hasOwn) {\n if (k === '__proto__') {\n Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });\n Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });\n }\n m[k] = {\n t: i < key.length - 1 && type === 2 /* Type.ARRAY */\n ? 3 /* Type.ARRAY_DOTTED */ : type,\n d: false,\n i: 0,\n c: {},\n };\n }\n }\n state = m[k];\n if (state.t !== type && !(type === 1 /* Type.EXPLICIT */ && state.t === 3 /* Type.ARRAY_DOTTED */)) {\n // Bad key type!\n return null;\n }\n if (type === 2 /* Type.ARRAY */) {\n if (!state.d) {\n state.d = true;\n t[k] = [];\n }\n t[k].push(t = {});\n state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c: {} });\n }\n if (state.d) {\n // Redefining a table!\n return null;\n }\n state.d = true;\n if (type === 1 /* Type.EXPLICIT */) {\n t = hasOwn ? t[k] : (t[k] = {});\n }\n else if (type === 0 /* Type.DOTTED */ && hasOwn) {\n return null;\n }\n return [k, t, state.c];\n}\nexport function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {\n let ctx = { s: toml, p: 0, d: maxDepth };\n let res = {};\n let meta = {};\n let tmp;\n let tbl = res;\n let m = meta;\n skipVoid(ctx);\n while (ctx.p < toml.length) {\n if (toml.charCodeAt(ctx.p) === 0x5b /* [ */) {\n let isTableArray = toml.charCodeAt(++ctx.p) === 0x5b; /* [ */\n tmp = ctx.p += +isTableArray;\n let k = parseKey(ctx, ']');\n if (isTableArray) {\n if (toml.charCodeAt(ctx.p - 1) !== 0x5d /* ] */) {\n throw new TomlError('expected end of table declaration', {\n toml: toml,\n ptr: ctx.p - 1,\n });\n }\n ctx.p++;\n }\n let p = peekTable(k, res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);\n if (!p) {\n throw new TomlError('trying to redefine an already defined table or value', {\n toml: toml,\n ptr: tmp,\n });\n }\n m = p[2];\n tbl = p[1];\n }\n else {\n tmp = ctx.p;\n let k = parseKey(ctx);\n let p = peekTable(k, tbl, m, 0 /* Type.DOTTED */);\n if (!p) {\n throw new TomlError('trying to redefine an already defined table or value', {\n toml: toml,\n ptr: tmp,\n });\n }\n p[1][p[0]] = extractValue(ctx, void 0, integersAsBigInt);\n }\n skipVoid(ctx, true);\n if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 0xa /* \\n */ && tmp !== 0xd /* \\r */) {\n throw new TomlError('each key-value declaration must be followed by an end-of-line', {\n toml: toml,\n ptr: ctx.p,\n });\n }\n skipVoid(ctx);\n }\n return res;\n}\n", "// A TOML document \u2192 a list of sections for tabular display.\n// [{ name: 'BUGS' | 'section.name' | 'arr[2]', rows: [[key, value, kind]] }]\n// Scalars at the top level form a first section named '' (root). Nested\n// tables are flattened into dotted keys inside their parent section; arrays\n// of tables become one section each, suffixed [i].\n\nimport { parse as parseToml } from 'smol-toml'\n\nconst isTable = v => v && typeof v === 'object' && !Array.isArray(v) && !(v instanceof Date)\n\nconst kindOf = v => {\n if (typeof v === 'string') return v.includes('\\n') ? 'multiline' : 'string'\n if (Array.isArray(v)) return 'array'\n if (v instanceof Date) return 'date'\n return typeof v\n}\n\nconst show = v => {\n if (typeof v === 'string') return v\n if (v instanceof Date) return v.toISOString()\n if (Array.isArray(v)) return v.map(x => (isTable(x) ? JSON.stringify(x) : show(x))).join(', ')\n return String(v)\n}\n\nconst rowsOf = (obj, prefix, rows, sections) => {\n for (const [k, v] of Object.entries(obj)) {\n const key = prefix ? `${prefix}.${k}` : k\n if (isTable(v)) rowsOf(v, key, rows, sections)\n else if (Array.isArray(v) && v.length && v.every(isTable)) {\n v.forEach((t, i) => {\n const rs = []\n rowsOf(t, '', rs, sections)\n sections.push({ name: `${key}[${i}]`, rows: rs })\n })\n } else rows.push([key, show(v), kindOf(v)])\n }\n}\n\nexport const sectionsOf = doc => {\n const sections = []\n const root = []\n for (const [k, v] of Object.entries(doc)) {\n if (isTable(v)) {\n const rows = []\n const nested = []\n rowsOf(v, '', rows, nested)\n sections.push({ name: k, rows })\n for (const s of nested) sections.push({ ...s, name: `${k}.${s.name}` })\n } else if (Array.isArray(v) && v.length && v.every(isTable)) {\n v.forEach((t, i) => {\n const rows = []\n const nested = []\n rowsOf(t, '', rows, nested)\n sections.push({ name: `${k}[${i}]`, rows })\n })\n } else root.push([k, show(v), kindOf(v)])\n }\n if (root.length) sections.unshift({ name: '', rows: root })\n return sections\n}\n\nexport const tomlSections = text => sectionsOf(parseToml(text))\n", "// wiki-plugin-file \u2014 read a file from a page's assets folder, in the page.\n//\n// The farm serves assets with whatever Content-Type its mime table guesses;\n// browsers download .toml, .py, .rs and even .md. fetch() does not care, so\n// this plugin fetches the bytes and renders them itself: markdown through the\n// wiki's own markdown plugin (wikilinks resolve), TOML as tables, code with\n// line numbers, images inline. Raw opens the text in a new tab as text/plain,\n// which every browser displays. See pages/about-file-plugin for the DSL.\n\nimport { parse } from './lib/parse.js'\nimport { resolveFile, resolveFolder } from './lib/resolve.js'\nimport { kindOf, extOf, looksBinary, LANGS } from './lib/detect.js'\nimport { tomlSections } from './lib/toml-view.js'\nimport { parse as parseToml } from 'smol-toml'\n\nconst esc = s => String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"')\n\nconst CSS = `\n.file-item { font-size: 13px; }\n.file-item .file-list { margin: 0 0 6px 0; padding: 0; list-style: none; }\n.file-item .file-list li { padding: 2px 0; }\n.file-item .file-list a { cursor: pointer; }\n.file-item .file-role { color: #777; }\n.file-item .file-view { border: 1px solid #ddd; border-radius: 4px; margin: 6px 0; background: #fafafa; }\n.file-item .file-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; padding: 4px 8px; border-bottom: 1px solid #e5e5e5; color: #555; }\n.file-item .file-toolbar .file-name { font-weight: bold; color: #222; }\n.file-item .file-toolbar button, .file-item .file-toolbar a.btn { font-size: 11px; padding: 1px 6px; border: 1px solid #bbb; border-radius: 3px; background: #fff; color: #333; text-decoration: none; cursor: pointer; }\n.file-item .file-prov { font-size: 11px; color: #777; padding: 2px 8px 4px; border-bottom: 1px solid #eee; }\n.file-item .file-badge { font-size: 11px; padding: 0 5px; border-radius: 8px; }\n.file-item .file-badge.ok { background: #e3f5e3; color: #1e6b1e; }\n.file-item .file-badge.drift { background: #fde8e8; color: #9b1c1c; }\n.file-item .file-body { padding: 6px 8px; overflow-x: auto; }\n.file-item .file-code { display: flex; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.45; }\n.file-item .file-code pre { margin: 0; white-space: pre; }\n.file-item .file-code .file-lines { color: #aaa; text-align: right; padding-right: 10px; user-select: none; }\n.file-item .file-more { margin: 4px 0 0; }\n.file-item table.file-toml { border-collapse: collapse; margin: 4px 0 10px; width: 100%; }\n.file-item table.file-toml th, .file-item table.file-toml td { border: 1px solid #ddd; padding: 3px 6px; vertical-align: top; text-align: left; }\n.file-item table.file-toml th { background: #f0f0f0; }\n.file-item table.file-toml td.key { font-family: ui-monospace, Menlo, monospace; white-space: nowrap; color: #444; }\n.file-item table.file-toml pre { margin: 0; white-space: pre-wrap; font-size: 12px; }\n.file-item .file-section { font-weight: bold; margin: 8px 0 2px; font-family: ui-monospace, Menlo, monospace; }\n.file-item .file-error { color: #9b1c1c; }\n.file-item img { max-width: 100%; }\n`\n\nconst ensureStyle = () => {\n if (typeof document === 'undefined' || document.getElementById('wiki-plugin-file-style')) return\n const s = document.createElement('style')\n s.id = 'wiki-plugin-file-style'\n s.textContent = CSS\n document.head.appendChild(s)\n}\n\n// ---- page context -----------------------------------------------------------\n\nconst pageOf = $item => $item.parents('.page')\nconst slugOf = $item => pageOf($item)[0].id.split('_rev')[0]\nconst siteOf = $item => pageOf($item).data('site') || null\n\nconst contextOf = $item => {\n const site = siteOf($item)\n const w = typeof wiki !== 'undefined' ? wiki : null\n const base = w && w.site ? w.site(site).getDirectURL('assets') : '/assets'\n return { base, slug: slugOf($item), site }\n}\n\n// ---- fetching ---------------------------------------------------------------\n\nconst fetchBytes = async url => {\n const res = await fetch(url, { mode: 'cors' })\n if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)\n const buf = await res.arrayBuffer()\n return new Uint8Array(buf)\n}\n\nconst sha256 = async bytes => {\n if (!(globalThis.crypto && crypto.subtle)) return ''\n const h = await crypto.subtle.digest('SHA-256', bytes)\n return Array.from(new Uint8Array(h)).map(b => b.toString(16).padStart(2, '0')).join('')\n}\n\nconst sourcesCache = new Map()\nconst fetchSources = async folderUrl => {\n const url = `${folderUrl}/SOURCES.toml`\n if (sourcesCache.has(url)) return sourcesCache.get(url)\n const p = (async () => {\n try {\n const bytes = await fetchBytes(url)\n const text = new TextDecoder().decode(bytes)\n return parseToml(text)\n } catch (e) {\n return null\n }\n })()\n sourcesCache.set(url, p)\n return p\n}\n\nconst fetchList = async listUrl => {\n const res = await fetch(listUrl, { mode: 'cors' })\n if (!res.ok) throw new Error(`${res.status}`)\n const data = await res.json()\n if (data.error) throw new Error(data.error.code || 'error')\n return data.files || []\n}\n\n// ---- rendering ---------------------------------------------------------------\n\nconst fmtSize = n => (n < 1024 ? `${n} B` : n < 1048576 ? `${(n / 1024).toFixed(1)} KB` : `${(n / 1048576).toFixed(1)} MB`)\n\nconst codeHtml = (text, lang, limit, show) => {\n const lines = text.replace(/\\n$/, '').split('\\n')\n const total = lines.length\n const cut = !show && total > limit\n const shown = cut ? lines.slice(0, limit) : lines\n const nums = shown.map((_, i) => i + 1).join('\\n')\n const more = cut ? `<div class=\"file-more\"><button class=\"file-showall\">Show all ${total} lines</button></div>` : ''\n return `<div class=\"file-code\"><pre class=\"file-lines\">${nums}</pre><pre class=\"file-text\"><code class=\"language-${esc(lang)}\">${esc(shown.join('\\n'))}</code></pre></div>${more}`\n}\n\nconst tomlHtml = text => {\n let sections\n try {\n sections = tomlSections(text)\n } catch (e) {\n return `<div class=\"file-error\">TOML did not parse: ${esc(e.message)}</div>` + codeHtml(text, 'ini', 1e9, true)\n }\n const cell = ([k, v, kind]) =>\n `<tr><td class=\"key\">${esc(k)}</td><td>${kind === 'multiline' ? `<pre>${esc(v)}</pre>` : esc(v)}</td></tr>`\n return sections\n .map(s => `${s.name ? `<div class=\"file-section\">[${esc(s.name)}]</div>` : ''}<table class=\"file-toml\">${s.rows.map(cell).join('')}</table>`)\n .join('')\n}\n\nconst provHtml = (entry, name) => {\n if (!entry) return ''\n const bits = []\n if (entry.source) bits.push(`source ${esc(entry.source)}`)\n if (entry.repo) bits.push(`repo ${esc(entry.repo)}`)\n if (entry.commit) bits.push(`commit ${esc(entry.commit)}`)\n if (entry.snapshot) bits.push(`snapshot ${esc(entry.snapshot)}`)\n if (entry.role) bits.unshift(`<i>${esc(entry.role)}</i>`)\n return `<div class=\"file-prov\">${bits.join(' \u00B7 ')}</div>`\n}\n\nconst highlight = $view => {\n const h = globalThis.hljs\n if (!h || !h.highlightElement) return\n $view.find('code[class^=\"language-\"]').each(function () { h.highlightElement(this) })\n}\n\nconst renderFile = async ($view, ref, ctx, spec) => {\n const { url, folderUrl, name } = resolveFile(ref, ctx)\n $view.html(`<div class=\"file-toolbar\"><span class=\"file-name\">${esc(name)}</span><span>loading\u2026</span></div>`)\n let bytes\n try {\n bytes = await fetchBytes(url)\n } catch (e) {\n $view.html(`<div class=\"file-toolbar\"><span class=\"file-name\">${esc(name)}</span><span class=\"file-error\">could not fetch ${esc(url)} (${esc(e.message)})</span></div>`)\n return\n }\n const sources = await fetchSources(folderUrl)\n const entry = sources && sources[name] ? sources[name] : null\n const kind = kindOf(name)\n const binary = kind === 'image' || kind === 'pdf' || looksBinary(bytes)\n const text = binary ? '' : new TextDecoder().decode(bytes)\n\n let badge = ''\n if (entry && entry.sha256) {\n const digest = await sha256(bytes)\n if (digest) badge = digest === entry.sha256\n ? `<span class=\"file-badge ok\" title=\"sha256 ${esc(digest)}\">matches snapshot</span>`\n : `<span class=\"file-badge drift\" title=\"fetched ${esc(digest)} vs recorded ${esc(entry.sha256)}\">differs from SOURCES.toml</span>`\n }\n\n const blob = new Blob([bytes], { type: binary ? 'application/octet-stream' : 'text/plain;charset=utf-8' })\n const blobUrl = URL.createObjectURL(blob)\n const toolbar = `<div class=\"file-toolbar\">\n <span class=\"file-name\">${esc(name)}</span><span>${fmtSize(bytes.length)}</span>${badge}\n ${binary ? '' : `<a class=\"btn file-raw\" href=\"${blobUrl}\" target=\"_blank\" rel=\"noopener\">Raw</a>`}\n <a class=\"btn\" href=\"${blobUrl}\" download=\"${esc(name)}\">Download</a>\n ${binary ? '' : '<button class=\"file-copy\">Copy</button>'}\n <a class=\"btn\" href=\"${esc(url)}\" target=\"_blank\" rel=\"noopener\" title=\"the asset URL on the site\">URL</a>\n </div>`\n\n let body\n if (kind === 'image') body = `<img src=\"${esc(url)}\" alt=\"${esc(name)}\">`\n else if (kind === 'pdf') body = `<a href=\"${esc(url)}\" target=\"_blank\" rel=\"noopener\">Open ${esc(name)} in a new tab</a>`\n else if (binary) body = `<span class=\"file-role\">binary file, ${fmtSize(bytes.length)}</span>`\n else if (kind === 'markdown') body = '<div class=\"file-md\"></div>'\n else if (kind === 'toml') body = `<div class=\"file-toml-view\">${tomlHtml(text)}</div><div class=\"file-more\"><button class=\"file-rawtoggle\">Show raw</button></div>`\n else if (kind === 'json') {\n let pretty = text\n try { pretty = JSON.stringify(JSON.parse(text), null, 2) } catch (e) { /* keep raw */ }\n body = codeHtml(pretty, 'json', spec.lines, spec.show)\n } else body = codeHtml(text, LANGS[extOf(name)] || 'plaintext', spec.lines, spec.show)\n\n $view.html(`${toolbar}${provHtml(entry, name)}<div class=\"file-body\">${body}</div>`)\n $view.data('file', { text, name, lang: LANGS[extOf(name)] || 'plaintext', spec })\n\n if (kind === 'markdown' && typeof wiki !== 'undefined' && wiki.getPlugin) {\n const $md = $view.find('.file-md')\n wiki.getPlugin('markdown', plugin => {\n try { plugin.emit($md, { type: 'markdown', id: `file-${name}`, text }) } catch (e) { $md.html(codeHtml(text, 'markdown', spec.lines, spec.show)) }\n })\n }\n highlight($view)\n}\n\nconst renderFolder = async ($view, ref, ctx, spec) => {\n const { folderUrl, listUrl, path } = resolveFolder(ref, ctx)\n $view.html(`<div class=\"file-toolbar\"><span class=\"file-name\">${esc(path)}/</span><span>listing\u2026</span></div>`)\n const sources = await fetchSources(folderUrl)\n let files = []\n let note = ''\n try {\n files = await fetchList(listUrl)\n } catch (e) {\n files = sources ? Object.keys(sources).filter(k => sources[k] && typeof sources[k] === 'object') : []\n note = files.length ? ' (from SOURCES.toml; the folder list route is not available on this site)' : ` (no listing: ${esc(e.message)})`\n }\n files = files.filter(f => f !== 'SOURCES.toml').sort()\n if (sources) files.push('SOURCES.toml')\n const rows = files.map(f => {\n const entry = sources && sources[f] && typeof sources[f] === 'object' ? sources[f] : null\n const role = entry && entry.role ? ` <span class=\"file-role\">\u2014 ${esc(entry.role)}</span>` : ''\n return `<li><a class=\"file-open\" data-url=\"${esc(`${folderUrl}/${encodeURIComponent(f)}`)}\">${esc(f)}</a>${role}</li>`\n })\n $view.html(`<div class=\"file-toolbar\"><span class=\"file-name\">${esc(path)}/</span><span>${files.length} file${files.length === 1 ? '' : 's'}${note}</span></div>\n <div class=\"file-body\"><ul class=\"file-list\">${rows.join('') || '<li class=\"file-role\">no files</li>'}</ul><div class=\"file-view file-folder-view\" hidden></div></div>`)\n}\n\n// ---- plugin ------------------------------------------------------------------\n\nexport const emit = ($item, item) => {\n ensureStyle()\n $item.addClass('file-item')\n const spec = parse(item.text)\n const blocks = []\n for (const f of spec.folders) blocks.push(`<div class=\"file-view\" data-folder=\"${esc(f)}\"><div class=\"file-toolbar\"><span>folder\u2026</span></div></div>`)\n for (const f of spec.files) blocks.push(`<div class=\"file-view\" data-file=\"${esc(f)}\"><div class=\"file-toolbar\"><span class=\"file-name\">${esc(f)}</span><span>\u2026</span></div></div>`)\n $item.html(blocks.join(''))\n}\n\nexport const bind = ($item, item) => {\n const spec = parse(item.text)\n const ctx = contextOf($item)\n\n $item.on('dblclick', e => {\n if (e.target && e.target.closest && e.target.closest('.file-toolbar, .file-list, .file-more')) return\n wiki.textEditor($item, item)\n })\n\n $item.on('click', '.file-open', function (e) {\n e.preventDefault(); e.stopPropagation()\n const url = this.dataset.url\n const $folder = $(this).closest('.file-body').find('.file-folder-view')\n $folder.prop('hidden', false)\n renderFile($folder, url, ctx, spec)\n })\n $item.on('click', '.file-showall', function (e) {\n e.preventDefault(); e.stopPropagation()\n const $view = $(this).closest('.file-view')\n const d = $view.data('file')\n if (!d) return\n $view.find('.file-body').html(codeHtml(d.text, d.lang, 1e9, true))\n highlight($view)\n })\n $item.on('click', '.file-rawtoggle', function (e) {\n e.preventDefault(); e.stopPropagation()\n const $view = $(this).closest('.file-view')\n const d = $view.data('file')\n if (!d) return\n const $body = $view.find('.file-body')\n if (this.textContent === 'Show raw') {\n $body.html(codeHtml(d.text, 'ini', 1e9, true) + '<div class=\"file-more\"><button class=\"file-rawtoggle\">Show tables</button></div>')\n highlight($view)\n } else {\n $body.html(`<div class=\"file-toml-view\">${tomlHtml(d.text)}</div><div class=\"file-more\"><button class=\"file-rawtoggle\">Show raw</button></div>`)\n }\n })\n $item.on('click', '.file-copy', function (e) {\n e.preventDefault(); e.stopPropagation()\n const d = $(this).closest('.file-view').data('file')\n if (!d || !navigator.clipboard) return\n navigator.clipboard.writeText(d.text).then(() => { this.textContent = 'Copied'; setTimeout(() => { this.textContent = 'Copy' }, 1500) })\n })\n\n $item.find('.file-view[data-folder]').each(function () {\n renderFolder($(this), this.dataset.folder, ctx, spec)\n })\n $item.find('.file-view[data-file]').each(function () {\n renderFile($(this), this.dataset.file, ctx, spec)\n })\n}\n\nif (typeof window !== 'undefined') {\n window.plugins = window.plugins || {}\n window.plugins.file = { emit, bind }\n}\n"],
|
|
5
|
+
"mappings": "MAcO,IAAMA,EAAQC,GAAQ,CAC3B,IAAMC,EAAO,CAAE,MAAO,CAAC,EAAG,QAAS,CAAC,EAAG,MAAO,GAAe,KAAM,EAAM,EACnEC,EAAQ,OAAOF,GAAQ,EAAE,EAAE,MAAM,OAAO,EAC9C,QAAWG,KAAOD,EAAO,CACvB,IAAME,EAAOD,EAAI,KAAK,EACtB,GAAI,CAACC,EAAM,SACX,IAAMC,EAAID,EAAK,MAAM,0BAA0B,EAC/C,GAAI,CAACC,EAAG,SACR,GAAM,CAAC,CAAEC,EAAKC,EAAM,EAAE,EAAIF,EAC1B,OAAQC,EAAK,CACX,IAAK,OACCC,GAAKN,EAAK,MAAM,KAAKM,EAAI,KAAK,CAAC,EACnC,MACF,IAAK,SACHN,EAAK,QAAQ,KAAKM,EAAI,KAAK,CAAC,EAC5B,MACF,IAAK,QAAS,CACZ,IAAMC,EAAI,SAASD,EAAK,EAAE,EACtBC,EAAI,IAAGP,EAAK,MAAQO,GACxB,KACF,CACA,IAAK,OACHP,EAAK,KAAO,GACZ,MACF,QACE,KACJ,CACF,CACA,MAAI,CAACA,EAAK,MAAM,QAAU,CAACA,EAAK,QAAQ,QAAQA,EAAK,QAAQ,KAAK,EAAE,EAC7DA,CACT,ECvCO,IAAMQ,EAAaC,GAAO,gBAAgB,KAAKA,CAAG,EAEnDC,EAAYC,GAAKA,EAAE,QAAQ,OAAQ,EAAE,EAE9BC,EAAWC,GAAO,CAC7B,IAAMC,EAAI,OAAOD,CAAG,EAAE,MAAM,sBAAsB,EAClD,OAAOC,EAAIA,EAAE,CAAC,EAAI,EACpB,EAGaC,EAAc,CAACN,EAAK,CAAE,KAAAO,EAAM,KAAAC,CAAK,IAAM,CAClD,IAAIJ,EACAL,EAAWC,CAAG,EAAGI,EAAMJ,EAClBA,EAAI,WAAW,UAAU,EAAGI,EAAM,GAAGH,EAAUM,CAAI,CAAC,GAAGP,EAAI,MAAM,CAAgB,CAAC,GAClFA,EAAI,WAAW,SAAS,EAAGI,EAAM,GAAGH,EAAUM,CAAI,CAAC,IAAIP,EAAI,MAAM,CAAgB,CAAC,GACtFI,EAAM,GAAGH,EAAUM,CAAI,CAAC,IAAIC,CAAI,IAAIR,CAAG,GAC5C,IAAMS,EAAML,EAAI,YAAY,GAAG,EAC/B,MAAO,CAAE,IAAAA,EAAK,UAAWA,EAAI,MAAM,EAAGK,CAAG,EAAG,KAAM,mBAAmBL,EAAI,MAAMK,EAAM,CAAC,CAAC,CAAE,CAC3F,EAMaC,EAAgB,CAACV,EAAK,CAAE,KAAAO,EAAM,KAAAC,CAAK,IAAM,CACpD,GAAIT,EAAWC,CAAG,EAAG,CACnB,IAAMW,EAAYV,EAAUD,CAAG,EACzBY,EAAST,EAASQ,CAAS,EAC3BE,EAAOF,EAAU,OAAOC,EAAS,YAAY,MAAM,EACzD,MAAO,CAAE,UAAAD,EAAW,KAAAE,EAAM,QAAS,GAAGD,CAAM,8BAA8B,mBAAmBC,CAAI,CAAC,EAAG,CACvG,CACA,IAAMA,EAAOb,EAAMA,EAAI,QAAQ,eAAgB,EAAE,EAAE,QAAQ,OAAQ,EAAE,EAAIQ,EACnEG,EAAY,GAAGV,EAAUM,CAAI,CAAC,IAAIM,CAAI,GACtCD,EAAST,EAASQ,CAAS,EACjC,MAAO,CAAE,UAAAA,EAAW,KAAAE,EAAM,QAAS,GAAGD,CAAM,8BAA8B,mBAAmBC,CAAI,CAAC,EAAG,CACvG,ECtCA,IAAMC,GAAQ,CACZ,GAAI,WAAY,SAAU,WAC1B,KAAM,OACN,KAAM,OACN,IAAK,QAAS,IAAK,QAAS,KAAM,QAAS,IAAK,QAAS,IAAK,QAAS,KAAM,QAC7E,IAAK,KACP,EAEaC,EAAQ,CACnB,GAAI,SAAU,GAAI,OAAQ,GAAI,OAAQ,KAAM,OAAQ,IAAK,OAAQ,GAAI,aAAc,IAAK,aACxF,GAAI,aAAc,OAAQ,eAAgB,KAAM,OAAQ,IAAK,OAAQ,KAAM,MAAO,IAAK,MAAO,IAAK,MACnG,KAAM,OAAQ,GAAI,WAAY,KAAM,MAAO,IAAK,MAAO,IAAK,YAAa,IAAK,YAAa,IAAK,WAClG,EAEaC,EAAQC,GAAQ,CAC3B,IAAMC,EAAI,OAAOD,CAAI,EAAE,YAAY,EAAE,MAAM,gBAAgB,EAC3D,OAAOC,EAAIA,EAAE,CAAC,EAAI,EACpB,EAEaC,EAASF,GAAQH,GAAME,EAAMC,CAAI,CAAC,GAAK,OAGvCG,EAAcC,GAAS,CAClC,IAAMC,EAAI,KAAK,IAAID,EAAM,OAAQ,IAAI,EACrC,GAAIC,IAAM,EAAG,MAAO,GACpB,IAAIC,EAAM,EACV,QAAS,EAAI,EAAG,EAAID,EAAG,IAAK,CAC1B,IAAME,EAAIH,EAAM,CAAC,EACjB,GAAIG,IAAM,EAAG,MAAO,IAChBA,EAAI,GAAMA,EAAI,IAAMA,EAAI,KAAKD,GACnC,CACA,OAAOA,EAAMD,EAAI,EACnB,ECPA,IAAIG,GAAe,0FACNC,EAAN,MAAMC,UAAiB,IAAK,CAC/BC,GAAW,GACXC,GAAW,GACXC,GAAU,KACV,YAAYC,EAAM,CACd,IAAIC,EAAU,GACVC,EAAU,GACVC,EAAS,IACb,GAAI,OAAOH,GAAS,SAAU,CAC1B,IAAII,EAAQJ,EAAK,MAAMN,EAAY,EAC/BU,GACKA,EAAM,CAAC,IACRH,EAAU,GACVD,EAAO,cAAcA,CAAI,IAE7BE,EAAU,CAAC,CAACE,EAAM,CAAC,EAEnBF,GAAWF,EAAK,EAAE,IAAM,MAAQA,EAAOA,EAAK,QAAQ,IAAK,GAAG,GAExDI,EAAM,CAAC,GAAK,CAACA,EAAM,CAAC,EAAI,GACxBJ,EAAO,IAGPG,EAASC,EAAM,CAAC,GAAK,KACrBJ,EAAOA,EAAK,YAAY,EACpB,CAACG,GAAUD,IACXF,GAAQ,OAIhBA,EAAO,EAEf,CACA,MAAMA,CAAI,EACL,MAAM,KAAK,QAAQ,CAAC,IACrB,KAAKH,GAAWI,EAChB,KAAKH,GAAWI,EAChB,KAAKH,GAAUI,EAEvB,CACA,YAAa,CACT,OAAO,KAAKN,IAAY,KAAKC,EACjC,CACA,SAAU,CACN,MAAO,CAAC,KAAKD,IAAY,CAAC,KAAKC,IAAY,CAAC,KAAKC,EACrD,CACA,QAAS,CACL,OAAO,KAAKF,IAAY,CAAC,KAAKC,EAClC,CACA,QAAS,CACL,OAAO,KAAKA,IAAY,CAAC,KAAKD,EAClC,CACA,SAAU,CACN,OAAO,KAAKA,IAAY,KAAKC,EACjC,CACA,aAAc,CACV,IAAIO,EAAM,MAAM,YAAY,EAE5B,GAAI,KAAK,OAAO,EACZ,OAAOA,EAAI,MAAM,EAAG,EAAE,EAE1B,GAAI,KAAK,OAAO,EACZ,OAAOA,EAAI,MAAM,GAAI,EAAE,EAE3B,GAAI,KAAKN,KAAY,KACjB,OAAOM,EAAI,MAAM,EAAG,EAAE,EAE1B,GAAI,KAAKN,KAAY,IACjB,OAAOM,EAGX,IAAIF,EAAU,CAAE,KAAKJ,GAAQ,MAAM,EAAG,CAAC,EAAK,IAAM,CAAE,KAAKA,GAAQ,MAAM,EAAG,CAAC,EAC3E,OAAAI,EAAS,KAAKJ,GAAQ,CAAC,IAAM,IAAMI,EAAS,CAACA,EAC5B,IAAI,KAAK,KAAK,QAAQ,EAAKA,EAAS,GAAK,EACxC,YAAY,EAAE,MAAM,EAAG,EAAE,EAAI,KAAKJ,EACxD,CACA,OAAO,qBAAqBO,EAAQH,EAAS,IAAK,CAC9C,IAAIH,EAAO,IAAIJ,EAASU,CAAM,EAC9B,OAAAN,EAAKD,GAAUI,EACRH,CACX,CACA,OAAO,oBAAoBM,EAAQ,CAC/B,IAAIN,EAAO,IAAIJ,EAASU,CAAM,EAC9B,OAAAN,EAAKD,GAAU,KACRC,CACX,CACA,OAAO,gBAAgBM,EAAQ,CAC3B,IAAIN,EAAO,IAAIJ,EAASU,CAAM,EAC9B,OAAAN,EAAKF,GAAW,GAChBE,EAAKD,GAAU,KACRC,CACX,CACA,OAAO,gBAAgBM,EAAQ,CAC3B,IAAIN,EAAO,IAAIJ,EAASU,CAAM,EAC9B,OAAAN,EAAKH,GAAW,GAChBG,EAAKD,GAAU,KACRC,CACX,CACJ,ECnGA,SAASO,GAAkBC,EAAQC,EAAK,CACpC,IAAIC,EAAQF,EAAO,MAAM,EAAGC,CAAG,EAAE,MAAM,aAAa,EACpD,MAAO,CAACC,EAAM,OAAQA,EAAM,IAAI,EAAE,OAAS,CAAC,CAChD,CACA,SAASC,GAAcH,EAAQI,EAAMC,EAAQ,CACzC,IAAIH,EAAQF,EAAO,MAAM,aAAa,EAClCM,EAAY,GACZC,GAAa,KAAK,MAAMH,EAAO,CAAC,EAAI,GAAK,EAC7C,QAASI,EAAIJ,EAAO,EAAGI,GAAKJ,EAAO,EAAGI,IAAK,CACvC,IAAI,EAAIN,EAAMM,EAAI,CAAC,EACd,IAELF,GAAaE,EAAE,SAAS,EAAE,OAAOD,EAAW,GAAG,EAC/CD,GAAa,MACbA,GAAa,EACbA,GAAa;AAAA,EACTE,IAAMJ,IACNE,GAAa,IAAI,OAAOC,EAAYF,EAAS,CAAC,EAC9CC,GAAa;AAAA,GAErB,CACA,OAAOA,CACX,CACO,IAAMG,EAAN,cAAwB,KAAM,CACjC,KACA,OACA,UACA,YAAYC,EAASC,EAAS,CAC1B,GAAM,CAACP,EAAMC,CAAM,EAAIN,GAAkBY,EAAQ,KAAMA,EAAQ,GAAG,EAC5DL,EAAYH,GAAcQ,EAAQ,KAAMP,EAAMC,CAAM,EAC1D,MAAM,0BAA0BK,CAAO;AAAA;AAAA,EAAOJ,CAAS,GAAIK,CAAO,EAClE,KAAK,KAAOP,EACZ,KAAK,OAASC,EACd,KAAK,UAAYC,CACrB,CACJ,ECjCO,SAASM,EAAeC,EAAKC,EAAQ,EAAG,CAC3C,IAAIC,EAAMF,EAAI,QAAQ;AAAA,EAAMC,CAAK,EACjC,OAAID,EAAI,WAAWE,EAAM,CAAC,IAAM,IAC5BA,IACGA,CACX,CAEO,SAASC,EAAYC,EAAK,CAC7B,KAAOA,EAAI,EAAIA,EAAI,EAAE,OAAQA,EAAI,IAAK,CAClC,IAAIC,EAAID,EAAI,EAAE,WAAWA,EAAI,CAAC,EAC9B,GAAIC,IAAM,GACN,MACJ,GAAIA,IAAM,IAAgBD,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAM,GAAc,CACpEA,EAAI,IACJ,KACJ,CACA,GAAKC,EAAI,IAAQA,IAAM,GAAiBA,IAAM,IAC1C,MAAM,IAAIC,EAAU,iDAAkD,CAClE,KAAMF,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,CAET,CACJ,CAEO,SAASG,EAASH,EAAKI,EAAaC,EAAa,CACpD,IAAIJ,EACJ,OAAU,CACN,MAAQA,EAAID,EAAI,EAAE,WAAWA,EAAI,CAAC,KAAO,IACrCC,IAAM,GACL,CAACG,IACGH,IAAM,IAAiBA,IAAM,IAAgBD,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAM,KAClFA,EAAI,IACR,GAAIK,GAAeJ,IAAM,GACrB,MACJF,EAAYC,CAAG,CACnB,CACJ,CAEO,SAASM,EAAUN,EAAKO,EAAKC,EAAK,CACrC,IAAIC,EAAMT,EAAI,EACd,GAAI,CAACQ,EAAK,CACNC,EAAMd,EAAeK,EAAI,EAAGS,CAAG,EAC/BT,EAAI,EAAIS,EAAM,EAAIT,EAAI,EAAE,OAASS,EACjC,MACJ,CACA,KAAOT,EAAI,EAAIA,EAAI,EAAE,OAAQA,EAAI,IAAK,CAClC,IAAIC,EAAID,EAAI,EAAE,WAAWA,EAAI,CAAC,EAC9B,GAAIC,IAAM,GACNF,EAAYC,CAAG,UAEVC,IAAMO,GAAOP,IAAMM,EACxB,MAER,CACA,MAAM,IAAIL,EAAU,+BAAgC,CAChD,KAAMF,EAAI,EACV,IAAAS,CACJ,CAAC,CACL,CCzDA,IAAIC,GAAY,+DACZC,GAAc,sDACdC,GAAe,gBAEZ,SAASC,EAAYC,EAAK,CAC7B,IAAIC,EAAQD,EAAI,EACZE,EAAIF,EAAI,EAAE,WAAWA,EAAI,GAAG,EAC5BG,EAAQD,EACRE,EAAYF,IAAM,GAClBG,EAAcH,IAAMF,EAAI,EAAE,WAAWA,EAAI,CAAC,GAAKE,IAAMF,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,EAC/EK,KAEKH,EAAIF,EAAI,EAAE,WAAWA,EAAI,GAAK,CAAC,KAAO,GACvCA,EAAI,IACCE,IAAM,IAAgBF,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAM,KAC3DA,EAAI,GAAK,IAiCjB,IAAIM,EAAS,GACTC,EAAaP,EAAI,EAMjBQ,EAAQ,EACZ,KAAOR,EAAI,EAAIA,EAAI,EAAE,OAAQA,EAAI,IAG7B,GAFAE,EAAIF,EAAI,EAAE,WAAWA,EAAI,CAAC,EAEtBK,IAAgBH,IAAM,IAAiBA,IAAM,IAAgBF,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAM,IAC7FQ,EAAQA,GAAS,MAGhB,IAAKN,EAAI,IAAQA,IAAM,GAAiBA,IAAM,IAC/C,MAAM,IAAIO,EAAU,gDAAiD,CACjE,KAAMT,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,EAIA,IAAK,CAACQ,GAASA,IAAU,IAAMN,IAAMC,IAAU,CAACE,GAAgBL,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAMG,GAASH,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAMG,GAC1I,OAAIE,IAEIL,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAMG,GAChCH,EAAI,IACJA,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,IAAMG,GAChCH,EAAI,KAGPQ,IACDF,GAAUN,EAAI,EAAE,MAAMO,EAAYP,EAAI,CAAC,GAC3CA,EAAI,GAAKK,EAAc,EAAI,EACpBC,EAEN,GAAI,CAACE,EACF,CAACJ,GAAaF,IAAM,KACpBI,GAAUN,EAAI,EAAE,MAAMO,EAAaA,EAAaP,EAAI,CAAE,EACtDQ,EAAQ,WAGPA,IAAU,EACf,GAAIN,IAAM,KAAgBA,IAAM,KAAgBA,IAAM,GAAc,CAChE,IAAIQ,EAAQ,EACRC,EAAMT,IAAM,IAAe,EAAIA,IAAM,IAAe,EAAI,EAC5D,QAASU,EAAI,EAAGA,EAAID,EAAKC,IAAKZ,EAAI,IAAK,CACnC,IAAIa,EAAMb,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,EAChCc,EACMD,GAAO,IAAQA,GAAO,GAAOA,EAAM,GAC/BA,GAAO,IAAQA,GAAO,GAAOA,EAAM,GAAO,GACtCA,GAAO,IAAQA,GAAO,IAAOA,EAAM,GAAO,GAAK,GACjE,GAAIC,EAAQ,EACR,MAAM,IAAIL,EAAU,8CAA+C,CAAE,KAAMT,EAAI,EAAG,IAAKA,EAAI,EAAI,CAAE,CAAC,EACtGU,EAASA,GAAS,EAAKI,CAC3B,CAEA,GAAIJ,EAAQ,GAAKA,EAAQ,SAAaA,GAAS,OAAUA,GAAS,MAC9D,MAAM,IAAID,EAAU,yBAA0B,CAAE,KAAMT,EAAI,EAAG,IAAKA,EAAI,CAAE,CAAC,EAE7EM,GAAU,OAAO,cAAcI,CAAK,EACpCH,EAAaP,EAAI,EAAI,EACrBQ,EAAQ,CACZ,SACSN,IAAM,IAAQA,IAAM,EACzBM,EAAQ,MAEP,CACD,GAAIN,IAAM,GACNI,GAAU,aACLJ,IAAM,IACXI,GAAU,YACLJ,IAAM,IACXI,GAAU;AAAA,UACLJ,IAAM,IACXI,GAAU,aACLJ,IAAM,IACXI,GAAU,aACLJ,IAAM,IACXI,GAAU,eACLJ,IAAM,GACXI,GAAU,YACLJ,IAAM,GACXI,GAAU,SAEV,OAAM,IAAIG,EAAU,+BAAgC,CAAE,KAAMT,EAAI,EAAG,IAAKA,EAAI,CAAE,CAAC,EACnFO,EAAaP,EAAI,EAAI,EACrBQ,EAAQ,CACZ,SAEKN,IAAM,IAAQA,IAAM,EAAc,CACvC,GAAIM,IAAU,EACV,MAAM,IAAIC,EAAU,6DAA8D,CAC9E,KAAMT,EAAI,EACV,IAAKO,CACT,CAAC,EAILC,EAAQ,CAACJ,GAAaF,IAAM,GAAe,EAAI,EAC/CK,EAAaP,EAAI,CACrB,EAEJ,MAAM,IAAIS,EAAU,oBAAqB,CAAE,KAAMT,EAAI,EAAG,IAAKC,CAAM,CAAC,CACxE,CACA,SAASc,GAAkBf,EAAKC,EAAOe,EAAK,CACxC,IAAIN,EAAQV,EAAI,EAAE,MAAMC,EAAOe,CAAG,EAC9BC,EAAaP,EAAM,QAAQ,GAAG,EAClC,OAAIO,EAAa,IAGbC,EAAY,CAAE,EAAGR,EAAO,EAAGO,EAAY,EAAG,CAAE,CAAC,EAC7CP,EAAQA,EAAM,MAAM,EAAGO,CAAU,GAE9BP,EAAM,QAAQ,CACzB,CAEO,SAASS,EAAWnB,EAAKoB,EAAkBJ,EAAK,CACnD,IAAIK,EAAMrB,EAAI,EACVsB,EAAM,CAAE,KAAMtB,EAAI,EAAG,IAAAqB,CAAI,EAC7BE,EAAUvB,EAAK,GAAcgB,CAAG,EAChC,IAAIN,EAAQK,GAAkBf,EAAKqB,EAAKrB,EAAI,CAAC,EAC7C,GAAI,CAACU,EACD,MAAM,IAAID,EAAU,yCAA0Ca,CAAG,EACrE,GAAIZ,IAAU,OACV,MAAO,KACX,GAAIA,IAAU,OAASA,IAAU,OAC7B,MAAO,KACX,GAAIA,IAAU,OAASA,IAAU,QAAUA,IAAU,OACjD,MAAO,KAEX,GAAIA,IAAU,KACV,OAAOU,EAAmB,GAAK,EAEnC,IAAII,EAAQ5B,GAAU,KAAKc,CAAK,EAChC,GAAIc,GAAS3B,GAAY,KAAKa,CAAK,EAAG,CAClC,GAAIZ,GAAa,KAAKY,CAAK,EACvB,MAAM,IAAID,EAAU,iCAAkCa,CAAG,EAE7DZ,EAAQA,EAAM,QAAQ,KAAM,EAAE,EAC9B,IAAIe,EAAU,CAACf,EACf,GAAI,MAAMe,CAAO,EACb,MAAM,IAAIhB,EAAU,iBAAkBa,CAAG,EAE7C,GAAIE,EAAO,CACP,IAAKA,EAAQ,CAAC,OAAO,cAAcC,CAAO,IAAM,CAACL,EAC7C,MAAM,IAAIX,EAAU,iDAAkDa,CAAG,GAEzEE,GAASJ,IAAqB,MAC9BK,EAAU,OAAOf,CAAK,EAC9B,CACA,OAAOe,CACX,CACA,IAAMC,EAAO,IAAIC,EAASjB,CAAK,EAC/B,GAAI,CAACgB,EAAK,QAAQ,EACd,MAAM,IAAIjB,EAAU,gBAAiBa,CAAG,EAC5C,OAAOI,CACX,CC9MO,SAASE,EAAaC,EAAKC,EAAKC,EAAkB,CACrD,IAAIC,EAAMH,EAAI,EACVI,EAAIJ,EAAI,EAAE,WAAWG,CAAG,EAE5B,GAAIC,IAAM,IAAgBA,IAAM,IAAc,CAC1C,GAAI,CAACJ,EAAI,IACL,MAAM,IAAIK,EAAU,6DAA8D,CAC9E,KAAML,EAAI,EACV,IAAAG,CACJ,CAAC,EAEL,IAAIG,EAAQF,IAAM,GACZG,EAAWP,EAAKE,CAAgB,EAChCM,EAAiBR,EAAKE,CAAgB,EAC5C,OAAAF,EAAI,IACGM,CACX,CAEA,GAAIF,IAAM,IAAgBA,IAAM,GAC5B,OAAOK,EAAYT,CAAG,EAI1B,GAAII,IAAM,IAAc,CACpB,GAAIJ,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,KAAQA,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,KAAQA,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,IAC1G,MAAM,IAAIK,EAAU,gBAAiB,CAAE,KAAML,EAAI,EAAG,IAAAG,CAAI,CAAC,EAC7D,OAAAH,EAAI,IACG,EACX,CACA,GAAII,IAAM,IAAc,CACpB,GAAIJ,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,IAAQA,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,KAAQA,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,KAAQA,EAAI,EAAE,WAAW,EAAEA,EAAI,CAAC,IAAM,IAChJ,MAAM,IAAIK,EAAU,gBAAiB,CAAE,KAAML,EAAI,EAAG,IAAAG,CAAI,CAAC,EAC7D,OAAAH,EAAI,IACG,EACX,CAEA,OAAOU,EAAWV,EAAKE,EAAkBD,CAAG,CAChD,CCrCA,IAAIU,GAAc,yBAEX,SAASC,EAASC,EAAKC,EAAM,IAAK,CACrC,IAAIC,EAAQF,EAAI,EACZG,EAAMD,EAAQ,EACdE,EAAS,CAAC,EACVC,EAASL,EAAI,EAAE,QAAQC,EAAKC,CAAK,EACrC,GAAIG,EAAS,EACT,MAAM,IAAIC,EAAU,+CAAgD,CAChE,KAAMN,EAAI,EACV,IAAKE,CACT,CAAC,EAEL,EAAG,CACC,IAAIK,EAAIP,EAAI,EAAE,WAAWA,EAAI,EAAI,EAAEG,CAAG,EAEtC,GAAII,IAAM,IAAQA,IAAM,EAEpB,GAAIA,IAAM,IAAgBA,IAAM,GAAc,CAC1C,GAAIA,IAAMP,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,GAAKO,IAAMP,EAAI,EAAE,WAAWA,EAAI,EAAI,CAAC,EACrE,MAAM,IAAIM,EAAU,4CAA6C,CAC7D,KAAMN,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,EAEL,IAAIQ,EAAOC,EAAYT,CAAG,EAC1BG,EAAMH,EAAI,EAAE,QAAQ,IAAKA,EAAI,CAAC,EAC9B,IAAIU,EAASV,EAAI,EAAE,MAAMA,EAAI,EAAGG,EAAM,GAAKA,EAAME,EAASA,EAASF,CAAG,EAClEQ,EAAUC,EAAeF,CAAM,EACnC,GAAIC,EAAU,GACV,MAAM,IAAIL,EAAU,mCAAoC,CACpD,KAAMN,EAAI,EACV,IAAKW,CACT,CAAC,EAEL,GAAID,EAAO,UAAU,EACjB,MAAM,IAAIJ,EAAU,2CAA4C,CAC5D,KAAMN,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,EAEL,GAAIK,EAASL,EAAI,IACbK,EAASL,EAAI,EAAE,QAAQC,EAAKD,EAAI,CAAC,EAC7BK,EAAS,GACT,MAAM,IAAIC,EAAU,+CAAgD,CAChE,KAAMN,EAAI,EACV,IAAKE,CACT,CAAC,EAGTE,EAAO,KAAKI,CAAI,CACpB,KACK,CAEDL,EAAMH,EAAI,EAAE,QAAQ,IAAKA,EAAI,CAAC,EAC9B,IAAIQ,EAAOR,EAAI,EAAE,MAAMA,EAAI,EAAGG,EAAM,GAAKA,EAAME,EAASA,EAASF,CAAG,EACpE,GAAI,CAACL,GAAY,KAAKU,CAAI,EACtB,MAAM,IAAIF,EAAU,mEAAoE,CACpF,KAAMN,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,EAELI,EAAO,KAAKI,EAAK,QAAQ,CAAC,CAC9B,CAGR,OAASL,EAAM,GAAKA,EAAME,GAC1B,OAAAL,EAAI,EAAIK,EAAS,EACjBQ,EAASb,EAAK,GAAM,EAAI,EACjBI,CACX,CAEO,SAASU,EAAiBd,EAAKe,EAAkB,CACpD,IAAIC,EAAM,CAAC,EACPC,EAAO,IAAI,IACXV,EAEJ,IADAP,EAAI,IACGA,EAAI,EAAIA,EAAI,EAAE,QAAQ,CAEzB,GADAa,EAASb,CAAG,GACPO,EAAIP,EAAI,EAAE,WAAWA,EAAI,CAAC,KAAO,IAClC,OAAAA,EAAI,IACGgB,EAEX,IAAIE,EACAC,EAAIH,EACJI,EAAS,GACTC,EAAIrB,EAAI,EACRsB,EAAMvB,EAASC,CAAG,EACtB,QAASuB,EAAI,EAAGA,EAAID,EAAI,OAAQC,IAAK,CAIjC,GAHIA,IACAJ,EAAIC,EAASD,EAAED,CAAC,EAAKC,EAAED,CAAC,EAAI,CAAC,GACjCA,EAAII,EAAIC,CAAC,GACJH,EAAS,OAAO,OAAOD,EAAGD,CAAC,KAAO,OAAOC,EAAED,CAAC,GAAM,UAAYD,EAAK,IAAIE,EAAED,CAAC,CAAC,GAC5E,MAAM,IAAIZ,EAAU,8CAA+C,CAC/D,KAAMN,EAAI,EACV,IAAKqB,CACT,CAAC,EAED,CAACD,GAAUF,IAAM,aACjB,OAAO,eAAeC,EAAGD,EAAG,CAAE,WAAY,GAAM,aAAc,GAAM,SAAU,EAAK,CAAC,CAE5F,CACA,GAAIE,EACA,MAAM,IAAId,EAAU,8CAA+C,CAC/D,KAAMN,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,EAEL,IAAIwB,EAAQC,EAAazB,EAAK,IAAce,CAAgB,EAG5D,GAFAE,EAAK,IAAIE,EAAED,CAAC,EAAIM,CAAK,EACrBX,EAASb,CAAG,GACPO,EAAIP,EAAI,EAAE,WAAWA,EAAI,GAAG,KAAO,IACpC,OAAOgB,EAEX,GAAIT,IAAM,GACN,MAAM,IAAID,EAAU,qCAAsC,CAAE,KAAMN,EAAI,EAAG,IAAKA,EAAI,EAAI,CAAE,CAAC,CAEjG,CACA,MAAM,IAAIM,EAAU,+BAAgC,CAChD,KAAMN,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,CACL,CAEO,SAAS0B,EAAW1B,EAAKe,EAAkB,CAC9C,IAAIC,EAAM,CAAC,EACPT,EAEJ,IADAP,EAAI,IACGA,EAAI,EAAIA,EAAI,EAAE,QAAQ,CAEzB,GADAa,EAASb,CAAG,GACPO,EAAIP,EAAI,EAAE,WAAWA,EAAI,CAAC,KAAO,GAClC,OAAAA,EAAI,IACGgB,EAIX,GAFAA,EAAI,KAAKS,EAAazB,EAAK,GAAce,CAAgB,CAAC,EAC1DF,EAASb,CAAG,GACPO,EAAIP,EAAI,EAAE,WAAWA,EAAI,GAAG,KAAO,GACpC,OAAOgB,EAEX,GAAIT,IAAM,GACN,MAAM,IAAID,EAAU,qCAAsC,CAAE,KAAMN,EAAI,EAAG,IAAKA,EAAI,EAAI,CAAE,CAAC,CAEjG,CACA,MAAM,IAAIM,EAAU,+BAAgC,CAChD,KAAMN,EAAI,EACV,IAAKA,EAAI,CACb,CAAC,CACL,CCnJA,SAAS2B,EAAUC,EAAKC,EAAOC,EAAMC,EAAM,CACvC,IAAIC,EAAIH,EACJI,EAAIH,EACJI,EACAC,EAAS,GACTC,EACJ,QAASC,EAAI,EAAGA,EAAIT,EAAI,OAAQS,IAAK,CACjC,GAAIA,EAAG,CAGH,GAFAL,EAAIG,EAASH,EAAEE,CAAC,EAAKF,EAAEE,CAAC,EAAI,CAAC,EAC7BD,GAAKG,EAAQH,EAAEC,CAAC,GAAG,EACfH,IAAS,IAAwBK,EAAM,IAAM,GAAyBA,EAAM,IAAM,GAClF,OAAO,KAEX,GAAIA,EAAM,IAAM,EAAoB,CAChC,IAAIE,EAAIN,EAAE,OAAS,EACnBA,EAAIA,EAAEM,CAAC,EACPL,EAAIA,EAAEK,CAAC,EAAE,CACb,CACJ,CAEA,GADAJ,EAAIN,EAAIS,CAAC,GACJF,EAAS,OAAO,OAAOH,EAAGE,CAAC,IAAMD,EAAEC,CAAC,GAAG,IAAM,GAAuBD,EAAEC,CAAC,GAAG,EAC3E,OAAO,KAENC,IACGD,IAAM,cACN,OAAO,eAAeF,EAAGE,EAAG,CAAE,WAAY,GAAM,aAAc,GAAM,SAAU,EAAK,CAAC,EACpF,OAAO,eAAeD,EAAGC,EAAG,CAAE,WAAY,GAAM,aAAc,GAAM,SAAU,EAAK,CAAC,GAExFD,EAAEC,CAAC,EAAI,CACH,EAAGG,EAAIT,EAAI,OAAS,GAAKG,IAAS,EAC5B,EAA4BA,EAClC,EAAG,GACH,EAAG,EACH,EAAG,CAAC,CACR,EAER,CAcA,GAbAK,EAAQH,EAAEC,CAAC,EACPE,EAAM,IAAML,GAAQ,EAAEA,IAAS,GAAyBK,EAAM,IAAM,KAIpEL,IAAS,IACJK,EAAM,IACPA,EAAM,EAAI,GACVJ,EAAEE,CAAC,EAAI,CAAC,GAEZF,EAAEE,CAAC,EAAE,KAAKF,EAAI,CAAC,CAAC,EAChBI,EAAM,EAAEA,EAAM,GAAG,EAAKA,EAAQ,CAAE,EAAG,EAAuB,EAAG,GAAO,EAAG,EAAG,EAAG,CAAC,CAAE,GAEhFA,EAAM,GAEN,OAAO,KAGX,GADAA,EAAM,EAAI,GACNL,IAAS,EACTC,EAAIG,EAASH,EAAEE,CAAC,EAAKF,EAAEE,CAAC,EAAI,CAAC,UAExBH,IAAS,GAAuBI,EACrC,OAAO,KAEX,MAAO,CAACD,EAAGF,EAAGI,EAAM,CAAC,CACzB,CACO,SAASG,EAAMC,EAAM,CAAE,SAAAC,EAAW,IAAM,iBAAAC,CAAiB,EAAI,CAAC,EAAG,CACpE,IAAIC,EAAM,CAAE,EAAGH,EAAM,EAAG,EAAG,EAAGC,CAAS,EACnCG,EAAM,CAAC,EACPd,EAAO,CAAC,EACRe,EACAC,EAAMF,EACNX,EAAIH,EAER,IADAiB,EAASJ,CAAG,EACLA,EAAI,EAAIH,EAAK,QAAQ,CACxB,GAAIA,EAAK,WAAWG,EAAI,CAAC,IAAM,GAAc,CACzC,IAAIK,EAAeR,EAAK,WAAW,EAAEG,EAAI,CAAC,IAAM,GAChDE,EAAMF,EAAI,GAAK,CAACK,EAChB,IAAId,EAAIe,EAASN,EAAK,GAAG,EACzB,GAAIK,EAAc,CACd,GAAIR,EAAK,WAAWG,EAAI,EAAI,CAAC,IAAM,GAC/B,MAAM,IAAIO,EAAU,oCAAqC,CACrD,KAAMV,EACN,IAAKG,EAAI,EAAI,CACjB,CAAC,EAELA,EAAI,GACR,CACA,IAAIQ,EAAIxB,EAAUO,EAAGU,EAAKd,EAAMkB,EAAe,EAAqB,CAAqB,EACzF,GAAI,CAACG,EACD,MAAM,IAAID,EAAU,uDAAwD,CACxE,KAAMV,EACN,IAAKK,CACT,CAAC,EAELZ,EAAIkB,EAAE,CAAC,EACPL,EAAMK,EAAE,CAAC,CACb,KACK,CACDN,EAAMF,EAAI,EACV,IAAIT,EAAIe,EAASN,CAAG,EAChBQ,EAAIxB,EAAUO,EAAGY,EAAKb,EAAG,CAAmB,EAChD,GAAI,CAACkB,EACD,MAAM,IAAID,EAAU,uDAAwD,CACxE,KAAMV,EACN,IAAKK,CACT,CAAC,EAELM,EAAE,CAAC,EAAEA,EAAE,CAAC,CAAC,EAAIC,EAAaT,EAAK,OAAQD,CAAgB,CAC3D,CAEA,GADAK,EAASJ,EAAK,EAAI,EACdA,EAAI,EAAIH,EAAK,SAAWK,EAAML,EAAK,WAAWG,EAAI,CAAC,KAAO,IAAgBE,IAAQ,GAClF,MAAM,IAAIK,EAAU,gEAAiE,CACjF,KAAMV,EACN,IAAKG,EAAI,CACb,CAAC,EAELI,EAASJ,CAAG,CAChB,CACA,OAAOC,CACX,CC5IA,IAAMS,EAAUC,GAAKA,GAAK,OAAOA,GAAM,UAAY,CAAC,MAAM,QAAQA,CAAC,GAAK,EAAEA,aAAa,MAEjFC,EAASD,GACT,OAAOA,GAAM,SAAiBA,EAAE,SAAS;AAAA,CAAI,EAAI,YAAc,SAC/D,MAAM,QAAQA,CAAC,EAAU,QACzBA,aAAa,KAAa,OACvB,OAAOA,EAGVE,EAAOF,GACP,OAAOA,GAAM,SAAiBA,EAC9BA,aAAa,KAAaA,EAAE,YAAY,EACxC,MAAM,QAAQA,CAAC,EAAUA,EAAE,IAAIG,GAAMJ,EAAQI,CAAC,EAAI,KAAK,UAAUA,CAAC,EAAID,EAAKC,CAAC,CAAE,EAAE,KAAK,IAAI,EACtF,OAAOH,CAAC,EAGXI,EAAS,CAACC,EAAKC,EAAQC,EAAMC,IAAa,CAC9C,OAAW,CAACC,EAAGT,CAAC,IAAK,OAAO,QAAQK,CAAG,EAAG,CACxC,IAAMK,EAAMJ,EAAS,GAAGA,CAAM,IAAIG,CAAC,GAAKA,EACpCV,EAAQC,CAAC,EAAGI,EAAOJ,EAAGU,EAAKH,EAAMC,CAAQ,EACpC,MAAM,QAAQR,CAAC,GAAKA,EAAE,QAAUA,EAAE,MAAMD,CAAO,EACtDC,EAAE,QAAQ,CAACW,EAAGC,IAAM,CAClB,IAAMC,EAAK,CAAC,EACZT,EAAOO,EAAG,GAAIE,EAAIL,CAAQ,EAC1BA,EAAS,KAAK,CAAE,KAAM,GAAGE,CAAG,IAAIE,CAAC,IAAK,KAAMC,CAAG,CAAC,CAClD,CAAC,EACIN,EAAK,KAAK,CAACG,EAAKR,EAAKF,CAAC,EAAGC,EAAOD,CAAC,CAAC,CAAC,CAC5C,CACF,EAEac,GAAaC,GAAO,CAC/B,IAAMP,EAAW,CAAC,EACZQ,EAAO,CAAC,EACd,OAAW,CAACP,EAAGT,CAAC,IAAK,OAAO,QAAQe,CAAG,EACrC,GAAIhB,EAAQC,CAAC,EAAG,CACd,IAAMO,EAAO,CAAC,EACRU,EAAS,CAAC,EAChBb,EAAOJ,EAAG,GAAIO,EAAMU,CAAM,EAC1BT,EAAS,KAAK,CAAE,KAAMC,EAAG,KAAAF,CAAK,CAAC,EAC/B,QAAWW,KAAKD,EAAQT,EAAS,KAAK,CAAE,GAAGU,EAAG,KAAM,GAAGT,CAAC,IAAIS,EAAE,IAAI,EAAG,CAAC,CACxE,MAAW,MAAM,QAAQlB,CAAC,GAAKA,EAAE,QAAUA,EAAE,MAAMD,CAAO,EACxDC,EAAE,QAAQ,CAACW,EAAGC,IAAM,CAClB,IAAML,EAAO,CAAC,EAEdH,EAAOO,EAAG,GAAIJ,EADC,CAAC,CACU,EAC1BC,EAAS,KAAK,CAAE,KAAM,GAAGC,CAAC,IAAIG,CAAC,IAAK,KAAAL,CAAK,CAAC,CAC5C,CAAC,EACIS,EAAK,KAAK,CAACP,EAAGP,EAAKF,CAAC,EAAGC,EAAOD,CAAC,CAAC,CAAC,EAE1C,OAAIgB,EAAK,QAAQR,EAAS,QAAQ,CAAE,KAAM,GAAI,KAAMQ,CAAK,CAAC,EACnDR,CACT,EAEaW,EAAeC,GAAQN,GAAWO,EAAUD,CAAI,CAAC,EC9C9D,IAAME,EAAMC,GAAK,OAAOA,CAAC,EAAE,QAAQ,KAAM,OAAO,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,QAAQ,EAE9GC,GAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BNC,GAAc,IAAM,CACxB,GAAI,OAAO,SAAa,KAAe,SAAS,eAAe,wBAAwB,EAAG,OAC1F,IAAMF,EAAI,SAAS,cAAc,OAAO,EACxCA,EAAE,GAAK,yBACPA,EAAE,YAAcC,GAChB,SAAS,KAAK,YAAYD,CAAC,CAC7B,EAIMG,GAASC,GAASA,EAAM,QAAQ,OAAO,EACvCC,GAASD,GAASD,GAAOC,CAAK,EAAE,CAAC,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC,EACrDE,GAASF,GAASD,GAAOC,CAAK,EAAE,KAAK,MAAM,GAAK,KAEhDG,GAAYH,GAAS,CACzB,IAAMI,EAAOF,GAAOF,CAAK,EACnBK,EAAI,OAAO,KAAS,IAAc,KAAO,KAE/C,MAAO,CAAE,KADIA,GAAKA,EAAE,KAAOA,EAAE,KAAKD,CAAI,EAAE,aAAa,QAAQ,EAAI,UAClD,KAAMH,GAAOD,CAAK,EAAG,KAAAI,CAAK,CAC3C,EAIME,GAAa,MAAMC,GAAO,CAC9B,IAAMC,EAAM,MAAM,MAAMD,EAAK,CAAE,KAAM,MAAO,CAAC,EAC7C,GAAI,CAACC,EAAI,GAAI,MAAM,IAAI,MAAM,GAAGA,EAAI,MAAM,IAAIA,EAAI,UAAU,EAAE,EAC9D,IAAMC,EAAM,MAAMD,EAAI,YAAY,EAClC,OAAO,IAAI,WAAWC,CAAG,CAC3B,EAEMC,GAAS,MAAMC,GAAS,CAC5B,GAAI,EAAE,WAAW,QAAU,OAAO,QAAS,MAAO,GAClD,IAAMC,EAAI,MAAM,OAAO,OAAO,OAAO,UAAWD,CAAK,EACrD,OAAO,MAAM,KAAK,IAAI,WAAWC,CAAC,CAAC,EAAE,IAAIC,GAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CACxF,EAEMC,EAAe,IAAI,IACnBC,GAAe,MAAMC,GAAa,CACtC,IAAMT,EAAM,GAAGS,CAAS,gBACxB,GAAIF,EAAa,IAAIP,CAAG,EAAG,OAAOO,EAAa,IAAIP,CAAG,EACtD,IAAMU,GAAK,SAAY,CACrB,GAAI,CACF,IAAMN,EAAQ,MAAML,GAAWC,CAAG,EAC5BW,EAAO,IAAI,YAAY,EAAE,OAAOP,CAAK,EAC3C,OAAOQ,EAAUD,CAAI,CACvB,MAAY,CACV,OAAO,IACT,CACF,GAAG,EACH,OAAAJ,EAAa,IAAIP,EAAKU,CAAC,EAChBA,CACT,EAEMG,GAAY,MAAMC,GAAW,CACjC,IAAMb,EAAM,MAAM,MAAMa,EAAS,CAAE,KAAM,MAAO,CAAC,EACjD,GAAI,CAACb,EAAI,GAAI,MAAM,IAAI,MAAM,GAAGA,EAAI,MAAM,EAAE,EAC5C,IAAMc,EAAO,MAAMd,EAAI,KAAK,EAC5B,GAAIc,EAAK,MAAO,MAAM,IAAI,MAAMA,EAAK,MAAM,MAAQ,OAAO,EAC1D,OAAOA,EAAK,OAAS,CAAC,CACxB,EAIMC,EAAUC,GAAMA,EAAI,KAAO,GAAGA,CAAC,KAAOA,EAAI,QAAU,IAAIA,EAAI,MAAM,QAAQ,CAAC,CAAC,MAAQ,IAAIA,EAAI,SAAS,QAAQ,CAAC,CAAC,MAE/GC,EAAW,CAACP,EAAMQ,EAAMC,EAAOC,IAAS,CAC5C,IAAMC,EAAQX,EAAK,QAAQ,MAAO,EAAE,EAAE,MAAM;AAAA,CAAI,EAC1CY,EAAQD,EAAM,OACdE,EAAM,CAACH,GAAQE,EAAQH,EACvBK,EAAQD,EAAMF,EAAM,MAAM,EAAGF,CAAK,EAAIE,EACtCI,EAAOD,EAAM,IAAI,CAACE,EAAGC,IAAMA,EAAI,CAAC,EAAE,KAAK;AAAA,CAAI,EAC3CC,EAAOL,EAAM,gEAAgED,CAAK,wBAA0B,GAClH,MAAO,kDAAkDG,CAAI,sDAAsDtC,EAAI+B,CAAI,CAAC,KAAK/B,EAAIqC,EAAM,KAAK;AAAA,CAAI,CAAC,CAAC,sBAAsBI,CAAI,EAClL,EAEMC,GAAWnB,GAAQ,CACvB,IAAIoB,EACJ,GAAI,CACFA,EAAWC,EAAarB,CAAI,CAC9B,OAASsB,EAAG,CACV,MAAO,+CAA+C7C,EAAI6C,EAAE,OAAO,CAAC,SAAWf,EAASP,EAAM,MAAO,IAAK,EAAI,CAChH,CACA,IAAMuB,EAAO,CAAC,CAACC,EAAGC,EAAGC,CAAI,IACvB,uBAAuBjD,EAAI+C,CAAC,CAAC,YAAYE,IAAS,YAAc,QAAQjD,EAAIgD,CAAC,CAAC,SAAWhD,EAAIgD,CAAC,CAAC,aACjG,OAAOL,EACJ,IAAI1C,GAAK,GAAGA,EAAE,KAAO,8BAA8BD,EAAIC,EAAE,IAAI,CAAC,UAAY,EAAE,4BAA4BA,EAAE,KAAK,IAAI6C,CAAI,EAAE,KAAK,EAAE,CAAC,UAAU,EAC3I,KAAK,EAAE,CACZ,EAEMI,GAAW,CAACC,EAAOC,IAAS,CAChC,GAAI,CAACD,EAAO,MAAO,GACnB,IAAME,EAAO,CAAC,EACd,OAAIF,EAAM,QAAQE,EAAK,KAAK,UAAUrD,EAAImD,EAAM,MAAM,CAAC,EAAE,EACrDA,EAAM,MAAME,EAAK,KAAK,QAAQrD,EAAImD,EAAM,IAAI,CAAC,EAAE,EAC/CA,EAAM,QAAQE,EAAK,KAAK,UAAUrD,EAAImD,EAAM,MAAM,CAAC,EAAE,EACrDA,EAAM,UAAUE,EAAK,KAAK,YAAYrD,EAAImD,EAAM,QAAQ,CAAC,EAAE,EAC3DA,EAAM,MAAME,EAAK,QAAQ,MAAMrD,EAAImD,EAAM,IAAI,CAAC,MAAM,EACjD,0BAA0BE,EAAK,KAAK,QAAK,CAAC,QACnD,EAEMC,EAAYC,GAAS,CACzB,IAAMtC,EAAI,WAAW,KACjB,CAACA,GAAK,CAACA,EAAE,kBACbsC,EAAM,KAAK,0BAA0B,EAAE,KAAK,UAAY,CAAEtC,EAAE,iBAAiB,IAAI,CAAE,CAAC,CACtF,EAEMuC,EAAa,MAAOD,EAAOE,EAAKC,EAAKC,IAAS,CAClD,GAAM,CAAE,IAAA/C,EAAK,UAAAS,EAAW,KAAA+B,CAAK,EAAIQ,EAAYH,EAAKC,CAAG,EACrDH,EAAM,KAAK,qDAAqDvD,EAAIoD,CAAI,CAAC,yCAAoC,EAC7G,IAAIpC,EACJ,GAAI,CACFA,EAAQ,MAAML,GAAWC,CAAG,CAC9B,OAASiC,EAAG,CACVU,EAAM,KAAK,qDAAqDvD,EAAIoD,CAAI,CAAC,mDAAmDpD,EAAIY,CAAG,CAAC,KAAKZ,EAAI6C,EAAE,OAAO,CAAC,gBAAgB,EACvK,MACF,CACA,IAAMgB,EAAU,MAAMzC,GAAaC,CAAS,EACtC8B,EAAQU,GAAWA,EAAQT,CAAI,EAAIS,EAAQT,CAAI,EAAI,KACnDH,EAAOa,EAAOV,CAAI,EAClBW,EAASd,IAAS,SAAWA,IAAS,OAASe,EAAYhD,CAAK,EAChEO,EAAOwC,EAAS,GAAK,IAAI,YAAY,EAAE,OAAO/C,CAAK,EAErDiD,EAAQ,GACZ,GAAId,GAASA,EAAM,OAAQ,CACzB,IAAMe,EAAS,MAAMnD,GAAOC,CAAK,EAC7BkD,IAAQD,EAAQC,IAAWf,EAAM,OACjC,6CAA6CnD,EAAIkE,CAAM,CAAC,4BACxD,iDAAiDlE,EAAIkE,CAAM,CAAC,gBAAgBlE,EAAImD,EAAM,MAAM,CAAC,qCACnG,CAEA,IAAMgB,GAAO,IAAI,KAAK,CAACnD,CAAK,EAAG,CAAE,KAAM+C,EAAS,2BAA6B,0BAA2B,CAAC,EACnGK,EAAU,IAAI,gBAAgBD,EAAI,EAClCE,GAAU;AAAA,8BACYrE,EAAIoD,CAAI,CAAC,gBAAgBxB,EAAQZ,EAAM,MAAM,CAAC,UAAUiD,CAAK;AAAA,MACrFF,EAAS,GAAK,iCAAiCK,CAAO,0CAA0C;AAAA,2BAC3EA,CAAO,eAAepE,EAAIoD,CAAI,CAAC;AAAA,MACpDW,EAAS,GAAK,yCAAyC;AAAA,2BAClC/D,EAAIY,CAAG,CAAC;AAAA,UAG7B0D,EACJ,GAAIrB,IAAS,QAASqB,EAAO,aAAatE,EAAIY,CAAG,CAAC,UAAUZ,EAAIoD,CAAI,CAAC,aAC5DH,IAAS,MAAOqB,EAAO,YAAYtE,EAAIY,CAAG,CAAC,yCAAyCZ,EAAIoD,CAAI,CAAC,4BAC7FW,EAAQO,EAAO,wCAAwC1C,EAAQZ,EAAM,MAAM,CAAC,kBAC5EiC,IAAS,WAAYqB,EAAO,sCAC5BrB,IAAS,OAAQqB,EAAO,+BAA+B5B,GAASnB,CAAI,CAAC,8FACrE0B,IAAS,OAAQ,CACxB,IAAIsB,EAAShD,EACb,GAAI,CAAEgD,EAAS,KAAK,UAAU,KAAK,MAAMhD,CAAI,EAAG,KAAM,CAAC,CAAE,MAAY,CAAiB,CACtF+C,EAAOxC,EAASyC,EAAQ,OAAQZ,EAAK,MAAOA,EAAK,IAAI,CACvD,MAAOW,EAAOxC,EAASP,EAAMiD,EAAMC,EAAMrB,CAAI,CAAC,GAAK,YAAaO,EAAK,MAAOA,EAAK,IAAI,EAKrF,GAHAJ,EAAM,KAAK,GAAGc,EAAO,GAAGnB,GAASC,EAAOC,CAAI,CAAC,0BAA0BkB,CAAI,QAAQ,EACnFf,EAAM,KAAK,OAAQ,CAAE,KAAAhC,EAAM,KAAA6B,EAAM,KAAMoB,EAAMC,EAAMrB,CAAI,CAAC,GAAK,YAAa,KAAAO,CAAK,CAAC,EAE5EV,IAAS,YAAc,OAAO,KAAS,KAAe,KAAK,UAAW,CACxE,IAAMyB,EAAMnB,EAAM,KAAK,UAAU,EACjC,KAAK,UAAU,WAAYoB,GAAU,CACnC,GAAI,CAAEA,EAAO,KAAKD,EAAK,CAAE,KAAM,WAAY,GAAI,QAAQtB,CAAI,GAAI,KAAA7B,CAAK,CAAC,CAAE,MAAY,CAAEmD,EAAI,KAAK5C,EAASP,EAAM,WAAYoC,EAAK,MAAOA,EAAK,IAAI,CAAC,CAAE,CACnJ,CAAC,CACH,CACAL,EAAUC,CAAK,CACjB,EAEMqB,GAAe,MAAOrB,EAAOE,EAAKC,EAAKC,IAAS,CACpD,GAAM,CAAE,UAAAtC,EAAW,QAAAK,EAAS,KAAAmD,CAAK,EAAIC,EAAcrB,EAAKC,CAAG,EAC3DH,EAAM,KAAK,qDAAqDvD,EAAI6E,CAAI,CAAC,0CAAqC,EAC9G,IAAMhB,EAAU,MAAMzC,GAAaC,CAAS,EACxC0D,EAAQ,CAAC,EACTC,EAAO,GACX,GAAI,CACFD,EAAQ,MAAMtD,GAAUC,CAAO,CACjC,OAASmB,EAAG,CACVkC,EAAQlB,EAAU,OAAO,KAAKA,CAAO,EAAE,OAAOd,GAAKc,EAAQd,CAAC,GAAK,OAAOc,EAAQd,CAAC,GAAM,QAAQ,EAAI,CAAC,EACpGiC,EAAOD,EAAM,OAAS,4EAA8E,iBAAiB/E,EAAI6C,EAAE,OAAO,CAAC,GACrI,CACAkC,EAAQA,EAAM,OAAOE,GAAKA,IAAM,cAAc,EAAE,KAAK,EACjDpB,GAASkB,EAAM,KAAK,cAAc,EACtC,IAAMG,EAAOH,EAAM,IAAIE,GAAK,CAC1B,IAAM9B,EAAQU,GAAWA,EAAQoB,CAAC,GAAK,OAAOpB,EAAQoB,CAAC,GAAM,SAAWpB,EAAQoB,CAAC,EAAI,KAC/EE,EAAOhC,GAASA,EAAM,KAAO,mCAA8BnD,EAAImD,EAAM,IAAI,CAAC,UAAY,GAC5F,MAAO,sCAAsCnD,EAAI,GAAGqB,CAAS,IAAI,mBAAmB4D,CAAC,CAAC,EAAE,CAAC,KAAKjF,EAAIiF,CAAC,CAAC,OAAOE,CAAI,OACjH,CAAC,EACD5B,EAAM,KAAK,qDAAqDvD,EAAI6E,CAAI,CAAC,iBAAiBE,EAAM,MAAM,QAAQA,EAAM,SAAW,EAAI,GAAK,GAAG,GAAGC,CAAI;AAAA,mDACjGE,EAAK,KAAK,EAAE,GAAK,qCAAqC,kEAAkE,CAC3K,EAIaE,GAAO,CAAC/E,EAAOgF,IAAS,CACnClF,GAAY,EACZE,EAAM,SAAS,WAAW,EAC1B,IAAMsD,EAAOnC,EAAM6D,EAAK,IAAI,EACtBC,EAAS,CAAC,EAChB,QAAWL,KAAKtB,EAAK,QAAS2B,EAAO,KAAK,uCAAuCtF,EAAIiF,CAAC,CAAC,mEAA8D,EACrJ,QAAWA,KAAKtB,EAAK,MAAO2B,EAAO,KAAK,qCAAqCtF,EAAIiF,CAAC,CAAC,uDAAuDjF,EAAIiF,CAAC,CAAC,wCAAmC,EACnL5E,EAAM,KAAKiF,EAAO,KAAK,EAAE,CAAC,CAC5B,EAEaC,GAAO,CAAClF,EAAOgF,IAAS,CACnC,IAAM1B,EAAOnC,EAAM6D,EAAK,IAAI,EACtB3B,EAAMlD,GAAUH,CAAK,EAE3BA,EAAM,GAAG,WAAYwC,GAAK,CACpBA,EAAE,QAAUA,EAAE,OAAO,SAAWA,EAAE,OAAO,QAAQ,uCAAuC,GAC5F,KAAK,WAAWxC,EAAOgF,CAAI,CAC7B,CAAC,EAEDhF,EAAM,GAAG,QAAS,aAAc,SAAUwC,EAAG,CAC3CA,EAAE,eAAe,EAAGA,EAAE,gBAAgB,EACtC,IAAMjC,EAAM,KAAK,QAAQ,IACnB4E,EAAU,EAAE,IAAI,EAAE,QAAQ,YAAY,EAAE,KAAK,mBAAmB,EACtEA,EAAQ,KAAK,SAAU,EAAK,EAC5BhC,EAAWgC,EAAS5E,EAAK8C,EAAKC,CAAI,CACpC,CAAC,EACDtD,EAAM,GAAG,QAAS,gBAAiB,SAAUwC,EAAG,CAC9CA,EAAE,eAAe,EAAGA,EAAE,gBAAgB,EACtC,IAAMU,EAAQ,EAAE,IAAI,EAAE,QAAQ,YAAY,EACpCkC,EAAIlC,EAAM,KAAK,MAAM,EACtBkC,IACLlC,EAAM,KAAK,YAAY,EAAE,KAAKzB,EAAS2D,EAAE,KAAMA,EAAE,KAAM,IAAK,EAAI,CAAC,EACjEnC,EAAUC,CAAK,EACjB,CAAC,EACDlD,EAAM,GAAG,QAAS,kBAAmB,SAAUwC,EAAG,CAChDA,EAAE,eAAe,EAAGA,EAAE,gBAAgB,EACtC,IAAMU,EAAQ,EAAE,IAAI,EAAE,QAAQ,YAAY,EACpCkC,EAAIlC,EAAM,KAAK,MAAM,EAC3B,GAAI,CAACkC,EAAG,OACR,IAAMC,EAAQnC,EAAM,KAAK,YAAY,EACjC,KAAK,cAAgB,YACvBmC,EAAM,KAAK5D,EAAS2D,EAAE,KAAM,MAAO,IAAK,EAAI,EAAI,kFAAkF,EAClInC,EAAUC,CAAK,GAEfmC,EAAM,KAAK,+BAA+BhD,GAAS+C,EAAE,IAAI,CAAC,qFAAqF,CAEnJ,CAAC,EACDpF,EAAM,GAAG,QAAS,aAAc,SAAUwC,EAAG,CAC3CA,EAAE,eAAe,EAAGA,EAAE,gBAAgB,EACtC,IAAM4C,EAAI,EAAE,IAAI,EAAE,QAAQ,YAAY,EAAE,KAAK,MAAM,EAC/C,CAACA,GAAK,CAAC,UAAU,WACrB,UAAU,UAAU,UAAUA,EAAE,IAAI,EAAE,KAAK,IAAM,CAAE,KAAK,YAAc,SAAU,WAAW,IAAM,CAAE,KAAK,YAAc,MAAO,EAAG,IAAI,CAAE,CAAC,CACzI,CAAC,EAEDpF,EAAM,KAAK,yBAAyB,EAAE,KAAK,UAAY,CACrDuE,GAAa,EAAE,IAAI,EAAG,KAAK,QAAQ,OAAQlB,EAAKC,CAAI,CACtD,CAAC,EACDtD,EAAM,KAAK,uBAAuB,EAAE,KAAK,UAAY,CACnDmD,EAAW,EAAE,IAAI,EAAG,KAAK,QAAQ,KAAME,EAAKC,CAAI,CAClD,CAAC,CACH,EAEI,OAAO,OAAW,MACpB,OAAO,QAAU,OAAO,SAAW,CAAC,EACpC,OAAO,QAAQ,KAAO,CAAE,KAAAyB,GAAM,KAAAG,EAAK",
|
|
6
|
+
"names": ["parse", "text", "spec", "lines", "raw", "line", "m", "cmd", "arg", "n", "isAbsolute", "ref", "trimSlash", "s", "originOf", "url", "m", "resolveFile", "base", "slug", "cut", "resolveFolder", "folderUrl", "origin", "path", "KINDS", "LANGS", "extOf", "name", "m", "kindOf", "looksBinary", "bytes", "n", "bad", "b", "DATE_TIME_RE", "TomlDate", "_TomlDate", "#hasDate", "#hasTime", "#offset", "date", "hasDate", "hasTime", "offset", "match", "iso", "jsDate", "getLineColFromPtr", "string", "ptr", "lines", "makeCodeBlock", "line", "column", "codeblock", "numberLen", "i", "TomlError", "message", "options", "indexOfNewline", "str", "start", "idx", "skipComment", "ctx", "c", "TomlError", "skipVoid", "banNewLines", "banComments", "skipUntil", "sep", "end", "ptr", "INT_REGEX", "FLOAT_REGEX", "LEADING_ZERO", "parseString", "ctx", "start", "c", "first", "isLiteral", "isMultiline", "parsed", "sliceStart", "state", "TomlError", "value", "len", "j", "hex", "digit", "sliceAndTrimEndOf", "end", "commentIdx", "skipComment", "parseValue", "integersAsBigInt", "ptr", "err", "skipUntil", "isInt", "numeric", "date", "TomlDate", "extractValue", "ctx", "end", "integersAsBigInt", "ptr", "c", "TomlError", "value", "parseArray", "parseInlineTable", "parseString", "parseValue", "KEY_PART_RE", "parseKey", "ctx", "end", "start", "dot", "parsed", "endPtr", "TomlError", "c", "part", "parseString", "strEnd", "newLine", "indexOfNewline", "skipVoid", "parseInlineTable", "integersAsBigInt", "res", "seen", "k", "t", "hasOwn", "p", "key", "i", "value", "extractValue", "parseArray", "peekTable", "key", "table", "meta", "type", "t", "m", "k", "hasOwn", "state", "i", "l", "parse", "toml", "maxDepth", "integersAsBigInt", "ctx", "res", "tmp", "tbl", "skipVoid", "isTableArray", "parseKey", "TomlError", "p", "extractValue", "isTable", "v", "kindOf", "show", "x", "rowsOf", "obj", "prefix", "rows", "sections", "k", "key", "t", "i", "rs", "sectionsOf", "doc", "root", "nested", "s", "tomlSections", "text", "parse", "esc", "s", "CSS", "ensureStyle", "pageOf", "$item", "slugOf", "siteOf", "contextOf", "site", "w", "fetchBytes", "url", "res", "buf", "sha256", "bytes", "h", "b", "sourcesCache", "fetchSources", "folderUrl", "p", "text", "parse", "fetchList", "listUrl", "data", "fmtSize", "n", "codeHtml", "lang", "limit", "show", "lines", "total", "cut", "shown", "nums", "_", "i", "more", "tomlHtml", "sections", "tomlSections", "e", "cell", "k", "v", "kind", "provHtml", "entry", "name", "bits", "highlight", "$view", "renderFile", "ref", "ctx", "spec", "resolveFile", "sources", "kindOf", "binary", "looksBinary", "badge", "digest", "blob", "blobUrl", "toolbar", "body", "pretty", "LANGS", "extOf", "$md", "plugin", "renderFolder", "path", "resolveFolder", "files", "note", "f", "rows", "role", "emit", "item", "blocks", "bind", "$folder", "d", "$body"]
|
|
7
|
+
}
|
package/factory.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name": "File", "title": "View a file from the page's assets folder — markdown, TOML, code, images", "category": "format"}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wiki-plugin-file",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "View a file from a page's assets folder inline — markdown, TOML, JSON, code, images — with provenance, a drift badge, and Raw/Download/Copy.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "client/file.js",
|
|
7
|
+
"files": ["client", "pages", "factory.json"],
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "node scripts/build.js",
|
|
10
|
+
"test": "node --test test/*.test.js"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"smol-toml": "^1.8.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"esbuild": "^0.25.0"
|
|
17
|
+
},
|
|
18
|
+
"author": "David Bovill",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": { "type": "git", "url": "git+https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-file.git" },
|
|
21
|
+
"bugs": { "url": "https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-file/issues" },
|
|
22
|
+
"homepage": "https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-file#readme"
|
|
23
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "About File Plugin",
|
|
3
|
+
"story": [
|
|
4
|
+
{
|
|
5
|
+
"type": "markdown",
|
|
6
|
+
"id": "28ad43ad7ea272da",
|
|
7
|
+
"text": "The File plugin shows a file from a page's assets folder inside the page. Browsers download most text assets because of the Content-Type the farm sends; this plugin fetches the bytes itself and renders them: markdown through the wiki's markdown plugin so [[wikilinks]] resolve, TOML as one table per section, JSON pretty-printed, code with line numbers, images inline. Every text file gets a Raw button that opens it in a new tab as plain text, plus Download, Copy and the asset URL."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"type": "markdown",
|
|
11
|
+
"id": "2093a9e9bb5c0b9f",
|
|
12
|
+
"text": "## Commands\n\nOne command per line, uppercase, per the wiki DSL convention.\n\n| Command | Meaning |\n| --- | --- |\n| FILE BUGS.toml | a file in this page's own assets folder |\n| FILE assets/other-slug/notes.md | a file in another folder on this site |\n| FILE https://host/assets/x/y.md | any absolute asset URL |\n| FOLDER | list this page's assets folder; click a name to read it |\n| FOLDER other-slug | list a sibling folder |\n| FOLDER https://host/assets/path | list a folder on another site |\n| LINES 60 | collapse files longer than this many lines (default 40) |\n| SHOW | start expanded |\n\nAn empty item is the same as FOLDER."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "markdown",
|
|
16
|
+
"id": "3c8b5d970c6e4882",
|
|
17
|
+
"text": "## Provenance\n\nIf the folder carries a SOURCES.toml manifest (written by asset-snapshot.py) the viewer shows each file's role, source path, repo, commit and snapshot date, and computes the sha256 of the bytes it fetched. A green badge means the file still matches the manifest; a red one means the snapshot was edited in place or the manifest is stale."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "markdown",
|
|
21
|
+
"id": "903061905eb29de0",
|
|
22
|
+
"text": "## Example \u2014 a TOML file from another site"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "file",
|
|
26
|
+
"id": "3325322fbb743f6b",
|
|
27
|
+
"text": "FILE https://sweet.fedwiki.club/assets/sweet-keycloak-plan/BUGS.toml\nLINES 60"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"type": "markdown",
|
|
31
|
+
"id": "62c3b2178ad39653",
|
|
32
|
+
"text": "## Example \u2014 a folder on another site"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "file",
|
|
36
|
+
"id": "6993fec08a20d286",
|
|
37
|
+
"text": "FOLDER https://sweet.fedwiki.club/assets/sweet-keycloak-plan"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "markdown",
|
|
41
|
+
"id": "21624a031affdcc4",
|
|
42
|
+
"text": "## Repositories\n\n- [https://github.com/Hitchhikers-Guide-to-the-Galaxy/wiki-plugin-file wiki-plugin-file] on GitHub\n- [https://www.npmjs.com/package/wiki-plugin-file wiki-plugin-file] on npm"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"type": "markdown",
|
|
46
|
+
"id": "cf4ff1d12597f575",
|
|
47
|
+
"text": "# See\n\n- [[File Plugin Plan]]\n- [[About Assets Plugin]]\n- [[About Code Plugin]]"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"journal": [
|
|
51
|
+
{
|
|
52
|
+
"type": "create",
|
|
53
|
+
"item": {
|
|
54
|
+
"title": "About File Plugin",
|
|
55
|
+
"story": [
|
|
56
|
+
{
|
|
57
|
+
"type": "markdown",
|
|
58
|
+
"id": "28ad43ad7ea272da",
|
|
59
|
+
"text": "The File plugin shows a file from a page's assets folder inside the page. Browsers download most text assets because of the Content-Type the farm sends; this plugin fetches the bytes itself and renders them: markdown through the wiki's markdown plugin so [[wikilinks]] resolve, TOML as one table per section, JSON pretty-printed, code with line numbers, images inline. Every text file gets a Raw button that opens it in a new tab as plain text, plus Download, Copy and the asset URL."
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"date": 1788429935173,
|
|
64
|
+
"provenance": "Authored by Claude Code (Fable 5.1) via the fedwiki-create-plugin skill, in dialogue with David Bovill, 2026-09-03. [https://claude.com/claude-code Claude Code]"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"plugin": "file"
|
|
68
|
+
}
|