pict-docuserve 1.4.1 → 1.4.2
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/dist/pict-docuserve.js +132 -15
- package/dist/pict-docuserve.js.map +1 -1
- package/dist/pict-docuserve.min.js +2 -2
- package/dist/pict-docuserve.min.js.map +1 -1
- package/package.json +4 -6
- package/source/cli/Docuserve-CLI-Program.js +1 -0
- package/source/cli/commands/Docuserve-Command-StagePlayground.js +279 -0
- package/source/views/PictView-Docuserve-Section-Playground.js +239 -19
- package/source/views/PictView-Docuserve-Splash.js +54 -0
package/dist/pict-docuserve.js
CHANGED
|
@@ -5923,8 +5923,26 @@ if(this.options.CodeDataAddress){const tmpAddressSpace={Fable:this.fable,Pict:th
|
|
|
5923
5923
|
*/getCode(){if(!this.codeJar){this.log.warn('PICT-Code getCode called before editor initialized.');return'';}return this.codeJar.toString();}/**
|
|
5924
5924
|
* Set the code content.
|
|
5925
5925
|
*
|
|
5926
|
+
* Safe to call whether or not the editor's host element is currently
|
|
5927
|
+
* visible. CodeJar's `updateCode()` internally touches the
|
|
5928
|
+
* selection APIs (to preserve cursor position across the swap), and
|
|
5929
|
+
* those APIs return null / empty Range when the contenteditable is
|
|
5930
|
+
* inside a `display:none` ancestor. In that case CodeJar's internal
|
|
5931
|
+
* bookkeeping throws — but the actual content swap is the easy
|
|
5932
|
+
* part: just set the editor element's textContent and re-run the
|
|
5933
|
+
* highlighter directly. When the user makes the tab visible later,
|
|
5934
|
+
* CodeJar picks up the new textContent and cursor handling resumes.
|
|
5935
|
+
*
|
|
5926
5936
|
* @param {string} pCode - The code to set
|
|
5927
|
-
*/setCode(pCode){if(!this.codeJar){this.log.warn('PICT-Code setCode called before editor initialized.');return;}this.codeJar.updateCode(pCode);
|
|
5937
|
+
*/setCode(pCode){if(!this.codeJar){this.log.warn('PICT-Code setCode called before editor initialized.');return;}let tmpUsedFallback=false;try{this.codeJar.updateCode(pCode);}catch(pError){// Fall back to a direct textContent swap + re-highlight.
|
|
5938
|
+
// This branch typically fires when setCode is called on a
|
|
5939
|
+
// tab that's not currently active (display:none), or on an
|
|
5940
|
+
// editor whose host has been detached from the DOM.
|
|
5941
|
+
tmpUsedFallback=true;try{if(this._editorElement){this._editorElement.textContent=typeof pCode==='string'?pCode:'';if(typeof this._highlightFunction==='function'){this._highlightFunction(this._editorElement);}}}catch(pFallbackError){this.log.warn('PICT-Code setCode failed: '+pError+' (textContent fallback also failed: '+pFallbackError+')');return;}}// Line-number gutter sync is best-effort either way; if it
|
|
5942
|
+
// throws (e.g. gutter wasn't built because the editor never
|
|
5943
|
+
// became visible), keep going — line numbers redraw on the
|
|
5944
|
+
// next visible render.
|
|
5945
|
+
try{this._updateLineNumbers();}catch(pLineNumberError){/* gutter sync is non-fatal */}}/**
|
|
5928
5946
|
* Change the editor language and re-highlight.
|
|
5929
5947
|
*
|
|
5930
5948
|
* @param {string} pLanguage - The language identifier
|
|
@@ -6039,7 +6057,15 @@ if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');tmpInList=false;}
|
|
|
6039
6057
|
let tmpFenceMatch=tmpLine.match(/^(`{3,})/);if(tmpFenceMatch){let tmpFenceLen=tmpFenceMatch[1].length;if(tmpInCodeBlock){// Only close if the closing fence is at least as long as the opening
|
|
6040
6058
|
if(tmpFenceLen>=tmpCodeFenceLength&&tmpLine.trim()===tmpFenceMatch[1]){// End code block
|
|
6041
6059
|
if(tmpCodeLang==='mermaid'){// Mermaid diagrams: output raw content for client-side rendering
|
|
6042
|
-
tmpHTML.push('<pre class="mermaid">'+tmpCodeLines.join('\n')+'</pre>');}else
|
|
6060
|
+
tmpHTML.push('<pre class="mermaid">'+tmpCodeLines.join('\n')+'</pre>');}else if(tmpCodeLang==='excalidraw'){// Excalidraw scenes: emit a placeholder div with the
|
|
6061
|
+
// scene JSON URI-component encoded into a data
|
|
6062
|
+
// attribute. Pict-View-Content's
|
|
6063
|
+
// renderExcalidrawDiagrams() swaps these for rendered
|
|
6064
|
+
// SVGs once the wrapper bundle is ready. We don't
|
|
6065
|
+
// validate the JSON here — invalid fences just stay
|
|
6066
|
+
// as the loading placeholder until the runtime
|
|
6067
|
+
// reports the error.
|
|
6068
|
+
let tmpRawScene=tmpCodeLines.join('\n');let tmpEncoded;try{tmpEncoded=encodeURIComponent(tmpRawScene);}catch(pErr){tmpEncoded='';}tmpHTML.push('<div class="pict-excalidraw-fence" data-scene="'+tmpEncoded+'">'+'<div class="pict-excalidraw-fence-loading">Rendering Excalidraw diagram…</div>'+'</div>');}else{let tmpCodeText=tmpCodeLines.join('\n');let tmpHighlightedCode=this.highlightCode(tmpCodeText,tmpCodeLang);let tmpLineNumbersHTML=this.generateLineNumbers(tmpCodeText);tmpHTML.push('<div class="pict-content-code-wrap"><div class="pict-content-code-line-numbers">'+tmpLineNumbersHTML+'</div><pre><code class="language-'+this.escapeHTML(tmpCodeLang)+'">'+tmpHighlightedCode+'</code></pre></div>');}tmpInCodeBlock=false;tmpCodeFenceLength=0;tmpCodeLang='';tmpCodeLines=[];continue;}else{// Inner fence with fewer backticks — treat as content
|
|
6043
6069
|
tmpCodeLines.push(tmpLine);continue;}}else{// Flush any pending paragraph
|
|
6044
6070
|
fFlushParagraph();// Close any open list or blockquote
|
|
6045
6071
|
if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');tmpInList=false;}if(tmpInBlockquote){tmpHTML.push('<blockquote>'+this.parseMarkdown(tmpBlockquoteLines.join('\n'),pLinkResolver,pImageResolver,pVocabularyResolver)+'</blockquote>');tmpInBlockquote=false;tmpBlockquoteLines=[];}// Start code block — record fence length
|
|
@@ -6121,7 +6147,7 @@ let tmpResult=pResolver(tmpLower);if(!tmpResult)return pMatch;tmpLinked[tmpLower
|
|
|
6121
6147
|
*
|
|
6122
6148
|
* @param {string} pText - The text to escape
|
|
6123
6149
|
* @returns {string} The escaped text
|
|
6124
|
-
*/escapeHTML(pText){if(!pText){return'';}return pText.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');}}module.exports=PictContentProvider;module.exports.default_configuration={ProviderIdentifier:"Pict-Content",AutoInitialize:true,AutoInitializeOrdinal:0};},{"pict-provider":148,"pict-section-code":151}],155:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"Pict-Content",DefaultRenderable:"Pict-Content-Display",DefaultDestinationAddress:"#Pict-Content-Container",AutoRender:false,CSS:/*css*/"\n\t\t.pict-content {\n\t\t\tpadding: 2em 3em;\n\t\t\tmax-width: 900px;\n\t\t\tmargin: 0 auto;\n\t\t}\n\t\t.pict-content-loading {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: 200px;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.pict-content h1 {\n\t\t\tfont-size: 2em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding-bottom: 0.3em;\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t.pict-content h2 {\n\t\t\tfont-size: 1.5em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t\tpadding-bottom: 0.25em;\n\t\t\tmargin-top: 1.5em;\n\t\t}\n\t\t.pict-content h3 {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin-top: 1.25em;\n\t\t}\n\t\t.pict-content h4, .pict-content h5, .pict-content h6 {\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\t.pict-content p {\n\t\t\tline-height: 1.7;\n\t\t\tcolor: var(--theme-color-text-primary, #423D37);\n\t\t\tmargin: 0.75em 0;\n\t\t}\n\t\t.pict-content a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.pict-content a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* \u2500\u2500\u2500 Code blocks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\t\t Background, text color, line-number gutter, and every\n\t\t syntax token route through pict-provider-theme tokens \u2014\n\t\t the same set pict-section-code (the live editor) uses.\n\t\t This way the rendered-preview code blocks look identical\n\t\t to the live editor and re-skin together when the theme\n\t\t switches. Previous version used the text-primary token\n\t\t as the code background (a TEXT token used as BACKGROUND),\n\t\t which broke in dark mode and any palette where text and\n\t\t background-tertiary diverge.\n\t\t*/\n\t\t.pict-content pre {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 1.25em;\n\t\t\tborder-radius: 6px;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: 0.9em;\n\t\t\tfont-family: var(--theme-typography-family-mono, 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace);\n\t\t}\n\t\t/* Inline code (single backtick) \u2014 slightly differentiated\n\t\t from block code so it doesn't disappear into prose. */\n\t\t.pict-content code {\n\t\t\tbackground: var(--theme-color-background-secondary, #FAF8F4);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tpadding: 0.15em 0.4em;\n\t\t\tborder-radius: 3px;\n\t\t\tfont-size: 0.9em;\n\t\t\tfont-family: var(--theme-typography-family-mono, 'SFMono-Regular', 'SF Mono', 'Menlo', monospace);\n\t\t}\n\t\t.pict-content-code-wrap {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: row;\n\t\t\tfont-family: var(--theme-typography-family-mono, 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace);\n\t\t\tfont-size: 14px;\n\t\t\tline-height: 1.5;\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 6px;\n\t\t\toverflow: hidden;\n\t\t\tmargin: 1em 0;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers {\n\t\t\twidth: 40px;\n\t\t\tmin-width: 40px;\n\t\t\tpadding: 1.25em 0;\n\t\t\ttext-align: right;\n\t\t\tbackground: var(--theme-color-background-secondary, #FAF8F4);\n\t\t\tborder-right: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tfont-family: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tline-height: inherit;\n\t\t\tuser-select: none;\n\t\t\tpointer-events: none;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers span {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0 8px 0 0;\n\t\t}\n\t\t.pict-content-code-wrap pre {\n\t\t\tmargin: 0;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: none;\n\t\t\tpadding: 1.25em 1.25em 1.25em 8px;\n\t\t\tborder-radius: 0 6px 6px 0;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: inherit;\n\t\t\tflex: 1;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.pict-content-code-wrap pre code {\n\t\t\tbackground: none;\n\t\t\tpadding: 0;\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tfont-family: inherit;\n\t\t}\n\t\t/* Syntax token colors \u2014 every class binds to a --theme-color-syntax-*\n\t\t variable, the same tokens pict-section-code (the live editor) uses.\n\t\t Each var() carries an Atom One Light hex as fallback for hosts\n\t\t without a theme provider; themes that DO ship syntax tokens\n\t\t (pict-default, retold-content-system, etc.) drive everything\n\t\t coherently. */\n\t\t.pict-content-code-wrap .keyword { color: var(--theme-color-syntax-keyword, #A626A4); }\n\t\t.pict-content-code-wrap .string { color: var(--theme-color-syntax-string, #50A14F); }\n\t\t.pict-content-code-wrap .number { color: var(--theme-color-syntax-number, #986801); }\n\t\t.pict-content-code-wrap .comment { color: var(--theme-color-syntax-comment, #A0A1A7); font-style: italic; }\n\t\t.pict-content-code-wrap .operator { color: var(--theme-color-syntax-operator, #0184BC); }\n\t\t.pict-content-code-wrap .punctuation { color: var(--theme-color-syntax-punctuation, #383A42); }\n\t\t.pict-content-code-wrap .function-name { color: var(--theme-color-syntax-function, #4078F2); }\n\t\t.pict-content-code-wrap .property { color: var(--theme-color-syntax-property, #E45649); }\n\t\t.pict-content-code-wrap .tag { color: var(--theme-color-syntax-tag, #E45649); }\n\t\t.pict-content-code-wrap .attr-name { color: var(--theme-color-syntax-attrname, #986801); }\n\t\t.pict-content-code-wrap .attr-value { color: var(--theme-color-syntax-attrvalue, #50A14F); }\n\t\t.pict-content-code-wrap .builtin { color: var(--theme-color-syntax-builtin, #986801); }\n\t\t.pict-content-code-wrap .type { color: var(--theme-color-syntax-type, #C18401); }\n\t\t.pict-content-code-wrap .variable { color: var(--theme-color-syntax-variable, #383A42); }\n\t\t.pict-content pre code {\n\t\t\tbackground: none;\n\t\t\tpadding: 0;\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t}\n\t\t.pict-content blockquote {\n\t\t\tborder-left: 4px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em 1em;\n\t\t\tbackground: var(--theme-color-background-secondary, #F7F5F0);\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t}\n\t\t.pict-content blockquote p {\n\t\t\tmargin: 0.25em 0;\n\t\t}\n\t\t.pict-content ul, .pict-content ol {\n\t\t\tpadding-left: 2em;\n\t\t\tline-height: 1.8;\n\t\t}\n\t\t.pict-content li {\n\t\t\tmargin: 0.25em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #423D37);\n\t\t}\n\t\t.pict-content hr {\n\t\t\tborder: none;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tmargin: 2em 0;\n\t\t}\n\t\t.pict-content table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.pict-content table th {\n\t\t\tbackground: var(--theme-color-background-secondary, #F5F0E8);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.6em 0.8em;\n\t\t\ttext-align: left;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-content table td {\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.5em 0.8em;\n\t\t\tcolor: var(--theme-color-text-primary, #423D37);\n\t\t}\n\t\t.pict-content table tr:nth-child(even) {\n\t\t\tbackground: var(--theme-color-background-secondary, #F7F5F0);\n\t\t}\n\t\t.pict-content img {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.pict-content pre.mermaid {\n\t\t\tbackground: var(--theme-color-background-panel, #fff);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\ttext-align: center;\n\t\t\tpadding: 1em;\n\t\t}\n\t\t.pict-content pre.mermaid text,\n\t\t.pict-content pre.mermaid .nodeLabel,\n\t\t.pict-content pre.mermaid .edgeLabel,\n\t\t.pict-content pre.mermaid .label,\n\t\t.pict-content pre.mermaid .cluster-label,\n\t\t.pict-content pre.mermaid span,\n\t\t.pict-content pre.mermaid foreignObject p,\n\t\t.pict-content pre.mermaid foreignObject div,\n\t\t.pict-content pre.mermaid foreignObject span {\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E) !important;\n\t\t\tfill: var(--theme-color-text-primary, #2A241E) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .edgePath .path {\n\t\t\tstroke: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .arrowheadPath {\n\t\t\tfill: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t.pict-content .pict-content-katex-display {\n\t\t\ttext-align: center;\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em;\n\t\t\toverflow-x: auto;\n\t\t}\n\t\t.pict-content .pict-content-katex-inline {\n\t\t\tdisplay: inline;\n\t\t}\n\n\t\t/* Fullscreen viewer for images and mermaid diagrams (click-to-zoom) */\n\t\t.pict-content [data-fullscreen-source] {\n\t\t\tcursor: zoom-in;\n\t\t\toutline: 1px solid transparent;\n\t\t\toutline-offset: 3px;\n\t\t\tborder-radius: 4px;\n\t\t\ttransition: outline-color 0.15s ease;\n\t\t}\n\t\t.pict-content [data-fullscreen-source]:hover {\n\t\t\toutline-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t/* Code block container with hover-revealed action buttons */\n\t\t.pict-content-code-container {\n\t\t\tposition: relative;\n\t\t\tdisplay: flex;\n\t\t\talign-items: flex-start;\n\t\t\tgap: 8px;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.pict-content-code-container > .pict-content-code-wrap {\n\t\t\tmargin: 0;\n\t\t\tflex: 1 1 auto;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.pict-content-code-actions {\n\t\t\tposition: sticky;\n\t\t\ttop: 64px;\n\t\t\talign-self: flex-start;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tgap: 6px;\n\t\t\tflex: 0 0 auto;\n\t\t\tpadding-top: 6px;\n\t\t\topacity: 0;\n\t\t\ttransform: translateX(-4px);\n\t\t\ttransition: opacity 0.15s ease, transform 0.15s ease;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t.pict-content-code-container:hover .pict-content-code-actions,\n\t\t.pict-content-code-container:focus-within .pict-content-code-actions {\n\t\t\topacity: 1;\n\t\t\ttransform: translateX(0);\n\t\t\tpointer-events: auto;\n\t\t}\n\t\t.pict-content-code-action-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 28px;\n\t\t\theight: 28px;\n\t\t\tpadding: 0;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-muted, #5E5549);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 6px;\n\t\t\tcursor: pointer;\n\t\t\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;\n\t\t}\n\t\t.pict-content-code-action-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 14px;\n\t\t\theight: 14px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.6;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-content-code-action-btn:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t}\n\t\t.pict-content-code-action-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-content-code-action-btn.is-copied {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.pict-content-code-action-btn.is-copy-failed {\n\t\t\tbackground: var(--theme-color-status-error, #B23A3A);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-status-error, #B23A3A);\n\t\t}\n\t\t.pict-fullscreen-overlay {\n\t\t\tposition: fixed;\n\t\t\tinset: 0;\n\t\t\tz-index: 9999;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tbackground: rgba(0, 0, 0, 0.62);\n\t\t\tbackdrop-filter: blur(6px);\n\t\t\t-webkit-backdrop-filter: blur(6px);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-fullscreen-overlay[hidden] {\n\t\t\tdisplay: none;\n\t\t}\n\t\t.pict-fullscreen-titlebar {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: space-between;\n\t\t\tgap: 1em;\n\t\t\theight: 48px;\n\t\t\tpadding: 0 1em;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #1A1612);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t\tflex: 0 0 auto;\n\t\t}\n\t\t.pict-fullscreen-title {\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\tletter-spacing: 0.01em;\n\t\t\twhite-space: nowrap;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t\tcolor: var(--theme-color-text-primary, #1A1612);\n\t\t}\n\t\t.pict-fullscreen-controls {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tgap: 4px;\n\t\t}\n\t\t.pict-fullscreen-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 32px;\n\t\t\theight: 32px;\n\t\t\tpadding: 0;\n\t\t\tbackground: transparent;\n\t\t\tborder: 1px solid transparent;\n\t\t\tborder-radius: 6px;\n\t\t\tcolor: var(--theme-color-text-muted, #5E5549);\n\t\t\tcursor: pointer;\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n\t\t}\n\t\t.pict-fullscreen-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 16px;\n\t\t\theight: 16px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.75;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-fullscreen-btn:hover {\n\t\t\tbackground: var(--theme-color-border-light, #EAE3D8);\n\t\t\tcolor: var(--theme-color-text-primary, #1A1612);\n\t\t}\n\t\t.pict-fullscreen-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-fullscreen-close:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t}\n\t\t.pict-fullscreen-stage {\n\t\t\tflex: 1 1 auto;\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\toverflow: hidden;\n\t\t\tpadding: 1.5em;\n\t\t\tcursor: zoom-in;\n\t\t\ttouch-action: none;\n\t\t}\n\t\t.pict-fullscreen-stage.is-zoomed {\n\t\t\tcursor: grab;\n\t\t}\n\t\t.pict-fullscreen-stage.is-panning {\n\t\t\tcursor: grabbing;\n\t\t}\n\t\t.pict-fullscreen-content {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmax-width: 100%;\n\t\t\tmax-height: 100%;\n\t\t\ttransform-origin: center center;\n\t\t\ttransition: transform 0.05s linear;\n\t\t\twill-change: transform;\n\t\t}\n\t\t.pict-fullscreen-content > * {\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-img {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tobject-fit: contain;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tpadding: 12px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg {\n\t\t\twidth: min(90vw, 1400px);\n\t\t\theight: auto;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tpadding: 16px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-codewrap {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tmargin: 0;\n\t\t\toverflow: auto;\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t",Templates:[{Hash:"Pict-Content-Template",Template:/*html*/"\n<div class=\"pict-content\" id=\"Pict-Content-Body\">\n\t<div class=\"pict-content-loading\">Loading content...</div>\n</div>\n"}],Renderables:[{RenderableHash:"Pict-Content-Display",TemplateHash:"Pict-Content-Template",DestinationAddress:"#Pict-Content-Container",RenderMethod:"replace"}]};class PictContentView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}/**
|
|
6150
|
+
*/escapeHTML(pText){if(!pText){return'';}return pText.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');}}module.exports=PictContentProvider;module.exports.default_configuration={ProviderIdentifier:"Pict-Content",AutoInitialize:true,AutoInitializeOrdinal:0};},{"pict-provider":148,"pict-section-code":151}],155:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"Pict-Content",DefaultRenderable:"Pict-Content-Display",DefaultDestinationAddress:"#Pict-Content-Container",AutoRender:false,CSS:/*css*/"\n\t\t.pict-content {\n\t\t\tpadding: 2em 3em;\n\t\t\tmax-width: 900px;\n\t\t\tmargin: 0 auto;\n\t\t}\n\t\t.pict-content-loading {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: 200px;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.pict-content h1 {\n\t\t\tfont-size: 2em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding-bottom: 0.3em;\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t.pict-content h2 {\n\t\t\tfont-size: 1.5em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-light, #EAE3D8);\n\t\t\tpadding-bottom: 0.25em;\n\t\t\tmargin-top: 1.5em;\n\t\t}\n\t\t.pict-content h3 {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin-top: 1.25em;\n\t\t}\n\t\t.pict-content h4, .pict-content h5, .pict-content h6 {\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\t.pict-content p {\n\t\t\tline-height: 1.7;\n\t\t\tcolor: var(--theme-color-text-primary, #423D37);\n\t\t\tmargin: 0.75em 0;\n\t\t}\n\t\t.pict-content a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.pict-content a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* \u2500\u2500\u2500 Code blocks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\t\t Background, text color, line-number gutter, and every\n\t\t syntax token route through pict-provider-theme tokens \u2014\n\t\t the same set pict-section-code (the live editor) uses.\n\t\t This way the rendered-preview code blocks look identical\n\t\t to the live editor and re-skin together when the theme\n\t\t switches. Previous version used the text-primary token\n\t\t as the code background (a TEXT token used as BACKGROUND),\n\t\t which broke in dark mode and any palette where text and\n\t\t background-tertiary diverge.\n\t\t*/\n\t\t.pict-content pre {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 1.25em;\n\t\t\tborder-radius: 6px;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: 0.9em;\n\t\t\tfont-family: var(--theme-typography-family-mono, 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace);\n\t\t}\n\t\t/* Inline code (single backtick) \u2014 slightly differentiated\n\t\t from block code so it doesn't disappear into prose. */\n\t\t.pict-content code {\n\t\t\tbackground: var(--theme-color-background-secondary, #FAF8F4);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tpadding: 0.15em 0.4em;\n\t\t\tborder-radius: 3px;\n\t\t\tfont-size: 0.9em;\n\t\t\tfont-family: var(--theme-typography-family-mono, 'SFMono-Regular', 'SF Mono', 'Menlo', monospace);\n\t\t}\n\t\t.pict-content-code-wrap {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: row;\n\t\t\tfont-family: var(--theme-typography-family-mono, 'SFMono-Regular', 'SF Mono', 'Menlo', 'Consolas', 'Liberation Mono', 'Courier New', monospace);\n\t\t\tfont-size: 14px;\n\t\t\tline-height: 1.5;\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 6px;\n\t\t\toverflow: hidden;\n\t\t\tmargin: 1em 0;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers {\n\t\t\twidth: 40px;\n\t\t\tmin-width: 40px;\n\t\t\tpadding: 1.25em 0;\n\t\t\ttext-align: right;\n\t\t\tbackground: var(--theme-color-background-secondary, #FAF8F4);\n\t\t\tborder-right: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tfont-family: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tline-height: inherit;\n\t\t\tuser-select: none;\n\t\t\tpointer-events: none;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t.pict-content-code-wrap .pict-content-code-line-numbers span {\n\t\t\tdisplay: block;\n\t\t\tpadding: 0 8px 0 0;\n\t\t}\n\t\t.pict-content-code-wrap pre {\n\t\t\tmargin: 0;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F0ECE4);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: none;\n\t\t\tpadding: 1.25em 1.25em 1.25em 8px;\n\t\t\tborder-radius: 0 6px 6px 0;\n\t\t\toverflow-x: auto;\n\t\t\tline-height: 1.5;\n\t\t\tfont-size: inherit;\n\t\t\tflex: 1;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.pict-content-code-wrap pre code {\n\t\t\tbackground: none;\n\t\t\tpadding: 0;\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t\tfont-family: inherit;\n\t\t}\n\t\t/* Syntax token colors \u2014 every class binds to a --theme-color-syntax-*\n\t\t variable, the same tokens pict-section-code (the live editor) uses.\n\t\t Each var() carries an Atom One Light hex as fallback for hosts\n\t\t without a theme provider; themes that DO ship syntax tokens\n\t\t (pict-default, retold-content-system, etc.) drive everything\n\t\t coherently. */\n\t\t.pict-content-code-wrap .keyword { color: var(--theme-color-syntax-keyword, #A626A4); }\n\t\t.pict-content-code-wrap .string { color: var(--theme-color-syntax-string, #50A14F); }\n\t\t.pict-content-code-wrap .number { color: var(--theme-color-syntax-number, #986801); }\n\t\t.pict-content-code-wrap .comment { color: var(--theme-color-syntax-comment, #A0A1A7); font-style: italic; }\n\t\t.pict-content-code-wrap .operator { color: var(--theme-color-syntax-operator, #0184BC); }\n\t\t.pict-content-code-wrap .punctuation { color: var(--theme-color-syntax-punctuation, #383A42); }\n\t\t.pict-content-code-wrap .function-name { color: var(--theme-color-syntax-function, #4078F2); }\n\t\t.pict-content-code-wrap .property { color: var(--theme-color-syntax-property, #E45649); }\n\t\t.pict-content-code-wrap .tag { color: var(--theme-color-syntax-tag, #E45649); }\n\t\t.pict-content-code-wrap .attr-name { color: var(--theme-color-syntax-attrname, #986801); }\n\t\t.pict-content-code-wrap .attr-value { color: var(--theme-color-syntax-attrvalue, #50A14F); }\n\t\t.pict-content-code-wrap .builtin { color: var(--theme-color-syntax-builtin, #986801); }\n\t\t.pict-content-code-wrap .type { color: var(--theme-color-syntax-type, #C18401); }\n\t\t.pict-content-code-wrap .variable { color: var(--theme-color-syntax-variable, #383A42); }\n\t\t.pict-content pre code {\n\t\t\tbackground: none;\n\t\t\tpadding: 0;\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t}\n\t\t.pict-content blockquote {\n\t\t\tborder-left: 4px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em 1em;\n\t\t\tbackground: var(--theme-color-background-secondary, #F7F5F0);\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t}\n\t\t.pict-content blockquote p {\n\t\t\tmargin: 0.25em 0;\n\t\t}\n\t\t.pict-content ul, .pict-content ol {\n\t\t\tpadding-left: 2em;\n\t\t\tline-height: 1.8;\n\t\t}\n\t\t.pict-content li {\n\t\t\tmargin: 0.25em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #423D37);\n\t\t}\n\t\t.pict-content hr {\n\t\t\tborder: none;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tmargin: 2em 0;\n\t\t}\n\t\t.pict-content table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.pict-content table th {\n\t\t\tbackground: var(--theme-color-background-secondary, #F5F0E8);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.6em 0.8em;\n\t\t\ttext-align: left;\n\t\t\tfont-weight: 600;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t}\n\t\t.pict-content table td {\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tpadding: 0.5em 0.8em;\n\t\t\tcolor: var(--theme-color-text-primary, #423D37);\n\t\t}\n\t\t.pict-content table tr:nth-child(even) {\n\t\t\tbackground: var(--theme-color-background-secondary, #F7F5F0);\n\t\t}\n\t\t.pict-content img {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.pict-content pre.mermaid {\n\t\t\tbackground: var(--theme-color-background-panel, #fff);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t\ttext-align: center;\n\t\t\tpadding: 1em;\n\t\t}\n\t\t.pict-content pre.mermaid text,\n\t\t.pict-content pre.mermaid .nodeLabel,\n\t\t.pict-content pre.mermaid .edgeLabel,\n\t\t.pict-content pre.mermaid .label,\n\t\t.pict-content pre.mermaid .cluster-label,\n\t\t.pict-content pre.mermaid span,\n\t\t.pict-content pre.mermaid foreignObject p,\n\t\t.pict-content pre.mermaid foreignObject div,\n\t\t.pict-content pre.mermaid foreignObject span {\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E) !important;\n\t\t\tfill: var(--theme-color-text-primary, #2A241E) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .edgePath .path {\n\t\t\tstroke: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t.pict-content pre.mermaid .arrowheadPath {\n\t\t\tfill: var(--theme-color-text-secondary, #5E5549) !important;\n\t\t}\n\t\t/* Excalidraw fence placeholders + rendered SVGs */\n\t\t.pict-content .pict-excalidraw-fence {\n\t\t\tdisplay: block;\n\t\t\tbackground: var(--theme-color-background-panel, #fff);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 4px;\n\t\t\tpadding: 1em;\n\t\t\tmargin: 1em 0;\n\t\t\ttext-align: center;\n\t\t}\n\t\t.pict-content .pict-excalidraw-fence svg {\n\t\t\tmax-width: 100%;\n\t\t\theight: auto;\n\t\t}\n\t\t.pict-content .pict-excalidraw-fence-loading {\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tfont-style: italic;\n\t\t\tfont-size: 0.9em;\n\t\t\tpadding: 1em;\n\t\t}\n\t\t.pict-content .pict-excalidraw-fence-error {\n\t\t\tborder-color: var(--theme-color-status-error, #D9534F);\n\t\t\tbackground: var(--theme-color-background-secondary, #FFF5F5);\n\t\t}\n\t\t.pict-content .pict-excalidraw-fence-error-message {\n\t\t\tcolor: var(--theme-color-status-error, #D9534F);\n\t\t\tfont-family: var(--theme-typography-family-mono, monospace);\n\t\t\tfont-size: 0.85em;\n\t\t\ttext-align: left;\n\t\t}\n\t\t.pict-content .pict-content-katex-display {\n\t\t\ttext-align: center;\n\t\t\tmargin: 1em 0;\n\t\t\tpadding: 0.5em;\n\t\t\toverflow-x: auto;\n\t\t}\n\t\t.pict-content .pict-content-katex-inline {\n\t\t\tdisplay: inline;\n\t\t}\n\n\t\t/* Fullscreen viewer for images and mermaid diagrams (click-to-zoom) */\n\t\t.pict-content [data-fullscreen-source] {\n\t\t\tcursor: zoom-in;\n\t\t\toutline: 1px solid transparent;\n\t\t\toutline-offset: 3px;\n\t\t\tborder-radius: 4px;\n\t\t\ttransition: outline-color 0.15s ease;\n\t\t}\n\t\t.pict-content [data-fullscreen-source]:hover {\n\t\t\toutline-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t/* Code block container with hover-revealed action buttons */\n\t\t.pict-content-code-container {\n\t\t\tposition: relative;\n\t\t\tdisplay: flex;\n\t\t\talign-items: flex-start;\n\t\t\tgap: 8px;\n\t\t\tmargin: 1em 0;\n\t\t}\n\t\t.pict-content-code-container > .pict-content-code-wrap {\n\t\t\tmargin: 0;\n\t\t\tflex: 1 1 auto;\n\t\t\tmin-width: 0;\n\t\t}\n\t\t.pict-content-code-actions {\n\t\t\tposition: sticky;\n\t\t\ttop: 64px;\n\t\t\talign-self: flex-start;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tgap: 6px;\n\t\t\tflex: 0 0 auto;\n\t\t\tpadding-top: 6px;\n\t\t\topacity: 0;\n\t\t\ttransform: translateX(-4px);\n\t\t\ttransition: opacity 0.15s ease, transform 0.15s ease;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t.pict-content-code-container:hover .pict-content-code-actions,\n\t\t.pict-content-code-container:focus-within .pict-content-code-actions {\n\t\t\topacity: 1;\n\t\t\ttransform: translateX(0);\n\t\t\tpointer-events: auto;\n\t\t}\n\t\t.pict-content-code-action-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 28px;\n\t\t\theight: 28px;\n\t\t\tpadding: 0;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-muted, #5E5549);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 6px;\n\t\t\tcursor: pointer;\n\t\t\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;\n\t\t}\n\t\t.pict-content-code-action-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 14px;\n\t\t\theight: 14px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.6;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-content-code-action-btn:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t}\n\t\t.pict-content-code-action-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-content-code-action-btn.is-copied {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.pict-content-code-action-btn.is-copy-failed {\n\t\t\tbackground: var(--theme-color-status-error, #B23A3A);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t\tborder-color: var(--theme-color-status-error, #B23A3A);\n\t\t}\n\t\t.pict-fullscreen-overlay {\n\t\t\tposition: fixed;\n\t\t\tinset: 0;\n\t\t\tz-index: 9999;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tbackground: rgba(0, 0, 0, 0.62);\n\t\t\tbackdrop-filter: blur(6px);\n\t\t\t-webkit-backdrop-filter: blur(6px);\n\t\t\tcolor: var(--theme-color-text-primary, #2A241E);\n\t\t}\n\t\t.pict-fullscreen-overlay[hidden] {\n\t\t\tdisplay: none;\n\t\t}\n\t\t.pict-fullscreen-titlebar {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: space-between;\n\t\t\tgap: 1em;\n\t\t\theight: 48px;\n\t\t\tpadding: 0 1em;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #1A1612);\n\t\t\tborder-bottom: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n\t\t\tflex: 0 0 auto;\n\t\t}\n\t\t.pict-fullscreen-title {\n\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\tletter-spacing: 0.01em;\n\t\t\twhite-space: nowrap;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t\tcolor: var(--theme-color-text-primary, #1A1612);\n\t\t}\n\t\t.pict-fullscreen-controls {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tgap: 4px;\n\t\t}\n\t\t.pict-fullscreen-btn {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\twidth: 32px;\n\t\t\theight: 32px;\n\t\t\tpadding: 0;\n\t\t\tbackground: transparent;\n\t\t\tborder: 1px solid transparent;\n\t\t\tborder-radius: 6px;\n\t\t\tcolor: var(--theme-color-text-muted, #5E5549);\n\t\t\tcursor: pointer;\n\t\t\ttransition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n\t\t}\n\t\t.pict-fullscreen-btn svg {\n\t\t\tdisplay: block;\n\t\t\twidth: 16px;\n\t\t\theight: 16px;\n\t\t\tstroke: currentColor;\n\t\t\tfill: none;\n\t\t\tstroke-width: 1.75;\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-linejoin: round;\n\t\t}\n\t\t.pict-fullscreen-btn:hover {\n\t\t\tbackground: var(--theme-color-border-light, #EAE3D8);\n\t\t\tcolor: var(--theme-color-text-primary, #1A1612);\n\t\t}\n\t\t.pict-fullscreen-btn:focus-visible {\n\t\t\toutline: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t\toutline-offset: 2px;\n\t\t}\n\t\t.pict-fullscreen-close:hover {\n\t\t\tbackground: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tcolor: var(--theme-color-text-on-brand, #FFFFFF);\n\t\t}\n\t\t.pict-fullscreen-stage {\n\t\t\tflex: 1 1 auto;\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\toverflow: hidden;\n\t\t\tpadding: 1.5em;\n\t\t\tcursor: zoom-in;\n\t\t\ttouch-action: none;\n\t\t}\n\t\t.pict-fullscreen-stage.is-zoomed {\n\t\t\tcursor: grab;\n\t\t}\n\t\t.pict-fullscreen-stage.is-panning {\n\t\t\tcursor: grabbing;\n\t\t}\n\t\t.pict-fullscreen-content {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmax-width: 100%;\n\t\t\tmax-height: 100%;\n\t\t\ttransform-origin: center center;\n\t\t\ttransition: transform 0.05s linear;\n\t\t\twill-change: transform;\n\t\t}\n\t\t.pict-fullscreen-content > * {\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-img {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\twidth: auto;\n\t\t\theight: auto;\n\t\t\tobject-fit: contain;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tpadding: 12px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-mermaid-svg {\n\t\t\twidth: min(90vw, 1400px);\n\t\t\theight: auto;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tpadding: 16px;\n\t\t\tborder-radius: 6px;\n\t\t}\n\t\t.pict-fullscreen-content .pict-fullscreen-codewrap {\n\t\t\tmax-width: 90vw;\n\t\t\tmax-height: calc(100vh - 96px);\n\t\t\tmargin: 0;\n\t\t\toverflow: auto;\n\t\t\tbox-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);\n\t\t}\n\t",Templates:[{Hash:"Pict-Content-Template",Template:/*html*/"\n<div class=\"pict-content\" id=\"Pict-Content-Body\">\n\t<div class=\"pict-content-loading\">Loading content...</div>\n</div>\n"}],Renderables:[{RenderableHash:"Pict-Content-Display",TemplateHash:"Pict-Content-Template",DestinationAddress:"#Pict-Content-Container",RenderMethod:"replace"}]};class PictContentView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}/**
|
|
6125
6151
|
* Display parsed HTML content in the content area.
|
|
6126
6152
|
*
|
|
6127
6153
|
* @param {string} pHTMLContent - The HTML to display
|
|
@@ -6136,8 +6162,31 @@ if(tmpContentContainer&&!tmpContentContainer.classList.contains('pict-content'))
|
|
|
6136
6162
|
// Mermaid blocks are tagged after mermaid.run() resolves (see below).
|
|
6137
6163
|
this.enableFullscreenViewers(tmpContainerID,{skipMermaid:true});// Post-render: initialize Mermaid diagrams if mermaid is available.
|
|
6138
6164
|
// Once mermaid finishes, retag so the rendered SVGs are also clickable.
|
|
6139
|
-
this.renderMermaidDiagrams(tmpContainerID);// Post-render: render
|
|
6165
|
+
this.renderMermaidDiagrams(tmpContainerID);// Post-render: render ```excalidraw fenced scenes if the
|
|
6166
|
+
// pict-section-excalidraw wrapper bundle is loaded. Each fence
|
|
6167
|
+
// becomes a static SVG (with the scene embedded for re-edit by
|
|
6168
|
+
// retold-content-system).
|
|
6169
|
+
this.renderExcalidrawDiagrams(tmpContainerID);// Post-render: render KaTeX equations if katex is available
|
|
6140
6170
|
this.renderKaTeXEquations(tmpContainerID);}/**
|
|
6171
|
+
* Render any `.pict-excalidraw-fence` placeholders inside the container
|
|
6172
|
+
* as static SVGs using the pict-section-excalidraw wrapper bundle's
|
|
6173
|
+
* exportToSvg helper. Each fence's scene JSON travels through a
|
|
6174
|
+
* URI-component-encoded data-scene attribute (placed there by the
|
|
6175
|
+
* markdown parser in Pict-Provider-Content).
|
|
6176
|
+
*
|
|
6177
|
+
* Gracefully degrades when the wrapper bundle isn't on the page:
|
|
6178
|
+
* leaves the loading placeholder visible with a one-time console hint.
|
|
6179
|
+
* Idempotent — placeholders carry `data-rendered="true"` after the
|
|
6180
|
+
* first pass so re-renders don't double-emit.
|
|
6181
|
+
*
|
|
6182
|
+
* @param {string} [pContainerID]
|
|
6183
|
+
*/renderExcalidrawDiagrams(pContainerID){if(typeof document==='undefined')return;let tmpContainerID=pContainerID||'Pict-Content-Body';let tmpContentBody=document.getElementById(tmpContainerID);if(!tmpContentBody)return;let tmpFences=tmpContentBody.querySelectorAll('.pict-excalidraw-fence:not([data-rendered])');if(tmpFences.length<1)return;let tmpVendor=typeof window!=='undefined'?window.PictSectionExcalidrawVendor:null;if(!tmpVendor||typeof tmpVendor.exportToSvg!=='function'){// Bundle not loaded — leave the placeholder visible. The host
|
|
6184
|
+
// can load the wrapper bundle and call renderExcalidrawDiagrams
|
|
6185
|
+
// again, or include the script tag in its HTML shell.
|
|
6186
|
+
if(this.log&&this.log.warn&&!this._excalidrawBundleWarnLogged){this.log.warn('pict-excalidraw fence(s) found but pict-section-excalidraw wrapper bundle is not loaded — leaving as placeholders.');this._excalidrawBundleWarnLogged=true;}return;}for(let i=0;i<tmpFences.length;i++){let tmpFence=tmpFences[i];let tmpEncoded=tmpFence.getAttribute('data-scene')||'';let tmpJson='';try{tmpJson=decodeURIComponent(tmpEncoded);}catch(pErr){tmpJson='';}let tmpScene;try{tmpScene=JSON.parse(tmpJson);}catch(pErr){this._renderExcalidrawFenceError(tmpFence,'Invalid scene JSON: '+pErr.message);continue;}let tmpExportArgs={elements:tmpScene.elements||[],appState:Object.assign({exportEmbedScene:true},tmpScene.appState||{}),files:tmpScene.files||{}};tmpVendor.exportToSvg(tmpExportArgs).then(pSvgEl=>{if(!pSvgEl)return;// Style the SVG to fit the fence's content width while preserving aspect.
|
|
6187
|
+
pSvgEl.removeAttribute('width');pSvgEl.removeAttribute('height');pSvgEl.setAttribute('style','max-width: 100%; height: auto;');tmpFence.innerHTML='';tmpFence.appendChild(pSvgEl);tmpFence.setAttribute('data-rendered','true');}).catch(pErr=>{this._renderExcalidrawFenceError(tmpFence,'Excalidraw render failed: '+(pErr&&pErr.message?pErr.message:pErr));});}}_renderExcalidrawFenceError(pFence,pMessage){pFence.setAttribute('data-rendered','true');pFence.classList.add('pict-excalidraw-fence-error');pFence.innerHTML='<div class="pict-excalidraw-fence-error-message"></div>';// Use textContent on the inner div so any user-supplied error
|
|
6188
|
+
// substrings (e.g. parser error positions) can't introduce HTML.
|
|
6189
|
+
let tmpMsg=pFence.querySelector('.pict-excalidraw-fence-error-message');if(tmpMsg)tmpMsg.textContent=pMessage;if(this.log&&this.log.warn)this.log.warn('pict-excalidraw fence: '+pMessage);}/**
|
|
6141
6190
|
* Initialize Mermaid with theme variables read from the active
|
|
6142
6191
|
* pict-provider-theme palette. Mermaid's `base` theme honors
|
|
6143
6192
|
* `themeVariables`, so the diagram colors (node fills, cluster
|
|
@@ -12652,7 +12701,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
12652
12701
|
// presumably different callback function.
|
|
12653
12702
|
// This makes sure that own properties are retained, so that
|
|
12654
12703
|
// decorations and such are not lost along the way.
|
|
12655
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],346:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],347:[function(require,module,exports){module.exports={"name":"pict-docuserve","version":"1.4.
|
|
12704
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],346:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],347:[function(require,module,exports){module.exports={"name":"pict-docuserve","version":"1.4.2","description":"Pict Documentation Server - A single-page documentation viewer built on Pict","main":"source/Pict-Application-Docuserve.js","bin":{"pict-docuserve":"source/cli/Docuserve-CLI-Run.js"},"files":["source/","dist/","html/"],"scripts":{"start":"node source/cli/Docuserve-CLI-Run.js serve","brand":"node node_modules/pict-section-theme/bin/pict-section-theme-brand.js --manifest ../../../Retold-Modules-Manifest.json --module pict-docuserve","build":"npx quack build && npx quack copy","build-docs":"npx quack build && npx quack copy && node source/cli/Docuserve-CLI-Run.js inject ./docs && node example_applications/build-examples.js stage-docs","serve-docs":"node source/cli/Docuserve-CLI-Run.js serve ./docs","serve-examples":"node example_applications/build-examples.js","test":"npx quack test","tests":"npx quack test -g","coverage":"npx quack coverage","prepublishOnly":"npm run build"},"author":"steven velozo <steven@velozo.com>","license":"MIT","dependencies":{"fable-serviceproviderbase":"^3.0.19","lunr":"^2.3.9","pict":"^1.0.372","pict-application":"^1.0.34","pict-provider":"^1.0.13","pict-section-code":"^1.0.11","pict-section-content":"^1.0.5","pict-section-histogram":"^1.0.1","pict-section-modal":"^1.1.4","pict-section-theme":"^1.0.6","pict-service-commandlineutility":"^1.0.19","pict-view":"^1.0.68"},"devDependencies":{"pict-docuserve":"^1.4.1","quackage":"^1.2.5"},"copyFilesSettings":{"whenFileExists":"overwrite"},"copyFiles":[{"from":"./html/*","to":"./dist/"}],"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"retold":{"brand":{"Hash":"pict-docuserve","Name":"Pict Docuserve","Tagline":"A documentation viewer built on Pict","Palette":"default","Icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-pict-docuserve-filled-light\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#692bbf\"/>\n\t\t<g clip-path=\"url(#frame-pict-docuserve-filled-light)\"><rect x=\"18\" y=\"30\" width=\"48\" height=\"48\" rx=\"8\" fill=\"#c13ccd\" opacity=\"0.9\"/>\n\t\t\t\t\t<rect x=\"30\" y=\"18\" width=\"48\" height=\"48\" rx=\"8\" fill=\"rgba(255,255,255,0.18)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"38\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">PD</text>\n\t</svg>","IconType":"svg","Favicon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-pict-docuserve-light\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#692bbf\"/>\n\t\t<g clip-path=\"url(#fav-pict-docuserve-light)\"><rect x=\"28\" y=\"16\" width=\"52\" height=\"52\" rx=\"9\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">P</text>\n\t</svg>","FaviconDark":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-pict-docuserve-dark\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#9a6fd8\"/>\n\t\t<g clip-path=\"url(#fav-pict-docuserve-dark)\"><rect x=\"28\" y=\"16\" width=\"52\" height=\"52\" rx=\"9\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">P</text>\n\t</svg>","Colors":{"Primary":"#692bbf","Secondary":"#c13ccd","PrimaryLight":"#692bbf","PrimaryDark":"#9a6fd8","SecondaryLight":"#c13ccd","SecondaryDark":"#d48adb"}}}};},{}],348:[function(require,module,exports){/**
|
|
12656
12705
|
* Docuserve-Brand — docuserve's own wordmark, used only as a fallback.
|
|
12657
12706
|
*
|
|
12658
12707
|
* Docuserve is a viewer: the docs being served dictate the brand, not
|
|
@@ -13983,18 +14032,68 @@ const _LocalStorageKeyPrefix='docuserve-section-playground';const _ViewConfigura
|
|
|
13983
14032
|
// postMessage required.
|
|
13984
14033
|
// ────────────────────────────────────────────────────────────────────────
|
|
13985
14034
|
function buildIframeSrcdoc(pConfig,pSpec,pBaseURL){// Defaults if the per-module _playground.json doesn't override.
|
|
13986
|
-
let tmpDefaults={SectionType:'pict-section-form',ApplicationGlobal:'PictFormApplication',ApplicationModule:'PictSectionForm',ManifestKey:'DefaultFormManifest',//
|
|
13987
|
-
//
|
|
13988
|
-
//
|
|
13989
|
-
//
|
|
13990
|
-
|
|
14035
|
+
let tmpDefaults={SectionType:'pict-section-form',ApplicationGlobal:'PictFormApplication',ApplicationModule:'PictSectionForm',ManifestKey:'DefaultFormManifest',// WrapperKind controls whether the resolved class is treated as a
|
|
14036
|
+
// PictApplication subclass (default) or as a PictView subclass that
|
|
14037
|
+
// the bootstrap will wrap in a synthesized PictApplication.
|
|
14038
|
+
// - "application": `window[ApplicationModule][ApplicationGlobal]`
|
|
14039
|
+
// already IS the PictApplication. (pict-section-form's pattern.)
|
|
14040
|
+
// - "view": the resolved class is a PictView; the bootstrap
|
|
14041
|
+
// synthesizes a wrapper PictApplication that registers it under
|
|
14042
|
+
// `ViewName` with config from `pictConfig[ViewConfigKey]`. This
|
|
14043
|
+
// is the path most UI-control modules take — they ship a view,
|
|
14044
|
+
// not an application, and don't need to author a wrapper class.
|
|
14045
|
+
WrapperKind:'application',ViewName:'Section-Playground-View',ViewConfigKey:'ViewConfig',// Optional DOM id where the section should mount. When set, the
|
|
14046
|
+
// iframe template includes <div id="<MountID>"></div> next to the
|
|
14047
|
+
// default #Section-Playground-Mount, AND the wrapper-synthesizer's
|
|
14048
|
+
// auto-target uses it instead of #Section-Playground-Mount. Lets
|
|
14049
|
+
// sections whose DefaultDestinationAddress doesn't already match
|
|
14050
|
+
// either the iframe slots or #Section-Playground-Mount declare
|
|
14051
|
+
// their own ID without overriding Renderables by hand.
|
|
14052
|
+
MountID:'',// Optional method on the view to call once after initialization
|
|
14053
|
+
// with seeded data. Use this for sections whose data is loaded
|
|
14054
|
+
// imperatively (e.g. pict-editor-timeline's `loadStoryboard`,
|
|
14055
|
+
// pict-section-equation's `setSolveResult`) rather than via a
|
|
14056
|
+
// `<X>DataAddress` config option. The value at
|
|
14057
|
+
// `BootstrapSeedAddress` (in `pict.AppData`) is the argument.
|
|
14058
|
+
BootstrapMethod:'',BootstrapSeedAddress:'',// Imports — each one is { Name, Source: 'cdn'|'bundled'|'local'|'esm', Version?, Path?, URL?, GlobalName?, ExportName? }.
|
|
14059
|
+
// Loading shapes:
|
|
14060
|
+
// cdn — <script src="https://cdn.jsdelivr.net/npm/<Name>@<Version>/dist/<Name>.min.js"></script>
|
|
14061
|
+
// local — <script src="<Path>"></script>; Path resolves against the docs root
|
|
14062
|
+
// esm — <script type="module">import { <ExportName> } from "<URL>"; window["<GlobalName>"] = <ExportName>;</script>
|
|
14063
|
+
// Use for ES-module-only packages (CodeJar 4.x, etc.) that
|
|
14064
|
+
// can't be loaded via plain <script src>. Bootstrap waits
|
|
14065
|
+
// on `window.<GlobalName>` before running the application.
|
|
14066
|
+
// Order matters: pict first, then anything that depends on it
|
|
14067
|
+
// (pict-application before any wrapper that needs synthesis),
|
|
14068
|
+
// then the section module last.
|
|
14069
|
+
Imports:[],// Stylesheets — each is { Source: 'cdn'|'local', Name?, Version?, Path? }.
|
|
14070
|
+
// Emitted as <link rel="stylesheet"> tags in the iframe head. Used by
|
|
14071
|
+
// sections that wrap external libraries with CSS (Toast UI Grid, KaTeX,
|
|
14072
|
+
// Mermaid pre-styled themes, …) so module authors don't have to inject
|
|
14073
|
+
// <link> tags from Application Code. Local sources are staged by the
|
|
14074
|
+
// `stage-playground` command alongside Imports.
|
|
14075
|
+
Stylesheets:[]};let tmpSpec=Object.assign({},tmpDefaults,pSpec||{});// Default Imports if none provided — minimum needed for a pict-section-form
|
|
13991
14076
|
// playground. Most callers will override this in _playground.json.
|
|
13992
|
-
let tmpImports=tmpSpec.Imports&&tmpSpec.Imports.length>0?tmpSpec.Imports:[{Name:'pict',Source:'cdn'},{Name:'pict-application',Source:'cdn'},{Name:'pict-section-form',Source:'cdn'},{Name:'pict-section-modal',Source:'cdn'},{Name:'pict-section-theme',Source:'cdn'}];// Build
|
|
14077
|
+
let tmpImports=tmpSpec.Imports&&tmpSpec.Imports.length>0?tmpSpec.Imports:[{Name:'pict',Source:'cdn'},{Name:'pict-application',Source:'cdn'},{Name:'pict-section-form',Source:'cdn'},{Name:'pict-section-modal',Source:'cdn'},{Name:'pict-section-theme',Source:'cdn'}];// Build script + stylesheet tags for every Import / Stylesheet.
|
|
14078
|
+
//
|
|
14079
|
+
// Imports — four sources:
|
|
13993
14080
|
// cdn — jsDelivr URL built from Name + Version
|
|
13994
14081
|
// local — Path relative to the docs root (resolved via <base href> tag
|
|
13995
14082
|
// we emit below, so the iframe's about:srcdoc origin doesn't
|
|
13996
14083
|
// break relative paths)
|
|
13997
|
-
|
|
14084
|
+
// esm — ES-module dynamic import emitted as <script type="module">; the
|
|
14085
|
+
// bootstrap waits on `window[GlobalName]` before running the app.
|
|
14086
|
+
// bundled — legacy alias, treated as cdn for compatibility.
|
|
14087
|
+
//
|
|
14088
|
+
// Stylesheets — same Source values minus 'esm' (CSS has no ESM concept).
|
|
14089
|
+
let tmpScriptTags='';let tmpESMImports=[];for(let i=0;i<tmpImports.length;i++){let tmpImport=tmpImports[i];if(tmpImport.Source==='esm'){// Defer to a single coalesced <script type="module"> at the
|
|
14090
|
+
// bottom so we can wait on all ESM globals before app init.
|
|
14091
|
+
tmpESMImports.push(tmpImport);continue;}let tmpSrc;if(tmpImport.Source==='local'){tmpSrc=tmpImport.Path;}else{let tmpVersion=tmpImport.Version||'1';tmpSrc='https://cdn.jsdelivr.net/npm/'+tmpImport.Name+'@'+tmpVersion+'/dist/'+tmpImport.Name+'.min.js';}tmpScriptTags+='<script src="'+tmpSrc+'"></script>\n';}// Stylesheet <link> tags — emitted into <head> before the script tags so
|
|
14092
|
+
// the section's first paint already has its external styles applied.
|
|
14093
|
+
let tmpStylesheets=Array.isArray(tmpSpec.Stylesheets)?tmpSpec.Stylesheets:[];let tmpLinkTags='';for(let i=0;i<tmpStylesheets.length;i++){let tmpStyle=tmpStylesheets[i];let tmpHref;if(tmpStyle.Source==='local'){tmpHref=tmpStyle.Path;}else{let tmpVersion=tmpStyle.Version||'1';let tmpStylePath=tmpStyle.Path||'dist/'+tmpStyle.Name+'.min.css';tmpHref='https://cdn.jsdelivr.net/npm/'+tmpStyle.Name+'@'+tmpVersion+'/'+tmpStylePath;}tmpLinkTags+='<link rel="stylesheet" href="'+tmpHref+'">\n';}// ESM imports — coalesced into one <script type="module"> that imports
|
|
14094
|
+
// each module, stamps the named export onto window[GlobalName], and
|
|
14095
|
+
// signals readiness via a single flag the bootstrap waits on.
|
|
14096
|
+
let tmpESMScript='';if(tmpESMImports.length>0){tmpESMScript+='<script type="module">\n';tmpESMScript+='window.__SectionPlaygroundESMReady = (async () => {\n';for(let i=0;i<tmpESMImports.length;i++){let tmpESM=tmpESMImports[i];let tmpURL=tmpESM.URL;if(!tmpURL&&tmpESM.Name){let tmpVersion=tmpESM.Version||'1';tmpURL='https://cdn.jsdelivr.net/npm/'+tmpESM.Name+'@'+tmpVersion+'/dist/'+tmpESM.Name+'.min.js';}let tmpExportName=tmpESM.ExportName||tmpESM.GlobalName||tmpESM.Name;let tmpGlobalName=tmpESM.GlobalName||tmpESM.ExportName||tmpESM.Name;tmpESMScript+=' try {\n';tmpESMScript+=' const mod = await import('+JSON.stringify(tmpURL)+');\n';tmpESMScript+=' window['+JSON.stringify(tmpGlobalName)+'] = mod['+JSON.stringify(tmpExportName)+'] || mod.default || mod;\n';tmpESMScript+=' } catch (err) {\n';tmpESMScript+=' console.error("ESM import failed for " + '+JSON.stringify(tmpURL)+', err);\n';tmpESMScript+=' throw err;\n';tmpESMScript+=' }\n';}tmpESMScript+='})();\n';tmpESMScript+='</script>\n';}// Caller passes an absolute base URL so local Imports + asset paths
|
|
13998
14097
|
// resolve against the parent's docs root. An about:srcdoc iframe
|
|
13999
14098
|
// has no base of its own — without the <base> tag, "playground/runtime/
|
|
14000
14099
|
// pict.min.js" 404s as "about:srcdoc/playground/runtime/pict.min.js".
|
|
@@ -14003,10 +14102,14 @@ let tmpBaseHref=pBaseURL||'';// JSON-encode each user config. We embed them ver
|
|
|
14003
14102
|
// iframe to call back to the parent.
|
|
14004
14103
|
function encode(pValue){// JSON.stringify of undefined → undefined; coerce to empty object.
|
|
14005
14104
|
let tmpEncoded=JSON.stringify(pValue===undefined?{}:pValue);// Defang </script> just in case a user pastes one in.
|
|
14006
|
-
return tmpEncoded.replace(/<\/script>/g,'<\\/script>');}let tmpManifestJSON=encode(pConfig.manifest);let tmpPictConfigJSON=encode(pConfig.pictConfig);let tmpAppConfigJSON=encode(pConfig.appConfig);let tmpAppDataJSON=encode(pConfig.appData);//
|
|
14105
|
+
return tmpEncoded.replace(/<\/script>/g,'<\\/script>');}let tmpManifestJSON=encode(pConfig.manifest);let tmpPictConfigJSON=encode(pConfig.pictConfig);let tmpAppConfigJSON=encode(pConfig.appConfig);let tmpAppDataJSON=encode(pConfig.appData);// Application Code editor — optional raw JS that runs as the body
|
|
14106
|
+
// of a function `(Base) => class`. Encoded as a JSON string so it
|
|
14107
|
+
// survives the srcdoc round-trip; the iframe wraps it with
|
|
14108
|
+
// `new Function('Base', source)` and expects a class back.
|
|
14109
|
+
let tmpApplicationJS=typeof pConfig.application==='string'?pConfig.application:'';let tmpApplicationJSON=JSON.stringify(tmpApplicationJS).replace(/<\/script>/g,'<\\/script>');// HTML. Theme picker is rendered into a slim topbar inside the iframe
|
|
14007
14110
|
// so the user can switch themes without leaving the page. The section
|
|
14008
14111
|
// itself mounts into the main content div below it.
|
|
14009
|
-
return'<!DOCTYPE html>\n'+'<html lang="en">\n'+'<head>\n'+'<meta charset="UTF-8">\n'+'<title>Section Playground</title>\n'+(tmpBaseHref?'<base href="'+tmpBaseHref+'">\n':'')+'<style>\n'+' html, body { height: 100%; margin: 0; }\n'+' body { display: flex; flex-direction: column; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }\n'+' #playground-topbar { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 14px; border-bottom: 1px solid var(--theme-color-border-default, #DDD6CA); background: var(--theme-color-background-panel, #FFFFFF); }\n'+' #playground-topbar-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--theme-color-text-muted, #8A7F72); }\n'+' #playground-topbar-controls { display: flex; align-items: center; gap: 8px; }\n'+' #playground-content { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 16px; background: var(--theme-color-background-primary, #FDFBF7); }\n'+' #playground-error { display: none; padding: 14px 18px; background: #FFF4F2; color: #B43A2E; border-bottom: 1px solid #B43A2E; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; white-space: pre-wrap; }\n'+' #playground-error.show { display: block; }\n'+'</style>\n'+tmpScriptTags+'</head>\n'+'<body>\n'+'<div id="playground-error"></div>\n'+'<div id="playground-topbar">\n'+' <div id="playground-topbar-title">Section Sandbox</div>\n'+' <div id="playground-topbar-controls">\n'+' <div id="Theme-Picker"></div>\n'+' <div id="Theme-ModeToggle"></div>\n'+' <div id="Theme-ScaleSelect"></div>\n'+' </div>\n'+'</div>\n'+'<div id="playground-content">\n'+' <!-- The section-form metacontroller renders into #Pict-Form-Container by default. -->\n'+' <!-- Other section types may use a different default; the spec drives the markup. -->\n'+' <div id="Pict-Form-Container"></div>\n'+' <div id="Section-Playground-Mount"></div>\n'+'</div>\n'+'<script>\n'+'(function() {\n'+' var manifest = '+tmpManifestJSON+';\n'+' var pictConfig = '+tmpPictConfigJSON+';\n'+' var appConfig = '+tmpAppConfigJSON+';\n'+' var appData = '+tmpAppDataJSON+';\n'+' var sectionType = '+JSON.stringify(tmpSpec.SectionType)+';\n'+' var applicationModule = '+JSON.stringify(tmpSpec.ApplicationModule)+';\n'+' var applicationGlobal = '+JSON.stringify(tmpSpec.ApplicationGlobal)+';\n'+' var manifestKey = '+JSON.stringify(tmpSpec.ManifestKey)+';\n'+'\n'+' function showError(msg) {\n'+' var el = document.getElementById("playground-error");\n'+' if (el) { el.textContent = msg; el.classList.add("show"); }\n'+' try { parent.postMessage({ type: "section-playground-error", message: msg }, "*"); } catch(e) {}\n'+' }\n'+'\n'+' function ready(fn) {\n'+' if (document.readyState !== "loading") { fn(); }\n'+' else { document.addEventListener("DOMContentLoaded", fn); }\n'+' }\n'+'\n'+' ready(function() {\n'+' try {\n'+' if (typeof Pict === "undefined") { throw new Error("pict bundle did not load — check the CDN imports in _playground.json"); }\n'+' var libSectionModule = window[applicationModule];\n'+' if (!libSectionModule) { throw new Error("Section module " + applicationModule + " is not loaded; check the Imports in _playground.json"); }\n'+' var ApplicationClass = libSectionModule[applicationGlobal] || libSectionModule;\n'+' if (typeof ApplicationClass !== "function") { throw new Error("Could not resolve " + applicationGlobal + " on " + applicationModule); }\n'+'\n'+' // Subclass via ES6 class extends — ApplicationClass is\n'+' // (in modern builds) a real class, which throws if invoked\n'+' // via .call() without new. class extends handles both ES6\n'+' // classes and old-style prototype constructors.\n'+' class PlaygroundApplication extends ApplicationClass {}\n'+'\n'+' // Merge user-supplied pict_configuration onto the section\'s default.\n'+' var basePict = (ApplicationClass.default_configuration && ApplicationClass.default_configuration.pict_configuration) || {};\n'+' var mergedPict = Object.assign({}, basePict, pictConfig);\n'+' mergedPict[manifestKey] = manifest;\n'+' if (appData !== undefined) { mergedPict.DefaultAppData = appData; }\n'+'\n'+' var defaultConfig = Object.assign({}, ApplicationClass.default_configuration || {}, appConfig);\n'+' defaultConfig.pict_configuration = mergedPict;\n'+' PlaygroundApplication.default_configuration = defaultConfig;\n'+'\n'+' // Pict.safeLoadPictApplication will instantiate and run lifecycle.\n'+' Pict.safeOnDocumentReady(function() {\n'+' Pict.safeLoadPictApplication(PlaygroundApplication, 2);\n'+' // Mount the theme controls once the app is up.\n'+' setTimeout(function() {\n'+' try {\n'+' if (window.PictSectionTheme && window._Pict && typeof window._Pict.addProvider === "function") {\n'+' if (!window._Pict.providers || !window._Pict.providers["Theme-Section"]) {\n'+' window._Pict.addProvider("Theme-Section", { ApplyDefault: "pict-default", DefaultMode: "system", DefaultScale: 1.0, Views: ["Picker", "ModeToggle", "ScaleSelect"] }, window.PictSectionTheme);\n'+' window._Pict.views["Theme-Picker"].render();\n'+' if (window._Pict.views["Theme-ModeToggle"]) { window._Pict.views["Theme-ModeToggle"].render(); }\n'+' if (window._Pict.views["Theme-ScaleSelect"]) { window._Pict.views["Theme-ScaleSelect"].render(); }\n'+' }\n'+' }\n'+' } catch (themeErr) { /* theme bootstrap is best-effort */ }\n'+' }, 50);\n'+' try { parent.postMessage({ type: "section-playground-ready" }, "*"); } catch(e) {}\n'+' });\n'+' } catch (err) {\n'+' showError(String(err && err.stack ? err.stack : err));\n'+' }\n'+' });\n'+'}());\n'+'</script>\n'+'</body>\n'+'</html>';}class DocuserveSectionPlaygroundView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);// Editor metadata — populated when the playground is opened for
|
|
14112
|
+
return'<!DOCTYPE html>\n'+'<html lang="en">\n'+'<head>\n'+'<meta charset="UTF-8">\n'+'<title>Section Playground</title>\n'+(tmpBaseHref?'<base href="'+tmpBaseHref+'">\n':'')+'<style>\n'+' html, body { height: 100%; margin: 0; }\n'+' body { display: flex; flex-direction: column; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }\n'+' #playground-topbar { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 14px; border-bottom: 1px solid var(--theme-color-border-default, #DDD6CA); background: var(--theme-color-background-panel, #FFFFFF); }\n'+' #playground-topbar-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--theme-color-text-muted, #8A7F72); }\n'+' #playground-topbar-controls { display: flex; align-items: center; gap: 8px; }\n'+' #playground-content { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 16px; background: var(--theme-color-background-primary, #FDFBF7); }\n'+' #playground-error { display: none; padding: 14px 18px; background: #FFF4F2; color: #B43A2E; border-bottom: 1px solid #B43A2E; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; white-space: pre-wrap; }\n'+' #playground-error.show { display: block; }\n'+'</style>\n'+tmpLinkTags+tmpScriptTags+tmpESMScript+'</head>\n'+'<body>\n'+'<div id="playground-error"></div>\n'+'<div id="playground-topbar">\n'+' <div id="playground-topbar-title">Section Sandbox</div>\n'+' <div id="playground-topbar-controls">\n'+' <div id="Theme-Picker"></div>\n'+' <div id="Theme-ModeToggle"></div>\n'+' <div id="Theme-ScaleSelect"></div>\n'+' </div>\n'+'</div>\n'+'<div id="playground-content">\n'+' <!-- The section-form metacontroller renders into #Pict-Form-Container by default. -->\n'+' <!-- Other section types may use a different default; the spec drives the markup. -->\n'+' <div id="Pict-Form-Container"></div>\n'+' <div id="Section-Playground-Mount"></div>\n'+(tmpSpec.MountID?' <div id="'+tmpSpec.MountID+'"></div>\n':'')+'</div>\n'+'<script>\n'+'(function() {\n'+' var manifest = '+tmpManifestJSON+';\n'+' var pictConfig = '+tmpPictConfigJSON+';\n'+' var appConfig = '+tmpAppConfigJSON+';\n'+' var appData = '+tmpAppDataJSON+';\n'+' var applicationSource = '+tmpApplicationJSON+';\n'+' var sectionType = '+JSON.stringify(tmpSpec.SectionType)+';\n'+' var applicationModule = '+JSON.stringify(tmpSpec.ApplicationModule)+';\n'+' var applicationGlobal = '+JSON.stringify(tmpSpec.ApplicationGlobal)+';\n'+' var manifestKey = '+JSON.stringify(tmpSpec.ManifestKey)+';\n'+' var wrapperKind = '+JSON.stringify(tmpSpec.WrapperKind)+';\n'+' var viewName = '+JSON.stringify(tmpSpec.ViewName)+';\n'+' var viewConfigKey = '+JSON.stringify(tmpSpec.ViewConfigKey)+';\n'+' var mountID = '+JSON.stringify(tmpSpec.MountID)+';\n'+' var bootstrapMethod = '+JSON.stringify(tmpSpec.BootstrapMethod)+';\n'+' var bootstrapSeedAddr = '+JSON.stringify(tmpSpec.BootstrapSeedAddress)+';\n'+'\n'+' function showError(msg) {\n'+' var el = document.getElementById("playground-error");\n'+' if (el) { el.textContent = msg; el.classList.add("show"); }\n'+' try { parent.postMessage({ type: "section-playground-error", message: msg }, "*"); } catch(e) {}\n'+' }\n'+'\n'+' function ready(fn) {\n'+' if (document.readyState !== "loading") { fn(); }\n'+' else { document.addEventListener("DOMContentLoaded", fn); }\n'+' }\n'+'\n'+' function awaitESM() {\n'+' return (window.__SectionPlaygroundESMReady && typeof window.__SectionPlaygroundESMReady.then === "function")\n'+' ? window.__SectionPlaygroundESMReady\n'+' : Promise.resolve();\n'+' }\n'+'\n'+' ready(function() {\n'+' awaitESM().then(function() { try {\n'+' if (typeof Pict === "undefined") { throw new Error("pict bundle did not load — check the CDN imports in _playground.json"); }\n'+' var libSectionModule = window[applicationModule];\n'+' if (!libSectionModule) { throw new Error("Section module " + applicationModule + " is not loaded; check the Imports in _playground.json"); }\n'+' var ResolvedClass = libSectionModule[applicationGlobal] || libSectionModule;\n'+' if (typeof ResolvedClass !== "function") { throw new Error("Could not resolve " + applicationGlobal + " on " + applicationModule); }\n'+'\n'+' // Wrapper resolution. Two paths:\n'+' // 1. WrapperKind: "application" (default) — the resolved class\n'+' // is already a PictApplication subclass; use it directly.\n'+' // pict-section-form\'s pattern.\n'+' // 2. WrapperKind: "view" — the resolved class is a PictView; the\n'+' // bootstrap synthesizes a PictApplication subclass that\n'+' // registers the view under `viewName` with config drawn\n'+' // from pictConfig[viewConfigKey]. This is the no-wrapper\n'+' // path: section modules ship just their view class and a\n'+' // _playground.json — no per-module Application file needed.\n'+' var BaseApplicationClass;\n'+' if (wrapperKind === "view") {\n'+' if (typeof window.PictApplication !== "function") { throw new Error("WrapperKind: \\"view\\" requires pict-application to be loaded — add it to Imports in _playground.json"); }\n'+' var ViewClass = ResolvedClass;\n'+' // PictApplication is an ES6 class, so the wrapper MUST be one\n'+' // too — ES6 classes throw "cannot be invoked without new" when\n'+' // called via `.call(this, ...)`, so the prototype-style pattern\n'+' // (function + Object.create) silently fails at construction.\n'+' // Build the class via a Function constructor so we can keep\n'+' // closure access to viewName / viewConfigKey / mountID / etc.\n'+' var BuildWrapperClass = new Function(\n'+' "PictApplication", "ViewClass", "pictConfig", "viewName", "viewConfigKey", "mountID", "bootstrapMethod", "bootstrapSeedAddr",\n'+' "return class ViewWrapperApplication extends PictApplication {"\n'+' + " constructor(pFable, pOptions, pServiceHash) {"\n'+' + " super(pFable, pOptions, pServiceHash);"\n'+' + " var tmpDefaultViewConfig = (ViewClass.default_configuration || {});"\n'+' + " var tmpInjectedViewConfig = (pictConfig && pictConfig[viewConfigKey]) || {};"\n'+' + " var tmpMergedViewConfig = Object.assign({}, tmpDefaultViewConfig, tmpInjectedViewConfig);"\n'+' + " var tmpAutoMount = \\"#\\" + (mountID || \\"Section-Playground-Mount\\");"\n'+' + " if (typeof tmpInjectedViewConfig.DefaultDestinationAddress === \\"undefined\\") {"\n'+' + " tmpMergedViewConfig.DefaultDestinationAddress = tmpAutoMount;"\n'+' + " if (Array.isArray(tmpDefaultViewConfig.Renderables)) {"\n'+' + " tmpMergedViewConfig.Renderables = tmpDefaultViewConfig.Renderables.map(function(pRenderable) {"\n'+' + " return Object.assign({}, pRenderable, { DestinationAddress: tmpAutoMount });"\n'+' + " });"\n'+' + " }"\n'+' + " }"\n'+' + " this.pict.addView(viewName, tmpMergedViewConfig, ViewClass);"\n'+' + " }"\n'+' + " onAfterInitialize() {"\n'+' + " super.onAfterInitialize();"\n'+' + " var tmpView = this.pict.views[viewName];"\n'+' + " if (bootstrapMethod && tmpView && typeof tmpView[bootstrapMethod] === \\"function\\") {"\n'+' + " try {"\n'+' + " var tmpSeed;"\n'+' + " if (bootstrapSeedAddr && this.pict && this.pict.manifest && typeof this.pict.manifest.getValueByHash === \\"function\\") {"\n'+' + " tmpSeed = this.pict.manifest.getValueByHash(this.pict.AppData, bootstrapSeedAddr);"\n'+' + " }"\n'+' + " tmpView[bootstrapMethod](tmpSeed);"\n'+' + " } catch (seedErr) { console.warn(\\"BootstrapMethod \\" + bootstrapMethod + \\" threw:\\", seedErr); }"\n'+' + " }"\n'+' + " if (tmpView && typeof tmpView.render === \\"function\\") { tmpView.render(); }"\n'+' + " }"\n'+' + "};"\n'+' );\n'+' BaseApplicationClass = BuildWrapperClass(window.PictApplication, ViewClass, pictConfig, viewName, viewConfigKey, mountID, bootstrapMethod, bootstrapSeedAddr);\n'+' // Carry through whatever defaults the view itself ships, so\n'+' // pict_configuration / Product / Hash stay sensible if the\n'+' // user has not provided their own appConfig / pictConfig.\n'+' BaseApplicationClass.default_configuration = (ViewClass.default_configuration && ViewClass.default_configuration.pict_configuration)\n'+' ? ViewClass.default_configuration\n'+' : { pict_configuration: {} };\n'+' } else {\n'+' BaseApplicationClass = ResolvedClass;\n'+' }\n'+'\n'+' // Subclass. If the user supplied Application Code,\n'+' // wrap it as `function (Base) { ...userBody... }` and\n'+' // expect it to return a class. Otherwise fall back to\n'+' // a no-op extends-Base subclass. class extends handles\n'+' // both ES6 classes and old-style prototype constructors.\n'+' var PlaygroundApplication;\n'+' if (typeof applicationSource === "string" && applicationSource.trim().length > 0) {\n'+' try {\n'+' var customizerFn = new Function("Base", applicationSource);\n'+' var customizerResult = customizerFn(BaseApplicationClass);\n'+' if (typeof customizerResult !== "function") {\n'+' throw new Error("Application Code must `return` a class. Got " + (typeof customizerResult) + ".");\n'+' }\n'+' PlaygroundApplication = customizerResult;\n'+' } catch (customizerErr) {\n'+' throw new Error("Application Code error: " + (customizerErr && customizerErr.message ? customizerErr.message : customizerErr));\n'+' }\n'+' } else {\n'+' PlaygroundApplication = class extends BaseApplicationClass {};\n'+' }\n'+'\n'+' // Precedence: Base class defaults < user-class defaults\n'+' // (if Application Code set its own) < the four editor tabs.\n'+' // The editor tabs are what the playground exists to drive,\n'+' // so they always win.\n'+' var userDefault = PlaygroundApplication.default_configuration || BaseApplicationClass.default_configuration || {};\n'+' var basePict = userDefault.pict_configuration || {};\n'+' var mergedPict = Object.assign({}, basePict, pictConfig);\n'+' mergedPict[manifestKey] = manifest;\n'+' if (appData !== undefined) { mergedPict.DefaultAppData = appData; }\n'+'\n'+' var defaultConfig = Object.assign({}, userDefault, appConfig);\n'+' defaultConfig.pict_configuration = mergedPict;\n'+' PlaygroundApplication.default_configuration = defaultConfig;\n'+'\n'+' // Pict.safeLoadPictApplication will instantiate and run lifecycle.\n'+' Pict.safeOnDocumentReady(function() {\n'+' Pict.safeLoadPictApplication(PlaygroundApplication, 2);\n'+' // Mount the theme controls once the app is up.\n'+' setTimeout(function() {\n'+' try {\n'+' if (window.PictSectionTheme && window._Pict && typeof window._Pict.addProvider === "function") {\n'+' if (!window._Pict.providers || !window._Pict.providers["Theme-Section"]) {\n'+' window._Pict.addProvider("Theme-Section", { ApplyDefault: "pict-default", DefaultMode: "system", DefaultScale: 1.0, Views: ["Picker", "ModeToggle", "ScaleSelect"] }, window.PictSectionTheme);\n'+' window._Pict.views["Theme-Picker"].render();\n'+' if (window._Pict.views["Theme-ModeToggle"]) { window._Pict.views["Theme-ModeToggle"].render(); }\n'+' if (window._Pict.views["Theme-ScaleSelect"]) { window._Pict.views["Theme-ScaleSelect"].render(); }\n'+' }\n'+' }\n'+' } catch (themeErr) { /* theme bootstrap is best-effort */ }\n'+' }, 50);\n'+' try { parent.postMessage({ type: "section-playground-ready" }, "*"); } catch(e) {}\n'+' });\n'+' } catch (err) {\n'+' showError(String(err && err.stack ? err.stack : err));\n'+' } }).catch(function(esmErr) {\n'+' showError("ESM import failed: " + String(esmErr && esmErr.message ? esmErr.message : esmErr));\n'+' });\n'+' });\n'+'}());\n'+'</script>\n'+'</body>\n'+'</html>';}class DocuserveSectionPlaygroundView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);// Editor metadata — populated when the playground is opened for
|
|
14010
14113
|
// a specific module. Each entry mirrors the _playground.json
|
|
14011
14114
|
// Editors[] descriptor + activation state.
|
|
14012
14115
|
this._editors=[];this._activeHash=null;// (group, module) currently mounted; used to scope localStorage.
|
|
@@ -14187,9 +14290,23 @@ let tmpGroupRoute=tmpGroup.Route||'';if(!tmpGroupRoute){for(let k=0;k<tmpGroup.M
|
|
|
14187
14290
|
// new section each time the title changes.
|
|
14188
14291
|
if(tmpSidebar&&tmpSidebar.length>0){let tmpCurrentSection=null;for(let i=0;i<tmpSidebar.length;i++){let tmpEntry=tmpSidebar[i];if(tmpEntry.Children){tmpCurrentSection={TitleSlot:[{Title:tmpEntry.Title}],Items:[]};tmpSections.push(tmpCurrentSection);for(let j=0;j<tmpEntry.Children.length;j++){let tmpChild=tmpEntry.Children[j];if(tmpChild.Path){tmpCurrentSection.Items.push({Title:tmpChild.Title,Route:tmpRoutePrefix+tmpChild.Path,ActiveClass:''});}}}else if(tmpEntry.Path){if(!tmpCurrentSection||tmpCurrentSection.TitleSlot.length>0){tmpCurrentSection={TitleSlot:[],Items:[]};tmpSections.push(tmpCurrentSection);}tmpCurrentSection.Items.push({Title:tmpEntry.Title,Route:tmpRoutePrefix+tmpEntry.Path,ActiveClass:''});}}}// Demos sub-section: titled, with active state mirroring the
|
|
14189
14292
|
// current demo route.
|
|
14190
|
-
if(tmpDemos.length>0){let tmpDemoSection={TitleSlot:[{Title:'Demos'}],Items:[]};for(let i=0;i<tmpDemos.length;i++){let tmpDemo=tmpDemos[i];tmpDemoSection.Items.push({Title:tmpDemo.Name||tmpDemo.Hash,Route:tmpDemoPrefix+tmpDemo.Hash,ActiveClass:tmpDemo.Hash===tmpCurrentDemo?'active':''});}tmpSections.push(tmpDemoSection);}this.pict.AppData.Docuserve.ModuleNavSections=tmpSections;}_refreshSearchResults(pQuery){let tmpDocuserve=this.pict.AppData.Docuserve;if(!pQuery||!pQuery.trim()){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[];return;}let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];let tmpResults=tmpDocProvider.search(pQuery);if(tmpResults.length===0){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[{}];return;}let tmpMaxResults=8;let tmpDisplayResults=[];for(let i=0;i<tmpResults.length&&i<tmpMaxResults;i++){let tmpResult=tmpResults[i];let tmpMeta=tmpResult.Group&&tmpResult.Module?tmpResult.Group+' / '+tmpResult.Module:'';tmpDisplayResults.push({Title:tmpResult.Title,Route:tmpResult.Route,MetaSlot:tmpMeta?[{Meta:tmpMeta}]:[]});}tmpDocuserve.SidebarSearchResults=tmpDisplayResults;tmpDocuserve.SidebarSearchEmpty=[];if(tmpResults.length>tmpMaxResults){tmpDocuserve.SidebarSearchOverflow=[{EncodedQuery:encodeURIComponent(pQuery),TotalCount:tmpResults.length}];}else{tmpDocuserve.SidebarSearchOverflow=[];}}}module.exports=DocusserveSidebarView;module.exports.default_configuration=_ViewConfiguration;},{"pict-view":231}],360:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"Docuserve-Splash",DefaultRenderable:"Docuserve-Splash-Content",DefaultDestinationAddress:"#Docuserve-Content-Container",AutoRender:false,CSS:/*css*/"\n\t\t.docuserve-splash {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: calc(100vh - 56px);\n\t\t\tpadding: 3em 2em;\n\t\t\ttext-align: center;\n\t\t\tbackground: var(--theme-color-background-primary, #FDFBF7);\n\t\t}\n\t\t.docuserve-splash h1 {\n\t\t\tfont-size: 3em;\n\t\t\tfont-weight: 700;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin: 0 0 0.25em 0;\n\t\t}\n\t\t.docuserve-splash h1 small {\n\t\t\tfont-size: 0.4em;\n\t\t\tfont-weight: 400;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tvertical-align: middle;\n\t\t\tmargin-left: 0.15em;\n\t\t}\n\t\t.docuserve-splash-tagline {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-bottom: 1.5em;\n\t\t\tfont-style: italic;\n\t\t}\n\t\t.docuserve-splash-description {\n\t\t\tfont-size: 1em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmax-width: 600px;\n\t\t\tline-height: 1.7;\n\t\t\tmargin-bottom: 2em;\n\t\t}\n\t\t.docuserve-splash-highlights {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n\t\t\tgap: 1.25em;\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t.docuserve-splash-highlight-card {\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\tpadding: 1.25em;\n\t\t\ttext-align: left;\n\t\t\ttransition: box-shadow 0.2s, border-color 0.2s;\n\t\t}\n\t\t.docuserve-splash-highlight-card:hover {\n\t\t\tbox-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-highlight-card h3 {\n\t\t\tmargin: 0 0 0.5em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.docuserve-splash-highlight-card p {\n\t\t\tmargin: 0;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tfont-size: 0.85em;\n\t\t\tline-height: 1.5;\n\t\t}\n\t\t.docuserve-splash-actions {\n\t\t\tdisplay: flex;\n\t\t\tgap: 1em;\n\t\t\tflex-wrap: wrap;\n\t\t\tjustify-content: center;\n\t\t}\n\t\t.docuserve-splash-actions a {\n\t\t\tdisplay: inline-block;\n\t\t\tpadding: 0.7em 1.5em;\n\t\t\tborder-radius: 6px;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t\ttransition: background-color 0.15s, color 0.15s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-splash-actions .primary {\n\t\t\tbackground-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\t/* text-on-brand falls to a fixed light hex \u2014 never to background-panel,\n\t\t\t which inverts contrast in dark themes (dark text on brand bg). */\n\t\t\tcolor: var(--theme-color-text-on-brand, #fff);\n\t\t}\n\t\t.docuserve-splash-actions .primary:hover {\n\t\t\tbackground-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t}\n\t\t.docuserve-splash-actions .secondary {\n\t\t\tbackground-color: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-actions .secondary:hover {\n\t\t\tborder-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-examples {\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t/* No staged examples \u2014 collapse the section entirely. */\n\t\t.docuserve-splash-examples:empty {\n\t\t\tdisplay: none;\n\t\t\tmargin: 0;\n\t\t}\n\t\t.docuserve-splash-examples-heading {\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 700;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.08em;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tmargin: 0 0 0.85em 0;\n\t\t}\n\t\t.docuserve-splash-examples table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\toverflow: hidden;\n\t\t}\n\t\t.docuserve-splash-examples thead th {\n\t\t\ttext-align: left;\n\t\t\tfont-size: 0.72em;\n\t\t\tfont-weight: 700;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.06em;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tpadding: 0.7em 1.1em;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F4EFE6);\n\t\t}\n\t\t.docuserve-splash-examples tbody td {\n\t\t\tpadding: 0.7em 1.1em;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\ttext-align: left;\n\t\t}\n\t\t.docuserve-splash-examples tbody tr:hover td {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F4EFE6);\n\t\t}\n\t\t.docuserve-splash-examples a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-splash-examples a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* docs/README.md content rendered beneath the hero. */\n\t\t.docuserve-splash-readme {\n\t\t\tmax-width: 820px;\n\t\t\tmargin: 0 auto;\n\t\t\tpadding: 3.5em 2em 5em 2em;\n\t\t\ttext-align: left;\n\t\t}\n\t\t.docuserve-splash-readme:empty {\n\t\t\tdisplay: none;\n\t\t}\n\t",Templates:[{Hash:"Docuserve-Splash-Template",Template:/*html*/"\n<div class=\"docuserve-splash\">\n\t<h1 id=\"Docuserve-Splash-Title\"></h1>\n\t<div class=\"docuserve-splash-tagline\" id=\"Docuserve-Splash-Tagline\"></div>\n\t<div class=\"docuserve-splash-description\" id=\"Docuserve-Splash-Description\"></div>\n\t<div class=\"docuserve-splash-highlights\" id=\"Docuserve-Splash-Highlights\"></div>\n\t<div class=\"docuserve-splash-examples\" id=\"Docuserve-Splash-Examples\"></div>\n\t<div class=\"docuserve-splash-actions\" id=\"Docuserve-Splash-Actions\"></div>\n</div>\n<div class=\"docuserve-splash-readme\" id=\"Docuserve-Splash-Readme\"></div>\n"}],Renderables:[{RenderableHash:"Docuserve-Splash-Content",TemplateHash:"Docuserve-Splash-Template",DestinationAddress:"#Docuserve-Content-Container",RenderMethod:"replace"}]};class DocusserveSplashView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}onAfterRender(pRenderable,pRenderDestinationAddress,pRecord,pContent){let tmpDocuserve=this.pict.AppData.Docuserve;if(tmpDocuserve.CoverLoaded&&tmpDocuserve.Cover){this.renderFromCover(tmpDocuserve.Cover);this.renderExamples(tmpDocuserve.Cover);}else{this.renderFromCatalog(tmpDocuserve);}//
|
|
14293
|
+
if(tmpDemos.length>0){let tmpDemoSection={TitleSlot:[{Title:'Demos'}],Items:[]};for(let i=0;i<tmpDemos.length;i++){let tmpDemo=tmpDemos[i];tmpDemoSection.Items.push({Title:tmpDemo.Name||tmpDemo.Hash,Route:tmpDemoPrefix+tmpDemo.Hash,ActiveClass:tmpDemo.Hash===tmpCurrentDemo?'active':''});}tmpSections.push(tmpDemoSection);}this.pict.AppData.Docuserve.ModuleNavSections=tmpSections;}_refreshSearchResults(pQuery){let tmpDocuserve=this.pict.AppData.Docuserve;if(!pQuery||!pQuery.trim()){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[];return;}let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];let tmpResults=tmpDocProvider.search(pQuery);if(tmpResults.length===0){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[{}];return;}let tmpMaxResults=8;let tmpDisplayResults=[];for(let i=0;i<tmpResults.length&&i<tmpMaxResults;i++){let tmpResult=tmpResults[i];let tmpMeta=tmpResult.Group&&tmpResult.Module?tmpResult.Group+' / '+tmpResult.Module:'';tmpDisplayResults.push({Title:tmpResult.Title,Route:tmpResult.Route,MetaSlot:tmpMeta?[{Meta:tmpMeta}]:[]});}tmpDocuserve.SidebarSearchResults=tmpDisplayResults;tmpDocuserve.SidebarSearchEmpty=[];if(tmpResults.length>tmpMaxResults){tmpDocuserve.SidebarSearchOverflow=[{EncodedQuery:encodeURIComponent(pQuery),TotalCount:tmpResults.length}];}else{tmpDocuserve.SidebarSearchOverflow=[];}}}module.exports=DocusserveSidebarView;module.exports.default_configuration=_ViewConfiguration;},{"pict-view":231}],360:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"Docuserve-Splash",DefaultRenderable:"Docuserve-Splash-Content",DefaultDestinationAddress:"#Docuserve-Content-Container",AutoRender:false,CSS:/*css*/"\n\t\t.docuserve-splash {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: calc(100vh - 56px);\n\t\t\tpadding: 3em 2em;\n\t\t\ttext-align: center;\n\t\t\tbackground: var(--theme-color-background-primary, #FDFBF7);\n\t\t}\n\t\t.docuserve-splash h1 {\n\t\t\tfont-size: 3em;\n\t\t\tfont-weight: 700;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin: 0 0 0.25em 0;\n\t\t}\n\t\t.docuserve-splash h1 small {\n\t\t\tfont-size: 0.4em;\n\t\t\tfont-weight: 400;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tvertical-align: middle;\n\t\t\tmargin-left: 0.15em;\n\t\t}\n\t\t.docuserve-splash-tagline {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-bottom: 1.5em;\n\t\t\tfont-style: italic;\n\t\t}\n\t\t.docuserve-splash-description {\n\t\t\tfont-size: 1em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmax-width: 600px;\n\t\t\tline-height: 1.7;\n\t\t\tmargin-bottom: 2em;\n\t\t}\n\t\t.docuserve-splash-highlights {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n\t\t\tgap: 1.25em;\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t.docuserve-splash-highlight-card {\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\tpadding: 1.25em;\n\t\t\ttext-align: left;\n\t\t\ttransition: box-shadow 0.2s, border-color 0.2s;\n\t\t}\n\t\t.docuserve-splash-highlight-card:hover {\n\t\t\tbox-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-highlight-card h3 {\n\t\t\tmargin: 0 0 0.5em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.docuserve-splash-highlight-card p {\n\t\t\tmargin: 0;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tfont-size: 0.85em;\n\t\t\tline-height: 1.5;\n\t\t}\n\t\t.docuserve-splash-actions {\n\t\t\tdisplay: flex;\n\t\t\tgap: 1em;\n\t\t\tflex-wrap: wrap;\n\t\t\tjustify-content: center;\n\t\t}\n\t\t.docuserve-splash-actions a {\n\t\t\tdisplay: inline-block;\n\t\t\tpadding: 0.7em 1.5em;\n\t\t\tborder-radius: 6px;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t\ttransition: background-color 0.15s, color 0.15s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-splash-actions .primary {\n\t\t\tbackground-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\t/* text-on-brand falls to a fixed light hex \u2014 never to background-panel,\n\t\t\t which inverts contrast in dark themes (dark text on brand bg). */\n\t\t\tcolor: var(--theme-color-text-on-brand, #fff);\n\t\t}\n\t\t.docuserve-splash-actions .primary:hover {\n\t\t\tbackground-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t}\n\t\t.docuserve-splash-actions .secondary {\n\t\t\tbackground-color: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-actions .secondary:hover {\n\t\t\tborder-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-examples {\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t/* No staged examples \u2014 collapse the section entirely. */\n\t\t.docuserve-splash-examples:empty {\n\t\t\tdisplay: none;\n\t\t\tmargin: 0;\n\t\t}\n\t\t.docuserve-splash-examples-heading {\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 700;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.08em;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tmargin: 0 0 0.85em 0;\n\t\t}\n\t\t.docuserve-splash-examples table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\toverflow: hidden;\n\t\t}\n\t\t.docuserve-splash-examples thead th {\n\t\t\ttext-align: left;\n\t\t\tfont-size: 0.72em;\n\t\t\tfont-weight: 700;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.06em;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tpadding: 0.7em 1.1em;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F4EFE6);\n\t\t}\n\t\t.docuserve-splash-examples tbody td {\n\t\t\tpadding: 0.7em 1.1em;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\ttext-align: left;\n\t\t}\n\t\t.docuserve-splash-examples tbody tr:hover td {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F4EFE6);\n\t\t}\n\t\t.docuserve-splash-examples a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-splash-examples a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* docs/README.md content rendered beneath the hero. */\n\t\t.docuserve-splash-readme {\n\t\t\tmax-width: 820px;\n\t\t\tmargin: 0 auto;\n\t\t\tpadding: 3.5em 2em 5em 2em;\n\t\t\ttext-align: left;\n\t\t}\n\t\t.docuserve-splash-readme:empty {\n\t\t\tdisplay: none;\n\t\t}\n\t",Templates:[{Hash:"Docuserve-Splash-Template",Template:/*html*/"\n<div class=\"docuserve-splash\">\n\t<h1 id=\"Docuserve-Splash-Title\"></h1>\n\t<div class=\"docuserve-splash-tagline\" id=\"Docuserve-Splash-Tagline\"></div>\n\t<div class=\"docuserve-splash-description\" id=\"Docuserve-Splash-Description\"></div>\n\t<div class=\"docuserve-splash-highlights\" id=\"Docuserve-Splash-Highlights\"></div>\n\t<div class=\"docuserve-splash-examples\" id=\"Docuserve-Splash-Examples\"></div>\n\t<div class=\"docuserve-splash-actions\" id=\"Docuserve-Splash-Actions\"></div>\n</div>\n<div class=\"docuserve-splash-readme\" id=\"Docuserve-Splash-Readme\"></div>\n"}],Renderables:[{RenderableHash:"Docuserve-Splash-Content",TemplateHash:"Docuserve-Splash-Template",DestinationAddress:"#Docuserve-Content-Container",RenderMethod:"replace"}]};class DocusserveSplashView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}onAfterRender(pRenderable,pRenderDestinationAddress,pRecord,pContent){let tmpDocuserve=this.pict.AppData.Docuserve;if(tmpDocuserve.CoverLoaded&&tmpDocuserve.Cover){this.renderFromCover(tmpDocuserve.Cover);this.renderExamples(tmpDocuserve.Cover);}else{this.renderFromCatalog(tmpDocuserve);}// Conditionally append a "Playground" button to the action row when
|
|
14294
|
+
// the current module ships a _playground.json. Async — the button
|
|
14295
|
+
// pops in once the config resolves.
|
|
14296
|
+
this.renderPlaygroundButton();// Render docs/README.md beneath the hero — the splash fills the
|
|
14191
14297
|
// viewport above the fold, the README content follows on scroll.
|
|
14192
14298
|
this.renderReadme();return super.onAfterRender(pRenderable,pRenderDestinationAddress,pRecord,pContent);}/**
|
|
14299
|
+
* Append a "Playground" button to the splash action row when the
|
|
14300
|
+
* current module declares a playground in `_playground.json`. The
|
|
14301
|
+
* route depends on `Kind`:
|
|
14302
|
+
* - Kind: "section" → full-page section playground
|
|
14303
|
+
* - anything else → Fable JS REPL drawer
|
|
14304
|
+
*
|
|
14305
|
+
* When no `_playground.json` exists (loadPlaygroundConfig resolves
|
|
14306
|
+
* to null), no button is added — the existing GitHub / Get Started
|
|
14307
|
+
* buttons stand on their own.
|
|
14308
|
+
*/renderPlaygroundButton(){let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];if(!tmpDocProvider||typeof tmpDocProvider.loadPlaygroundConfig!=='function'){return;}let tmpAppData=this.pict.AppData.Docuserve||{};let tmpGroup=tmpAppData.CurrentGroup||'';let tmpModule=tmpAppData.CurrentModule||'';tmpDocProvider.loadPlaygroundConfig(tmpGroup,tmpModule).then(pConfig=>{if(!pConfig){return;}let tmpRoute;if(pConfig.Kind==='section'){tmpRoute=tmpGroup&&tmpModule?'#/playground/section/'+tmpGroup+'/'+tmpModule:'#/playground/section';}else{tmpRoute='#/playground/fable';}let tmpButtonHTML='<a class="secondary" href="'+this.escapeHTML(tmpRoute)+'">Playground</a>';this.pict.ContentAssignment.projectContent('append','#Docuserve-Splash-Actions',tmpButtonHTML);}).catch(()=>{// Soft failure — no button is added when the config can't load.
|
|
14309
|
+
});}/**
|
|
14193
14310
|
* Render the splash screen from parsed _cover.md data.
|
|
14194
14311
|
*
|
|
14195
14312
|
* @param {Object} pCover - The parsed cover data { Title, Tagline, Description, Highlights, Actions }
|