code-playpad 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{d as e}from"./config-3Z6xX6Jr.js";import{t}from"./worker-runtime-BObmUwpG.js";var n=`let currentId=null,stdinLines=[],stdinExhausted=!1,nextRequest=1,inputWaitMs=0;const pendingLines=new Map;let sucrasePromise=null,sucraseURL=null;const pendingModules=new Map;class TransformLoadError extends Error{}function requestModule(t){return new Promise((e,r)=>{pendingModules.set(t,{resolve:e,reject:r}),post({type:"module-request",id:currentId,name:t})})}function post(t){self.postMessage(t)}let functionLineOffset=0;try{new Function('throw new Error("probe")')()}catch(t){const e=/<anonymous>:(\\d+):/.exec(t.stack||"");e&&(functionLineOffset=Number(e[1])-1)}let currentFiles=[];const FLUSH_BYTES=8192,FLUSH_MS=16,EAGER_POSTS=32;let outputQueue=[],queuedChars=0,windowStart=-1/0,windowPosts=0;function writeOutput(t,e){const r=outputQueue[outputQueue.length-1];r&&r.type===t?r.text+=e:outputQueue.push({type:t,text:e}),queuedChars+=e.length;const i=performance.now();i-windowStart>=FLUSH_MS&&(windowStart=i,windowPosts=0),(windowPosts<EAGER_POSTS||queuedChars>=FLUSH_BYTES)&&flushOutput()}function flushOutput(){if(!outputQueue.length)return;windowPosts++;const t=outputQueue;outputQueue=[],queuedChars=0;for(const e of t)post({type:e.type,id:currentId,text:e.text})}function format(t,e,r){if(e=e||new Set,typeof t=="string")return r?t:JSON.stringify(t);if(typeof t=="bigint")return String(t)+"n";if(typeof t=="function")return"[Function"+(t.name?": "+t.name:"")+"]";if(typeof t=="symbol"||t==null||typeof t!="object")return String(t);if(e.has(t))return"[Circular]";e.add(t);try{if(t instanceof Error)return t.stack||t.name+": "+t.message;if(Array.isArray(t))return"[ "+t.map(n=>format(n,e)).join(", ")+" ]";if(t instanceof Map)return"Map("+t.size+") { "+[...t].map(([n,o])=>format(n,e)+" => "+format(o,e)).join(", ")+" }";if(t instanceof Set)return"Set("+t.size+") { "+[...t].map(n=>format(n,e)).join(", ")+" }";if(t instanceof Date)return t.toISOString();if(t instanceof Promise)return"Promise { \\u2026 }";const i=Object.entries(t).map(([n,o])=>n+": "+format(o,e)),a=t.constructor&&t.constructor.name;return(a&&a!=="Object"?a+" ":"")+"{ "+i.join(", ")+" }"}finally{e.delete(t)}}function formatArgs(t){return t.map(e=>format(e,null,!0)).join(" ")+\`
1
+ import{d as e}from"./config-3Z6xX6Jr.js";import{t}from"./worker-runtime-Ey7jwPA3.js";var n=`let currentId=null,stdinLines=[],stdinExhausted=!1,nextRequest=1,inputWaitMs=0;const pendingLines=new Map;let sucrasePromise=null,sucraseURL=null;const pendingModules=new Map;class TransformLoadError extends Error{}function requestModule(t){return new Promise((e,r)=>{pendingModules.set(t,{resolve:e,reject:r}),post({type:"module-request",id:currentId,name:t})})}function post(t){self.postMessage(t)}let functionLineOffset=0;try{new Function('throw new Error("probe")')()}catch(t){const e=/<anonymous>:(\\d+):/.exec(t.stack||"");e&&(functionLineOffset=Number(e[1])-1)}let currentFiles=[];const FLUSH_BYTES=8192,FLUSH_MS=16,EAGER_POSTS=32;let outputQueue=[],queuedChars=0,windowStart=-1/0,windowPosts=0;function writeOutput(t,e){const r=outputQueue[outputQueue.length-1];r&&r.type===t?r.text+=e:outputQueue.push({type:t,text:e}),queuedChars+=e.length;const i=performance.now();i-windowStart>=FLUSH_MS&&(windowStart=i,windowPosts=0),(windowPosts<EAGER_POSTS||queuedChars>=FLUSH_BYTES)&&flushOutput()}function flushOutput(){if(!outputQueue.length)return;windowPosts++;const t=outputQueue;outputQueue=[],queuedChars=0;for(const e of t)post({type:e.type,id:currentId,text:e.text})}function format(t,e,r){if(e=e||new Set,typeof t=="string")return r?t:JSON.stringify(t);if(typeof t=="bigint")return String(t)+"n";if(typeof t=="function")return"[Function"+(t.name?": "+t.name:"")+"]";if(typeof t=="symbol"||t==null||typeof t!="object")return String(t);if(e.has(t))return"[Circular]";e.add(t);try{if(t instanceof Error)return t.stack||t.name+": "+t.message;if(Array.isArray(t))return"[ "+t.map(n=>format(n,e)).join(", ")+" ]";if(t instanceof Map)return"Map("+t.size+") { "+[...t].map(([n,o])=>format(n,e)+" => "+format(o,e)).join(", ")+" }";if(t instanceof Set)return"Set("+t.size+") { "+[...t].map(n=>format(n,e)).join(", ")+" }";if(t instanceof Date)return t.toISOString();if(t instanceof Promise)return"Promise { \\u2026 }";const i=Object.entries(t).map(([n,o])=>n+": "+format(o,e)),a=t.constructor&&t.constructor.name;return(a&&a!=="Object"?a+" ":"")+"{ "+i.join(", ")+" }"}finally{e.delete(t)}}function formatArgs(t){return t.map(e=>format(e,null,!0)).join(" ")+\`
2
2
  \`}const nativeConsole=self.console;self.console=Object.assign(Object.create(nativeConsole),{log:(...t)=>writeOutput("stdout",formatArgs(t)),info:(...t)=>writeOutput("stdout",formatArgs(t)),debug:(...t)=>writeOutput("stdout",formatArgs(t)),warn:(...t)=>writeOutput("stderr",formatArgs(t)),error:(...t)=>writeOutput("stderr",formatArgs(t))}),self._ppReadLine=async()=>{if(stdinLines.length){const i=stdinLines.shift();return writeOutput("echo",i+\`
3
3
  \`),i}const t=nextRequest++;flushOutput();const e=performance.now(),r=await new Promise(i=>{pendingLines.set(t,i),post({type:"stdin-request",id:currentId,request:t})});return inputWaitMs+=performance.now()-e,typeof r!="string"&&(stdinExhausted=!0),typeof r=="string"?r:null};async function input(t){t!==void 0&&writeOutput("stdout",String(t));const e=await self._ppReadLine();if(e===null)throw new Error("EOF: no more input");return e}self.input=input;async function loadSucrase(){return sucrasePromise||(sucrasePromise=(async()=>{try{if(sucraseURL)return await import(sucraseURL);const t=await requestModule("sucrase"),e=URL.createObjectURL(new Blob([t],{type:"text/javascript"}));try{return await import(e)}finally{URL.revokeObjectURL(e)}}catch(t){const e=sucraseURL?" from "+sucraseURL:"";throw new TransformLoadError("Could not load the TypeScript transform (Sucrase)"+e+": "+(t&&t.message?t.message:String(t)))}})(),sucrasePromise.catch(()=>{sucrasePromise=null})),sucrasePromise}function isModule(t,e){return Object.keys(t).length>1?!0:/^\\s*(import|export)\\s/m.test(t[e]||"")}function needsTypeScript(t){return/\\.(ts|tsx|jsx|mts|cts)$/.test(t)}function transformsFor(t){const e=["imports"];return/\\.tsx?$|\\.mts$|\\.cts$/.test(t)&&e.push("typescript"),/\\.[jt]sx$/.test(t)&&e.push("jsx"),e}async function runAsModules(t,e){const{transform:r}=await loadSucrase(),i=new Map,a=(n,o)=>{if(!o.startsWith("."))return null;const u=((n.includes("/")?n.slice(0,n.lastIndexOf("/")+1):"")+o).split("/"),d=[];for(const p of u)p==="."||p===""||(p===".."?d.pop():d.push(p));const c=d.join("/");return[c,c+".js",c+".ts",c+".tsx",c+".jsx",c+".json",c+"/index.js",c+"/index.ts"].find(p=>p in t)||null};function s(n){if(i.has(n))return i.get(n).exports;const o={exports:{}};if(i.set(n,o),n.endsWith(".json")){try{o.exports=JSON.parse(t[n])}catch(c){throw new SyntaxError("Invalid JSON in "+n+": "+c.message)}return o.exports}const{code:f}=r(t[n],{transforms:transformsFor(n),filePath:n,preserveDynamicImport:!0}),u=c=>{const l=a(n,c);if(!l)throw new Error('Cannot find module "'+c+'" from "'+n+'"');return s(l)};return new Function("exports","require","module","__filename","input","console",f+\`
4
4
  //# sourceURL=\`+n)(o.exports,u,o,n,input,self.console),o.exports}s(e)}async function run(t){currentId=t.id,stdinLines=t.stdin?String(t.stdin).replace(/\\n$/,"").split(\`
@@ -1 +1 @@
1
- import{t as e}from"./react-version.generated-BNNJmf7J.js";import{u as t}from"./config-3Z6xX6Jr.js";import{n,t as r}from"./boot-DMkl17sw.js";var i=`default-src 'none'; script-src 'unsafe-inline' blob:; worker-src blob:; style-src 'unsafe-inline'; img-src data:; font-src data:; form-action 'none'; base-uri 'none'`,a=/@import\s+["']tailwindcss/,o=`self.__webpack_require__=function(){throw new Error('Client modules do not run on the server.')};self.__webpack_require__.u=function(){return ''};self.__webpack_chunk_load__=function(){return Promise.resolve()};`;function s(){let e=document.implementation.createHTMLDocument(``),n=e.createElement(`meta`);n.setAttribute(`charset`,`utf-8`);let a=e.createElement(`meta`);a.httpEquiv=`Content-Security-Policy`,a.content=i;let o=e.createElement(`script`),{nonce:s}=t();return s&&o.setAttribute(`nonce`,s),o.textContent=r,e.head.prepend(n,a,o),e.documentElement.lang=`en`,`<!doctype html>${e.documentElement.outerHTML}`}function c(e){let t={};for(let n of Object.keys(e))n.startsWith(`public/`)&&n.endsWith(`.svg`)&&(t[n.slice(6)]=`data:image/svg+xml,${encodeURIComponent(e[n])}`);return t}function l(e){let t=document.createElement(`form`);t.className=`cp-next-bar`;let n=(t,n,r)=>{let i=document.createElement(`button`);return i.type=`button`,i.setAttribute(`aria-label`,t),i.textContent=n,i.addEventListener(`click`,()=>e()?.send({__playpadNav:1,op:r})),i},r=n(`Back`,`←`,`back`),i=n(`Forward`,`→`,`forward`),a=n(`Reload`,`↻`,`refresh`);r.disabled=i.disabled=!0;let o=document.createElement(`input`);return o.setAttribute(`aria-label`,`Address`),o.spellcheck=!1,t.append(r,i,a,o),t.addEventListener(`submit`,t=>{t.preventDefault(),e()?.send({__playpadNav:1,op:`push`,url:o.value.startsWith(`/`)?o.value:`/${o.value}`})}),{element:t,update(e){o.value=e.url,r.disabled=!e.canBack,i.disabled=!e.canForward}}}var u=new class{id=`next`;label=`Next.js preview (React ${e})`;interactiveStdin=!1;statusDecidesFailure=!0;#e=null;#t=null;#n=null;#r=/* @__PURE__ */ new WeakMap;#i=/* @__PURE__ */ new WeakMap;get ready(){return this.#e!==null}async editorLanguage(){let{javascript:e}=await import(`@codemirror/lang-javascript`);return e({jsx:!0})}load(){return this.#n??=(async()=>{try{[this.#e,this.#t]=await Promise.all([import(`./compiler-DqXxgvtN.js`),import(`./next-vendor.generated-CuKJHEOm.js`)])}catch(e){throw this.#n=null,Error(`The Next.js runtime could not be loaded. Check your connection and reload the page. (${e.message})`)}})(),this.#n}run(e,t={}){let r=t.preview;if(!r)return Promise.reject(/* @__PURE__ */ Error(`Next.js needs a <code-playpad> widget to render in.`));this.dispose(r.host);let i,a=l(()=>i),o=new Promise((e,t)=>{i=new n(r,{},e,t,a.update)});return this.#r.set(r.host,i),this.#i.set(o,i),this.#a(i,t.files??{},t.entry??`app/page.jsx`,a.element),o}async#a(e,n,r,i){try{await this.load();let{compileProject:l,CompileError:u,startPath:d}=this.#e,f;try{f=l(n)}catch(t){if(t instanceof u){e.fail(t.reason,{file:t.file,...t.line?{line:t.line}:{},...t.column?{column:t.column}:{}},t.hint),e.showCompileBanner(t.hint);return}throw t}let p=f.css.some(e=>a.test(e.text))?(await import(`./next-tailwind.generated-BWL5i33i.js`)).NEXT_TAILWIND_SOURCE:null,m=this.#t;Object.assign(e.payload,{nextClient:m.NEXT_CLIENT_SOURCE,tailwind:p,nonce:t().nonce,modules:f.client,css:f.css,notices:f.notices,routeFiles:f.routeFiles,assets:c(n),start:d(r),serverSource:`${o}\n${m.NEXT_SERVER_SOURCE}`,serverModules:f.server.filter(e=>e.kind===`js`).map(({path:e,text:t})=>({path:e,text:t})),serverMeta:f.server.map(({path:e,kind:t,links:n,directive:r,text:i})=>({path:e,kind:t,links:n,directive:r,...t===`json`?{text:i}:{}}))}),e.open(s(),[i])}catch(t){e.fail(t.message)}}stop(e){e&&this.#i.get(e)?.dispose(!0)}hasLivePreview(e){return this.#r.get(e)?.live??!1}dispose(e){this.#r.get(e)?.dispose(!0),this.#r.delete(e)}};export{u as nextRuntime};
1
+ import{t as e}from"./react-version.generated-BNNJmf7J.js";import{u as t}from"./config-3Z6xX6Jr.js";import{n,t as r}from"./boot-ecKcv-zZ.js";var i=`default-src 'none'; script-src 'unsafe-inline' blob:; worker-src blob:; style-src 'unsafe-inline'; img-src data:; font-src data:; form-action 'none'; base-uri 'none'`,a=/@import\s+["']tailwindcss/,o=`self.__webpack_require__=function(){throw new Error('Client modules do not run on the server.')};self.__webpack_require__.u=function(){return ''};self.__webpack_chunk_load__=function(){return Promise.resolve()};`;function s(){let e=document.implementation.createHTMLDocument(``),n=e.createElement(`meta`);n.setAttribute(`charset`,`utf-8`);let a=e.createElement(`meta`);a.httpEquiv=`Content-Security-Policy`,a.content=i;let o=e.createElement(`script`),{nonce:s}=t();return s&&o.setAttribute(`nonce`,s),o.textContent=r,e.head.prepend(n,a,o),e.documentElement.lang=`en`,`<!doctype html>${e.documentElement.outerHTML}`}function c(e){let t={};for(let n of Object.keys(e))n.startsWith(`public/`)&&n.endsWith(`.svg`)&&(t[n.slice(6)]=`data:image/svg+xml,${encodeURIComponent(e[n])}`);return t}function l(e){let t=document.createElement(`form`);t.className=`cp-next-bar`;let n=(t,n,r)=>{let i=document.createElement(`button`);return i.type=`button`,i.setAttribute(`aria-label`,t),i.textContent=n,i.addEventListener(`click`,()=>e()?.send({__playpadNav:1,op:r})),i},r=n(`Back`,`←`,`back`),i=n(`Forward`,`→`,`forward`),a=n(`Reload`,`↻`,`refresh`);r.disabled=i.disabled=!0;let o=document.createElement(`input`);return o.setAttribute(`aria-label`,`Address`),o.spellcheck=!1,t.append(r,i,a,o),t.addEventListener(`submit`,t=>{t.preventDefault(),e()?.send({__playpadNav:1,op:`push`,url:o.value.startsWith(`/`)?o.value:`/${o.value}`})}),{element:t,update(e){o.value=e.url,r.disabled=!e.canBack,i.disabled=!e.canForward}}}var u=new class{id=`next`;label=`Next.js preview (React ${e})`;interactiveStdin=!1;statusDecidesFailure=!0;#e=null;#t=null;#n=null;#r=/* @__PURE__ */ new WeakMap;#i=/* @__PURE__ */ new WeakMap;get ready(){return this.#e!==null}async editorLanguage(){let{javascript:e}=await import(`@codemirror/lang-javascript`);return e({jsx:!0})}load(){return this.#n??=(async()=>{try{[this.#e,this.#t]=await Promise.all([import(`./compiler-DqXxgvtN.js`),import(`./next-vendor.generated-CuKJHEOm.js`)])}catch(e){throw this.#n=null,Error(`The Next.js runtime could not be loaded. Check your connection and reload the page. (${e.message})`)}})(),this.#n}run(e,t={}){let r=t.preview;if(!r)return Promise.reject(/* @__PURE__ */ Error(`Next.js needs a <code-playpad> widget to render in.`));this.dispose(r.host);let i,a=l(()=>i),o=new Promise((e,t)=>{i=new n(r,{},e,t,a.update)});return this.#r.set(r.host,i),this.#i.set(o,i),this.#a(i,t.files??{},t.entry??`app/page.jsx`,a.element),o}async#a(e,n,r,i){try{await this.load();let{compileProject:l,CompileError:u,startPath:d}=this.#e,f;try{f=l(n)}catch(t){if(t instanceof u){e.fail(t.reason,{file:t.file,...t.line?{line:t.line}:{},...t.column?{column:t.column}:{}},t.hint),e.showCompileBanner(t.hint);return}throw t}let p=f.css.some(e=>a.test(e.text))?(await import(`./next-tailwind.generated-BWL5i33i.js`)).NEXT_TAILWIND_SOURCE:null,m=this.#t;Object.assign(e.payload,{nextClient:m.NEXT_CLIENT_SOURCE,tailwind:p,nonce:t().nonce,modules:f.client,css:f.css,notices:f.notices,routeFiles:f.routeFiles,assets:c(n),start:d(r),serverSource:`${o}\n${m.NEXT_SERVER_SOURCE}`,serverModules:f.server.filter(e=>e.kind===`js`).map(({path:e,text:t})=>({path:e,text:t})),serverMeta:f.server.map(({path:e,kind:t,links:n,directive:r,text:i})=>({path:e,kind:t,links:n,directive:r,...t===`json`?{text:i}:{}}))}),e.open(s(),[i])}catch(t){e.fail(t.message)}}stop(e){e&&this.#i.get(e)?.dispose(!0)}hasLivePreview(e){return this.#r.get(e)?.live??!1}dispose(e){this.#r.get(e)?.dispose(!0),this.#r.delete(e)}};export{u as nextRuntime};
@@ -12,6 +12,8 @@ export interface ProgressRecord {
12
12
  export declare function saveSnippet(id: string, code: string): Promise<void>;
13
13
  export declare function loadSnippet(id: string): Promise<string | null>;
14
14
  export declare function clearSnippet(id: string): Promise<void>;
15
+ export declare function saveStarters(id: string, files: string): Promise<void>;
16
+ export declare function loadStarters(id: string): Promise<string | null>;
15
17
  export declare function setProgress(id: string, data?: Partial<ProgressRecord>): Promise<ProgressRecord>;
16
18
  export declare function getProgress(id: string): Promise<ProgressRecord | null>;
17
19
  export declare function allProgress(): Promise<ProgressRecord[]>;
@@ -1,4 +1,4 @@
1
- import{l as e}from"./config-3Z6xX6Jr.js";import{t}from"./worker-runtime-BObmUwpG.js";var n=`let pyodide=null,stdinLines=[],stdinExhausted=!1,currentId=null,interactive=!1,inputWaitMs=0,nextRequest=1;const pendingLines=new Map,MOUNT="/home/pyodide/playground";let written=new Set,internals=null;const REFRESH=["import importlib, os, sys","MOUNT = "+JSON.stringify(MOUNT),"os.makedirs(MOUNT, exist_ok=True)","sys.path.insert(0, MOUNT) if MOUNT not in sys.path else None","os.chdir(MOUNT)","for _name, _mod in list(sys.modules.items()):",' _file = getattr(_mod, "__file__", None) or ""',' _paths = list(getattr(_mod, "__path__", None) or [])'," if _file.startswith(MOUNT) or any(str(p).startswith(MOUNT) for p in _paths):"," del sys.modules[_name]","importlib.invalidate_caches()"].join(\`
1
+ import{l as e}from"./config-3Z6xX6Jr.js";import{t}from"./worker-runtime-Ey7jwPA3.js";var n=`let pyodide=null,stdinLines=[],stdinExhausted=!1,currentId=null,interactive=!1,inputWaitMs=0,nextRequest=1;const pendingLines=new Map,MOUNT="/home/pyodide/playground";let written=new Set,internals=null;const REFRESH=["import importlib, os, sys","MOUNT = "+JSON.stringify(MOUNT),"os.makedirs(MOUNT, exist_ok=True)","sys.path.insert(0, MOUNT) if MOUNT not in sys.path else None","os.chdir(MOUNT)","for _name, _mod in list(sys.modules.items()):",' _file = getattr(_mod, "__file__", None) or ""',' _paths = list(getattr(_mod, "__path__", None) or [])'," if _file.startswith(MOUNT) or any(str(p).startswith(MOUNT) for p in _paths):"," del sys.modules[_name]","importlib.invalidate_caches()"].join(\`
2
2
  \`);function flushStreams(){try{pyodide.runPython(\`import sys
3
3
  sys.stdout.flush()
4
4
  sys.stderr.flush()\`,{globals:internals})}catch{}flushOutput()}const INPUT_OVERRIDE=["import builtins, sys, js","from pyodide.ffi import run_sync","",'def _pg_input(prompt=""):',' if prompt != "":'," sys.stdout.write(str(prompt))"," sys.stdout.flush()"," line = run_sync(js._pgReadLine())"," # Pyodide maps JS null to its own JsNull singleton, not None, so test"," # for what we want rather than for the several ways EOF can arrive."," if not isinstance(line, str):",' raise EOFError("EOF when reading a line")'," return line","",'_pg_input.__name__ = "input"','_pg_input.__qualname__ = "input"',"_pg_input.__doc__ = builtins.input.__doc__","builtins.input = _pg_input"].join(\`
@@ -1 +1 @@
1
- import{t as e}from"./react-version.generated-BNNJmf7J.js";import{u as t}from"./config-3Z6xX6Jr.js";import{n,t as r}from"./boot-DMkl17sw.js";var i=[`src/main.jsx`,`src/main.js`],a=`<!doctype html><html lang="en"><head><meta charset="utf-8"></head><body><div id="root"></div></body></html>`;function o(e){return/^([a-z][a-z0-9+.-]*:|\/\/)/i.test(e)}function s(e,n,s){let{CompileError:c,compileProject:l,resolveImport:u}=s,d=n.endsWith(`.html`)?n:`index.html`,f=Object.hasOwn(e,d),p=new DOMParser().parseFromString(f?e[d]:a,`text/html`),m=[];if(f){let t=[...p.querySelectorAll(`script[src], link[rel="stylesheet"][href]`)],n=[];for(let r of t){let t=r.tagName===`SCRIPT`,i=r.getAttribute(t?`src`:`href`);if(o(i))throw new c(d,`This project can't load "${i}". The preview can only use the project's own files.`);let a=u(e,d,i);if(!a)throw new c(d,`The file "${i}" does not exist.`);(t?n:m).push(a),r.remove()}if(!n.length)throw new c(d,`Add <script type="module" src="/src/main.jsx"><\/script> so the app has an entry file.`);m.push(...n)}else{let t=n.endsWith(`.html`)?void 0:Object.hasOwn(e,n)?n:i.find(t=>Object.hasOwn(e,t));if(!t)throw new c(`index.html`,`This project has no entry file. Add src/main.jsx.`);m.push(t)}let h=l(e,m),{nonce:g,runtimeURL:_}=t(),v=p.createElement(`meta`);v.httpEquiv=`Content-Security-Policy`,v.content=`default-src 'none'; script-src 'unsafe-inline'${_?` ${_}`:``}; style-src 'unsafe-inline'; img-src data:; font-src data:; form-action 'none'; base-uri 'none'`;let y=p.createElement(`script`);return g&&y.setAttribute(`nonce`,g),y.textContent=r,p.head.prepend(v,y),{html:`<!doctype html>${p.documentElement.outerHTML}`,modules:h,entries:m}}var c=new class{id=`react`;label=`React ${e}`;interactiveStdin=!1;statusDecidesFailure=!0;#e=null;#t=null;#n=null;#r=/* @__PURE__ */ new WeakMap;#i=/* @__PURE__ */ new WeakMap;get ready(){return this.#e!==null}async editorLanguage(){let{javascript:e}=await import(`@codemirror/lang-javascript`);return e({jsx:!0})}load(){return this.#n??=(async()=>{try{let e=import(`./compiler-A2mqXrqO.js`),n=t().runtimeURL?null:import(`./react-vendor.generated-DMxIoCMn.js`);this.#t=(await n)?.REACT_VENDOR_SOURCE??null,this.#e=await e}catch(e){throw this.#n=null,Error(`The React runtime could not be loaded. Check your connection and reload the page. (${e.message})`)}})(),this.#n}run(e,r={}){let i=r.preview;if(!i)return Promise.reject(/* @__PURE__ */ Error(`React needs a <code-playpad> widget to render in.`));this.dispose(i.host);let a,o=r.files??{},s=new Promise((e,r)=>{let o=t().runtimeURL;a=new n(i,{...o?{runtimeURL:o}:{vendor:this.#t},nonce:t().nonce},e,r)});return this.#r.set(i.host,a),this.#i.set(s,a),this.#a(a,o,r.entry??`index.html`),s}async#a(e,t,n){try{await this.load();let r=this.#e,i;try{i=s(t,n,r)}catch(t){if(t instanceof r.CompileError){e.fail(t.reason,{file:t.file,...t.line?{line:t.line}:{},...t.column?{column:t.column}:{}},t.hint),e.showCompileBanner(t.hint);return}throw t}e.payload.modules=i.modules,e.payload.entries=i.entries,e.open(i.html)}catch(t){e.fail(t.message)}}stop(e){e&&this.#i.get(e)?.dispose(!0)}hasLivePreview(e){return this.#r.get(e)?.live??!1}dispose(e){this.#r.get(e)?.dispose(!0),this.#r.delete(e)}};export{c as reactRuntime};
1
+ import{t as e}from"./react-version.generated-BNNJmf7J.js";import{u as t}from"./config-3Z6xX6Jr.js";import{n,t as r}from"./boot-ecKcv-zZ.js";var i=[`src/main.jsx`,`src/main.js`],a=`<!doctype html><html lang="en"><head><meta charset="utf-8"></head><body><div id="root"></div></body></html>`;function o(e){return/^([a-z][a-z0-9+.-]*:|\/\/)/i.test(e)}function s(e,n,s){let{CompileError:c,compileProject:l,resolveImport:u}=s,d=n.endsWith(`.html`)?n:`index.html`,f=Object.hasOwn(e,d),p=new DOMParser().parseFromString(f?e[d]:a,`text/html`),m=[];if(f){let t=[...p.querySelectorAll(`script[src], link[rel="stylesheet"][href]`)],n=[];for(let r of t){let t=r.tagName===`SCRIPT`,i=r.getAttribute(t?`src`:`href`);if(o(i))throw new c(d,`This project can't load "${i}". The preview can only use the project's own files.`);let a=u(e,d,i);if(!a)throw new c(d,`The file "${i}" does not exist.`);(t?n:m).push(a),r.remove()}if(!n.length)throw new c(d,`Add <script type="module" src="/src/main.jsx"><\/script> so the app has an entry file.`);m.push(...n)}else{let t=n.endsWith(`.html`)?void 0:Object.hasOwn(e,n)?n:i.find(t=>Object.hasOwn(e,t));if(!t)throw new c(`index.html`,`This project has no entry file. Add src/main.jsx.`);m.push(t)}let h=l(e,m),{nonce:g,runtimeURL:_}=t(),v=p.createElement(`meta`);v.httpEquiv=`Content-Security-Policy`,v.content=`default-src 'none'; script-src 'unsafe-inline'${_?` ${_}`:``}; style-src 'unsafe-inline'; img-src data:; font-src data:; form-action 'none'; base-uri 'none'`;let y=p.createElement(`script`);return g&&y.setAttribute(`nonce`,g),y.textContent=r,p.head.prepend(v,y),{html:`<!doctype html>${p.documentElement.outerHTML}`,modules:h,entries:m}}var c=new class{id=`react`;label=`React ${e}`;interactiveStdin=!1;statusDecidesFailure=!0;#e=null;#t=null;#n=null;#r=/* @__PURE__ */ new WeakMap;#i=/* @__PURE__ */ new WeakMap;get ready(){return this.#e!==null}async editorLanguage(){let{javascript:e}=await import(`@codemirror/lang-javascript`);return e({jsx:!0})}load(){return this.#n??=(async()=>{try{let e=import(`./compiler-A2mqXrqO.js`),n=t().runtimeURL?null:import(`./react-vendor.generated-DMxIoCMn.js`);this.#t=(await n)?.REACT_VENDOR_SOURCE??null,this.#e=await e}catch(e){throw this.#n=null,Error(`The React runtime could not be loaded. Check your connection and reload the page. (${e.message})`)}})(),this.#n}run(e,r={}){let i=r.preview;if(!i)return Promise.reject(/* @__PURE__ */ Error(`React needs a <code-playpad> widget to render in.`));this.dispose(i.host);let a,o=r.files??{},s=new Promise((e,r)=>{let o=t().runtimeURL;a=new n(i,{...o?{runtimeURL:o}:{vendor:this.#t},nonce:t().nonce},e,r)});return this.#r.set(i.host,a),this.#i.set(s,a),this.#a(a,o,r.entry??`index.html`),s}async#a(e,t,n){try{await this.load();let r=this.#e,i;try{i=s(t,n,r)}catch(t){if(t instanceof r.CompileError){e.fail(t.reason,{file:t.file,...t.line?{line:t.line}:{},...t.column?{column:t.column}:{}},t.hint),e.showCompileBanner(t.hint);return}throw t}e.payload.modules=i.modules,e.payload.entries=i.entries,e.open(i.html)}catch(t){e.fail(t.message)}}stop(e){e&&this.#i.get(e)?.dispose(!0)}hasLivePreview(e){return this.#r.get(e)?.live??!1}dispose(e){this.#r.get(e)?.dispose(!0),this.#r.delete(e)}};export{c as reactRuntime};
package/dist/react.d.ts CHANGED
@@ -22,11 +22,17 @@ export interface CodePlayPadProps {
22
22
  treeWidth?: number | string;
23
23
  /** How to list several files: "tabs" (default) or "tree". */
24
24
  fileView?: 'tabs' | 'tree';
25
+ /** Shows a toolbar button that switches between tabs and the tree. */
26
+ fileViewSwitch?: boolean;
27
+ /** Lets the reader add, rename and remove files. */
28
+ fileActions?: boolean;
25
29
  /** Which file is on screen to begin with, if not the entry. */
26
30
  openFile?: string;
27
31
  theme?: 'light' | 'dark' | 'auto';
28
32
  /** false hides the theme button and editor theme list. */
29
33
  themeControls?: boolean;
34
+ /** false hides the marks that show code hasn't run yet. */
35
+ changeMarks?: boolean;
30
36
  readOnly?: boolean;
31
37
  autoRun?: boolean;
32
38
  /** IndexedDB key: edits are restored on the student's next visit */
@@ -48,7 +54,7 @@ export interface CodePlayPadProps {
48
54
  * which keeps React 18 (no non-string prop support on custom elements) working
49
55
  * the same as React 19.
50
56
  */
51
- export declare function CodePlayPad({ code, files, entry, stdin, language, height, minHeight, maxHeight, previewHeight, treeWidth, fileView, openFile, theme, themeControls, readOnly, autoRun, persist, practice, className, style, onReady, onRun, onOutput, onError }: CodePlayPadProps): import("react").JSX.Element;
57
+ export declare function CodePlayPad({ code, files, entry, stdin, language, height, minHeight, maxHeight, previewHeight, treeWidth, fileView, fileViewSwitch, fileActions, openFile, theme, themeControls, changeMarks, readOnly, autoRun, persist, practice, className, style, onReady, onRun, onOutput, onError }: CodePlayPadProps): import("react").JSX.Element;
52
58
  declare module 'react' {
53
59
  namespace JSX {
54
60
  interface IntrinsicElements {
package/dist/react.js CHANGED
@@ -1 +1 @@
1
- import{n as e}from"./element-DnazizZC.js";import{useEffect as t,useRef as n}from"react";import{jsx as r}from"react/jsx-runtime";e();function i({code:e=``,files:i,entry:a,stdin:o,language:s=`python`,height:c,minHeight:l,maxHeight:u,previewHeight:d,treeWidth:f,fileView:p,openFile:m,theme:h=`auto`,themeControls:g=!0,readOnly:_,autoRun:v,persist:y,practice:b,className:x,style:S,onReady:C,onRun:w,onOutput:T,onError:E}){let D=n(null),O=n({onReady:C,onRun:w,onOutput:T,onError:E});O.current={onReady:C,onRun:w,onOutput:T,onError:E},t(()=>{let e=D.current;if(!e)return;let t=(t,n)=>{let r=e=>n(O.current)?.(e.detail);return e.addEventListener(t,r),()=>e.removeEventListener(t,r)},n=[t(`py-ready`,e=>e.onReady),t(`py-run`,e=>e.onRun),t(`py-output`,e=>e.onOutput),t(`py-error`,e=>e.onError)];return()=>n.forEach(e=>e())},[]);let k=i?JSON.stringify(i):null;t(()=>{let t=D.current;t&&(k?t.files=JSON.parse(k):e!==t.code&&(t.code=e))},[e,k]),t(()=>{D.current&&o!==void 0&&(D.current.stdin=o)},[o]);let A=b?JSON.stringify(b):null;return t(()=>{D.current&&(D.current.practice=A?JSON.parse(A):null)},[A]),/* @__PURE__ */ r(`code-playpad`,{ref:D,language:s,theme:h,"theme-controls":g?void 0:`off`,class:x,style:S,...c===void 0?{}:{height:String(c)},...l===void 0?{}:{"min-height":String(l)},...u===void 0?{}:{"max-height":String(u)},...d===void 0?{}:{"preview-height":String(d)},...f===void 0?{}:{"tree-width":String(f)},...p?{"file-view":p}:{},...m?{"open-file":m}:{},..._?{readonly:``}:{},...v?{autorun:``}:{},...y?{persist:y}:{},...a?{entry:a}:{},children:i?null:e})}export{i as CodePlayPad,i as default};
1
+ import{n as e}from"./element-Ce06T38j.js";import{useEffect as t,useRef as n}from"react";import{jsx as r}from"react/jsx-runtime";e();function i({code:e=``,files:i,entry:a,stdin:o,language:s=`python`,height:c,minHeight:l,maxHeight:u,previewHeight:d,treeWidth:f,fileView:p,fileViewSwitch:m,fileActions:h,openFile:g,theme:_=`auto`,themeControls:v=!0,changeMarks:y=!0,readOnly:b,autoRun:x,persist:S,practice:C,className:w,style:T,onReady:E,onRun:D,onOutput:O,onError:k}){let A=n(null),j=n({onReady:E,onRun:D,onOutput:O,onError:k});j.current={onReady:E,onRun:D,onOutput:O,onError:k},t(()=>{let e=A.current;if(!e)return;let t=(t,n)=>{let r=e=>n(j.current)?.(e.detail);return e.addEventListener(t,r),()=>e.removeEventListener(t,r)},n=[t(`py-ready`,e=>e.onReady),t(`py-run`,e=>e.onRun),t(`py-output`,e=>e.onOutput),t(`py-error`,e=>e.onError)];return()=>n.forEach(e=>e())},[]);let M=i?JSON.stringify(i):null;t(()=>{let t=A.current;t&&(M?t.files=JSON.parse(M):e!==t.code&&(t.code=e))},[e,M]),t(()=>{A.current&&o!==void 0&&(A.current.stdin=o)},[o]);let N=C?JSON.stringify(C):null;return t(()=>{A.current&&(A.current.practice=N?JSON.parse(N):null)},[N]),/* @__PURE__ */ r(`code-playpad`,{ref:A,language:s,theme:_,"theme-controls":v?void 0:`off`,"change-marks":y?void 0:`off`,class:w,style:T,...c===void 0?{}:{height:String(c)},...l===void 0?{}:{"min-height":String(l)},...u===void 0?{}:{"max-height":String(u)},...d===void 0?{}:{"preview-height":String(d)},...f===void 0?{}:{"tree-width":String(f)},...p?{"file-view":p}:{},...m?{"file-view-switch":``}:{},...h?{"file-actions":``}:{},...g?{"open-file":g}:{},...b?{readonly:``}:{},...x?{autorun:``}:{},...S?{persist:S}:{},...a?{entry:a}:{},children:i?null:e})}export{i as CodePlayPad,i as default};
@@ -15,7 +15,7 @@ import{n as e,t}from"./types-CfcYqU2K.js";import{t as n}from"./hints-DpBIeoeG.js
15
15
  --cp-ok: ${n.ok};
16
16
  color-scheme: ${t};
17
17
  }`]:[]).join(`
18
- `)}async function S(e){try{return await D(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),O(e)}}var C=/* @__PURE__ */ new Map,w=/* @__PURE__ */ new Set,T=!1;function E(){T||(T=!0,queueMicrotask(()=>{T=!1;for(let e of w){let t=[...e.adoptedStyleSheets];e.adoptedStyleSheets=[],e.adoptedStyleSheets=t}}))}async function D(e){let[t,n,r,i,a,o,s]=await Promise.all([import(`./dist-D4P7t1AU.js`).then(e=>e.s),import(`./dist-CjnVq6q1.js`).then(e=>e.x),import(`./dist-g8djAEMH.js`),import(`./dist-CTLX4tws.js`),import(`./dist-_fde-E8H.js`).then(e=>e.n),import(`./dist-DHeVjdBc.js`),import(`./dist-IFh_mUXG.js`).then(e=>e.t)]),{EditorView:c,keymap:l,lineNumbers:u,highlightActiveLine:f,highlightActiveLineGutter:p,highlightSpecialChars:m,drawSelection:h,rectangularSelection:g,crosshairCursor:_}=t,{EditorState:v,Compartment:y}=n,{defaultKeymap:b,history:x,historyKeymap:S,indentWithTab:T}=r,{syntaxHighlighting:D,defaultHighlightStyle:O,HighlightStyle:k,indentOnInput:A,bracketMatching:j,foldGutter:M,foldKeymap:N}=i,{autocompletion:P,closeBrackets:F,closeBracketsKeymap:I,completionKeymap:ee}=a,L=new y,R=new y,z=new y,B=C.get(`default-light`)??[c.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),D(O,{fallback:!0})];C.set(`default-light`,B);let{tags:V}=s,H=(e,t)=>[c.theme({"&":{color:e.fg,backgroundColor:e.bg},".cm-content":{caretColor:e.fg},".cm-gutters":{backgroundColor:e.surface,color:e.muted,border:`none`},".cm-activeLine":{backgroundColor:e.activeLine},".cm-activeLineGutter":{backgroundColor:e.selection},".cm-cursor, .cm-dropCursor":{borderLeftColor:e.fg},"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:e.selection},".cm-tooltip":{backgroundColor:e.surface,color:e.fg,border:`1px solid ${e.border}`},".cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:e.selection,color:e.fg}},{dark:t}),D(k.define([{tag:[V.comment,V.meta],color:e.comment,fontStyle:`italic`},{tag:[V.keyword,V.operatorKeyword,V.modifier],color:e.keyword},{tag:[V.string,V.special(V.string),V.regexp],color:e.string},{tag:[V.number,V.bool,V.null,V.atom],color:e.number},{tag:[V.function(V.variableName),V.function(V.propertyName),V.definition(V.function(V.variableName))],color:e.fn},{tag:[V.typeName,V.className,V.namespace,V.tagName],color:e.type},{tag:[V.variableName,V.propertyName,V.attributeName],color:e.variable},{tag:V.invalid,color:e.keyword,textDecoration:`underline`}]))],U=(e,t)=>{let n=d.find(e=>e.id===t);if(!n?.colors)return e?o.oneDark:B;let r=C.get(n.id);return r||(r=H(n.colors,n.mode===`dark`),C.set(n.id,r)),r},W=l.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),G=e.dark,K=e.themeId,q=e.readOnly,J=e.language??[],Y=t=>v.create({doc:t,extensions:[u(),p(),m(),x(),M(),h(),v.allowMultipleSelections.of(!0),A(),j(),F(),P(),g(),_(),f(),W,l.of([...I,...b,...S,...N,...ee,T]),c.lineWrapping,z.of(J),L.of(U(G,K)),R.of(v.readOnly.of(q)),c.updateListener.of(t=>{t.startState.facet(c.styleModule)!==t.state.facet(c.styleModule)&&E(),t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),X=new c({parent:e.parent,state:Y(e.doc)});w.add(X.root),E();let Z=/* @__PURE__ */ new Map,Q=e.name??``;return{fallback:!1,getCode:()=>X.state.doc.toString(),setCode(e){X.dispatch({changes:{from:0,to:X.state.doc.length,insert:e}})},openFile(e,t){if(e===Q)return;Z.set(Q,X.state);let n=Z.get(e);X.setState(n??Y(t)),Q=e,n&&X.dispatch({effects:[L.reconfigure(U(G,K)),R.reconfigure(v.readOnly.of(q)),z.reconfigure(J)]}),E()},fileCode(e,t){if(e===Q)return X.state.doc.toString();let n=Z.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...Z.keys()])e.includes(t)||Z.delete(t)},setTheme(e,t){G=e,K=t,X.dispatch({effects:L.reconfigure(U(G,K))})},setReadOnly(e){q=e,X.dispatch({effects:R.reconfigure(v.readOnly.of(q))})},setLanguage(e){J=e,X.dispatch({effects:z.reconfigure(J)})},focus:()=>X.focus(),destroy(){w.delete(X.root),X.destroy()}}}function O(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=/* @__PURE__ */ new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var k=/* @__PURE__ */ new Map,A=/* @__PURE__ */ new Map;function j(e,t){k.set(e,t)}function M(){return[...k.keys()]}function N(e){let t=A.get(e);if(t)return t;let n=k.get(e);if(!n)return Promise.reject(/* @__PURE__ */ Error(`Unknown runtime "${e}". Registered: ${M().join(`, `)||`none`}`));let r=n().catch(t=>{throw A.delete(e),t});return A.set(e,r),r}j(`python`,()=>import(`./pyodide-C5KhmXre.js`).then(e=>e.pythonRuntime)),j(`javascript`,()=>import(`./javascript-kqyWH6DS.js`).then(e=>e.javascriptRuntime)),j(`typescript`,()=>import(`./javascript-kqyWH6DS.js`).then(e=>e.typescriptRuntime)),j(`java`,()=>import(`./java-2z8CcJaR.js`).then(e=>e.javaRuntime)),j(`c`,()=>import(`./cpp-BxFy0NSM.js`).then(e=>e.cRuntime)),j(`cpp`,()=>import(`./cpp-BxFy0NSM.js`).then(e=>e.cppRuntime)),j(`csharp`,()=>import(`./csharp-ByGGaB0V.js`).then(e=>e.csharpRuntime)),j(`cs`,()=>import(`./csharp-ByGGaB0V.js`).then(e=>e.csharpRuntime)),j(`react`,()=>import(`./react-BKPRfjtf.js`).then(e=>e.reactRuntime)),j(`next`,()=>import(`./next-BIUzwrH6.js`).then(e=>e.nextRuntime));var P=String.raw`
18
+ `)}async function S(e){try{return await D(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),ee(e)}}var C=/* @__PURE__ */ new Map,w=/* @__PURE__ */ new Set,T=!1;function E(){T||(T=!0,queueMicrotask(()=>{T=!1;for(let e of w){let t=[...e.adoptedStyleSheets];e.adoptedStyleSheets=[],e.adoptedStyleSheets=t}}))}async function D(e){let[t,n,r,i,a,o,s]=await Promise.all([import(`./dist-D4P7t1AU.js`).then(e=>e.s),import(`./dist-CjnVq6q1.js`).then(e=>e.x),import(`./dist-g8djAEMH.js`),import(`./dist-CTLX4tws.js`),import(`./dist-_fde-E8H.js`).then(e=>e.n),import(`./dist-DHeVjdBc.js`),import(`./dist-IFh_mUXG.js`).then(e=>e.t)]),{EditorView:c,keymap:l,lineNumbers:u,highlightActiveLine:f,highlightActiveLineGutter:p,highlightSpecialChars:m,drawSelection:h,rectangularSelection:g,crosshairCursor:_}=t,{EditorState:v,Compartment:y}=n,{defaultKeymap:b,history:x,historyKeymap:S,indentWithTab:T}=r,{syntaxHighlighting:D,defaultHighlightStyle:ee,HighlightStyle:O,indentOnInput:k,bracketMatching:A,foldGutter:j,foldKeymap:M}=i,{autocompletion:N,closeBrackets:P,closeBracketsKeymap:F,completionKeymap:te}=a,I=new y,L=new y,R=new y,z=C.get(`default-light`)??[c.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),D(ee,{fallback:!0})];C.set(`default-light`,z);let{tags:B}=s,V=(e,t)=>[c.theme({"&":{color:e.fg,backgroundColor:e.bg},".cm-content":{caretColor:e.fg},".cm-gutters":{backgroundColor:e.surface,color:e.muted,border:`none`},".cm-activeLine":{backgroundColor:e.activeLine},".cm-activeLineGutter":{backgroundColor:e.selection},".cm-cursor, .cm-dropCursor":{borderLeftColor:e.fg},"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:e.selection},".cm-tooltip":{backgroundColor:e.surface,color:e.fg,border:`1px solid ${e.border}`},".cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:e.selection,color:e.fg}},{dark:t}),D(O.define([{tag:[B.comment,B.meta],color:e.comment,fontStyle:`italic`},{tag:[B.keyword,B.operatorKeyword,B.modifier],color:e.keyword},{tag:[B.string,B.special(B.string),B.regexp],color:e.string},{tag:[B.number,B.bool,B.null,B.atom],color:e.number},{tag:[B.function(B.variableName),B.function(B.propertyName),B.definition(B.function(B.variableName))],color:e.fn},{tag:[B.typeName,B.className,B.namespace,B.tagName],color:e.type},{tag:[B.variableName,B.propertyName,B.attributeName],color:e.variable},{tag:B.invalid,color:e.keyword,textDecoration:`underline`}]))],H=(e,t)=>{let n=d.find(e=>e.id===t);if(!n?.colors)return e?o.oneDark:z;let r=C.get(n.id);return r||(r=V(n.colors,n.mode===`dark`),C.set(n.id,r)),r},U=l.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),W=e.dark,G=e.themeId,K=e.readOnly,q=e.language??[],J=t=>v.create({doc:t,extensions:[u(),p(),m(),x(),j(),h(),v.allowMultipleSelections.of(!0),k(),A(),P(),N(),g(),_(),f(),U,l.of([...F,...b,...S,...M,...te,T]),c.lineWrapping,R.of(q),I.of(H(W,G)),L.of(v.readOnly.of(K)),c.updateListener.of(t=>{t.startState.facet(c.styleModule)!==t.state.facet(c.styleModule)&&E(),t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),Y=new c({parent:e.parent,state:J(e.doc)});w.add(Y.root),E();let X=/* @__PURE__ */ new Map,Z=e.name??``;return{fallback:!1,getCode:()=>Y.state.doc.toString(),setCode(e){Y.dispatch({changes:{from:0,to:Y.state.doc.length,insert:e}})},openFile(e,t){if(e===Z)return;X.set(Z,Y.state);let n=X.get(e);Y.setState(n??J(t)),Z=e,n&&Y.dispatch({effects:[I.reconfigure(H(W,G)),L.reconfigure(v.readOnly.of(K)),R.reconfigure(q)]}),E()},fileCode(e,t){if(e===Z)return Y.state.doc.toString();let n=X.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...X.keys()])e.includes(t)||X.delete(t)},renameFile(e,t){Z===e&&(Z=t);let n=X.get(e);n&&(X.delete(e),X.set(t,n))},setTheme(e,t){W=e,G=t,Y.dispatch({effects:I.reconfigure(H(W,G))})},setReadOnly(e){K=e,Y.dispatch({effects:L.reconfigure(v.readOnly.of(K))})},setLanguage(e){q=e,Y.dispatch({effects:R.reconfigure(q)})},focus:()=>Y.focus(),destroy(){w.delete(Y.root),Y.destroy()}}}function ee(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=/* @__PURE__ */ new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},renameFile(e,t){r===e&&(r=t);let i=n.get(e);i!==void 0&&(n.delete(e),n.set(t,i))},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var O=/* @__PURE__ */ new Map,k=/* @__PURE__ */ new Map;function A(e,t){O.set(e,t)}function j(){return[...O.keys()]}function M(e){let t=k.get(e);if(t)return t;let n=O.get(e);if(!n)return Promise.reject(/* @__PURE__ */ Error(`Unknown runtime "${e}". Registered: ${j().join(`, `)||`none`}`));let r=n().catch(t=>{throw k.delete(e),t});return k.set(e,r),r}A(`python`,()=>import(`./pyodide-C5KhmXre.js`).then(e=>e.pythonRuntime)),A(`javascript`,()=>import(`./javascript-kqyWH6DS.js`).then(e=>e.javascriptRuntime)),A(`typescript`,()=>import(`./javascript-kqyWH6DS.js`).then(e=>e.typescriptRuntime)),A(`java`,()=>import(`./java-2z8CcJaR.js`).then(e=>e.javaRuntime)),A(`c`,()=>import(`./cpp-BxFy0NSM.js`).then(e=>e.cRuntime)),A(`cpp`,()=>import(`./cpp-BxFy0NSM.js`).then(e=>e.cppRuntime)),A(`csharp`,()=>import(`./csharp-ByGGaB0V.js`).then(e=>e.csharpRuntime)),A(`cs`,()=>import(`./csharp-ByGGaB0V.js`).then(e=>e.csharpRuntime)),A(`react`,()=>import(`./react-BKPRfjtf.js`).then(e=>e.reactRuntime)),A(`next`,()=>import(`./next-BIUzwrH6.js`).then(e=>e.nextRuntime));var N=String.raw`
19
19
  :host {
20
20
  --cp-bg: #ffffff;
21
21
  --cp-fg: #1f2328;
@@ -427,9 +427,48 @@ table.cp-table th { background: var(--cp-bg); }
427
427
  .cp-preview-notice[hidden] { display: none; }
428
428
  .cp-output .cp-warn { color: #9a6700; }
429
429
  :host([data-resolved-theme="dark"]) .cp-output .cp-warn { color: #d29922; }
430
- .cp-edited-note { font-size: 12px; color: var(--cp-muted); white-space: nowrap; }
431
- .cp-edited-note[hidden] { display: none; }
432
- .cp-tabs button.cp-edited::after { content: ' ●'; color: var(--cp-accent); }
430
+ /* What hasn't run yet. A filled mark: changed since the last run. A hollow one:
431
+ differs from what the page shipped, but has run. The text after the slash is
432
+ what a screen reader says; browsers without it keep the first rule. */
433
+ .cp-tabs button.cp-edited::after { content: ' ○'; color: var(--cp-muted); }
434
+ .cp-tabs button.cp-edited::after { content: ' ○' / ', changed'; }
435
+ .cp-tabs button.cp-unrun::after { content: ' ●'; color: var(--cp-accent); }
436
+ .cp-tabs button.cp-unrun::after { content: ' ●' / ', not run yet'; }
437
+ button.cp-primary { position: relative; }
438
+ button.cp-primary.cp-unrun::after {
439
+ content: '';
440
+ position: absolute;
441
+ top: -4px;
442
+ right: -4px;
443
+ width: 8px;
444
+ height: 8px;
445
+ border: 2px solid var(--cp-surface);
446
+ border-radius: 50%;
447
+ background: #bf8700;
448
+ }
449
+ :host([data-resolved-theme="dark"]) button.cp-primary.cp-unrun::after { background: #d29922; }
450
+ /* Over the output, so the widget keeps its size; clicks go through to what's under it. */
451
+ .cp-output-box { position: relative; }
452
+ .cp-has-preview .cp-preview-pane { position: relative; }
453
+ .cp-stale-note {
454
+ position: absolute;
455
+ top: 6px;
456
+ right: 8px;
457
+ z-index: 2;
458
+ max-width: calc(100% - 16px);
459
+ padding: 3px 8px;
460
+ border: 1px solid var(--cp-border);
461
+ border-radius: 999px;
462
+ background: var(--cp-bg);
463
+ color: var(--cp-muted);
464
+ font-size: 12px;
465
+ white-space: nowrap;
466
+ overflow: hidden;
467
+ text-overflow: ellipsis;
468
+ pointer-events: none;
469
+ box-shadow: 0 1px 3px rgb(0 0 0 / 0.12);
470
+ }
471
+ .cp-stale-note[hidden], .cp-output-box:has(> .cp-output[hidden]) .cp-stale-note { display: none; }
433
472
  .cp-tab-folder { opacity: 0.65; }
434
473
 
435
474
  @container (max-width: 480px) {
@@ -499,7 +538,7 @@ table.cp-table th { background: var(--cp-bg); }
499
538
  .cp-has-tree.cp-has-preview .cp-source { grid-template-columns: min(var(--cp-tree-width, 20%), calc(100% - 167px)) 7px minmax(0, 1fr); }
500
539
  /* A sized row follows the divider, so a long tree scrolls instead of holding it open. */
501
540
  .cp-editor-sized.cp-has-tree .cp-tabs.cp-tree { height: 0; min-height: 100%; }
502
- .cp-has-tree .cp-source > :not(.cp-tabs, .cp-split-tree) { grid-column: 3; }
541
+ .cp-has-tree .cp-source > :not(.cp-tabs, .cp-split-tree, .cp-file-overlay) { grid-column: 3; }
503
542
  .cp-has-tree .cp-split-tree { display: block; grid-column: 2; grid-row: 1 / span 2; }
504
543
  .cp-tabs.cp-tree {
505
544
  display: block;
@@ -545,6 +584,110 @@ table.cp-table th { background: var(--cp-bg); }
545
584
  .cp-editor-sized.cp-has-tree .cp-tabs.cp-tree { height: auto; min-height: 0; }
546
585
  }
547
586
 
587
+ /* file-actions: files come and go, so the list scrolls and never moves the widget. */
588
+ .cp-file-actions .cp-source { position: relative; }
589
+ .cp-file-actions .cp-tabs:not(.cp-tree) { scrollbar-width: none; align-items: stretch; }
590
+ .cp-file-actions .cp-tabs:not(.cp-tree)::-webkit-scrollbar { display: none; }
591
+ .cp-file-actions.cp-has-tree .cp-tabs.cp-tree { height: 0; min-height: 100%; padding-top: 0; }
592
+ @container (max-width: 420px) {
593
+ .cp-file-actions.cp-has-tree .cp-tabs.cp-tree { height: 150px; min-height: 0; }
594
+ }
595
+ .cp-file-row { display: flex; flex: none; align-items: stretch; min-width: 0; }
596
+ .cp-tabs.cp-tree .cp-file-row > button:first-child { flex: 1 1 auto; width: auto; min-width: 0; }
597
+ .cp-tabs button.cp-file-tool,
598
+ .cp-tabs.cp-tree button.cp-file-tool {
599
+ display: inline-flex;
600
+ flex: none;
601
+ align-items: center;
602
+ justify-content: center;
603
+ width: 24px;
604
+ padding: 0;
605
+ border: 0;
606
+ color: var(--cp-muted);
607
+ font-size: 14px;
608
+ }
609
+ .cp-file-tool svg {
610
+ width: 15px;
611
+ height: 15px;
612
+ fill: none;
613
+ stroke: currentColor;
614
+ stroke-width: 1.8;
615
+ stroke-linecap: round;
616
+ stroke-linejoin: round;
617
+ }
618
+ .cp-tabs button.cp-file-new {
619
+ position: sticky;
620
+ right: -6px;
621
+ background: var(--cp-surface);
622
+ }
623
+ .cp-tree-head {
624
+ position: sticky;
625
+ top: 0;
626
+ z-index: 1;
627
+ display: flex;
628
+ align-items: center;
629
+ gap: 2px;
630
+ min-height: 30px;
631
+ background: var(--cp-surface);
632
+ }
633
+ .cp-tabs.cp-tree button.cp-tree-root {
634
+ display: block;
635
+ flex: 1 1 auto;
636
+ align-self: stretch;
637
+ width: auto;
638
+ min-width: 0;
639
+ padding: 0 8px;
640
+ border-left: 0;
641
+ font-family: inherit;
642
+ }
643
+ .cp-tabs.cp-tree button[aria-current='true'] {
644
+ background: var(--cp-bg);
645
+ color: var(--cp-accent);
646
+ font-weight: 600;
647
+ }
648
+ .cp-file-field {
649
+ display: flex;
650
+ flex: none;
651
+ align-items: stretch;
652
+ padding: 3px 2px;
653
+ }
654
+ .cp-tree .cp-file-field { padding-left: calc(8px + var(--cp-depth, 0) * 12px); }
655
+ .cp-file-field input {
656
+ flex: 1 1 auto;
657
+ width: 170px;
658
+ min-width: 0;
659
+ padding: 2px 5px;
660
+ border: 1px solid var(--cp-accent);
661
+ border-radius: 3px;
662
+ background: var(--cp-bg);
663
+ color: var(--cp-fg);
664
+ font-family: var(--cp-font-mono);
665
+ font-size: 12px;
666
+ }
667
+ .cp-tree .cp-file-field input { width: 100%; }
668
+ .cp-file-overlay {
669
+ position: absolute;
670
+ z-index: 5;
671
+ max-width: 100%;
672
+ box-sizing: border-box;
673
+ border: 1px solid var(--cp-border);
674
+ border-radius: 4px;
675
+ background: var(--cp-bg);
676
+ color: var(--cp-fg);
677
+ font-size: 12px;
678
+ box-shadow: 0 2px 8px rgb(0 0 0 / 20%);
679
+ }
680
+ .cp-file-overlay[hidden] { display: none; }
681
+ .cp-file-message { padding: 5px 8px; }
682
+ .cp-file-message.cp-file-refused { border-color: var(--cp-danger); color: var(--cp-danger); }
683
+ .cp-file-pop { display: flex; flex-direction: column; gap: 4px; padding: 4px; width: max-content; max-width: min(100%, 280px); }
684
+ .cp-file-pop p { margin: 4px; }
685
+ .cp-file-pop > button { text-align: left; }
686
+ .cp-file-pop-buttons { display: flex; justify-content: flex-end; gap: 6px; }
687
+ @media (pointer: coarse) {
688
+ .cp-tabs button.cp-file-tool, .cp-tabs.cp-tree button.cp-file-tool { width: 34px; }
689
+ }
690
+
548
691
  /* Only a preview sits beside the code, and only with no tree: three columns leave
549
692
  the preview too little room. A tree makes any widget a container. */
550
693
  @container (min-width: 760px) {
@@ -566,18 +709,19 @@ table.cp-table th { background: var(--cp-bg); }
566
709
  @media (prefers-reduced-motion: reduce) {
567
710
  .cp-progress { animation: none; background-position: 0 0; background-size: 100% 100%; opacity: 0.4; }
568
711
  }
569
- `,F=e=>()=>import(`./dist-BwlTZqCY.js`).then(t=>t.javascript(e)),I={py:()=>import(`./dist-CRXZcpYD.js`).then(e=>e.python()),pyi:()=>import(`./dist-CRXZcpYD.js`).then(e=>e.python()),js:F({}),mjs:F({}),cjs:F({}),jsx:F({jsx:!0}),ts:F({typescript:!0}),mts:F({typescript:!0}),cts:F({typescript:!0}),tsx:F({typescript:!0,jsx:!0}),json:()=>import(`./dist-BDifu2bQ.js`).then(e=>e.json()),css:()=>import(`./dist-UbI3_a5S.js`).then(e=>e.css()),html:()=>import(`./dist-C41hAfPr.js`).then(e=>e.html()),c:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),h:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cpp:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cc:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cxx:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),hpp:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),hxx:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),java:()=>import(`./dist-ixcYRC9x.js`).then(e=>e.java()),cs:()=>Promise.all([import(`./dist-CTLX4tws.js`),import(`./clike-C2M2Cbvf.js`)]).then(([e,t])=>e.StreamLanguage.define(t.csharp))};async function ee(e,t){let n=e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``,r=(t===`react`||t===`next`)&&n===`js`?I.jsx:I[n];return r?r().catch(()=>null):null}var L=`code-playpad`,R=1,z=`snippets`,B=`progress`,V=null;function H(){return typeof indexedDB>`u`?Promise.reject(/* @__PURE__ */ Error(`IndexedDB unavailable`)):(V||=new Promise((e,t)=>{let n=indexedDB.open(L,R);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(z)||e.createObjectStore(z),e.objectStoreNames.contains(B)||e.createObjectStore(B,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw V=null,e}),V)}function U(e,t,n){return H().then(r=>new Promise((i,a)=>{let o=n(r.transaction(e,t).objectStore(e));o.onsuccess=()=>i(o.result),o.onerror=()=>a(o.error)}))}function W(e,t){return U(z,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function G(e){return U(z,`readonly`,t=>t.get(e)).then(e=>e??null)}function K(e){return U(z,`readwrite`,t=>t.delete(e)).then(()=>void 0)}function q(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return U(B,`readwrite`,e=>e.put(n)).then(()=>n)}function J(e){return U(B,`readonly`,t=>t.get(e)).then(e=>e??null)}function Y(){return U(B,`readonly`,e=>e.getAll())}var X=`code-playpad`;function Z(e){let t=e.replace(/\t/g,` `).split(`
712
+ `,P=e=>()=>import(`./dist-BwlTZqCY.js`).then(t=>t.javascript(e)),F={py:()=>import(`./dist-CRXZcpYD.js`).then(e=>e.python()),pyi:()=>import(`./dist-CRXZcpYD.js`).then(e=>e.python()),js:P({}),mjs:P({}),cjs:P({}),jsx:P({jsx:!0}),ts:P({typescript:!0}),mts:P({typescript:!0}),cts:P({typescript:!0}),tsx:P({typescript:!0,jsx:!0}),json:()=>import(`./dist-BDifu2bQ.js`).then(e=>e.json()),css:()=>import(`./dist-UbI3_a5S.js`).then(e=>e.css()),html:()=>import(`./dist-C41hAfPr.js`).then(e=>e.html()),c:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),h:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cpp:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cc:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),cxx:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),hpp:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),hxx:()=>import(`./dist-3xj9-ylK.js`).then(e=>e.cpp()),java:()=>import(`./dist-ixcYRC9x.js`).then(e=>e.java()),cs:()=>Promise.all([import(`./dist-CTLX4tws.js`),import(`./clike-C2M2Cbvf.js`)]).then(([e,t])=>e.StreamLanguage.define(t.csharp))};async function te(e,t){let n=e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1).toLowerCase():``,r=(t===`react`||t===`next`)&&n===`js`?F.jsx:F[n];return r?r().catch(()=>null):null}var I=`code-playpad`,L=1,R=`snippets`,z=`progress`,B=null;function V(){return typeof indexedDB>`u`?Promise.reject(/* @__PURE__ */ Error(`IndexedDB unavailable`)):(B||=new Promise((e,t)=>{let n=indexedDB.open(I,L);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(R)||e.createObjectStore(R),e.objectStoreNames.contains(z)||e.createObjectStore(z,{keyPath:`id`})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(e=>{throw B=null,e}),B)}function H(e,t,n){return V().then(r=>new Promise((i,a)=>{let o=n(r.transaction(e,t).objectStore(e));o.onsuccess=()=>i(o.result),o.onerror=()=>a(o.error)}))}function U(e,t){return H(R,`readwrite`,n=>n.put(t,e)).then(()=>void 0)}function W(e){return H(R,`readonly`,t=>t.get(e)).then(e=>e??null)}function G(e){return H(R,`readwrite`,t=>(t.delete(K(e)),t.delete(e))).then(()=>void 0)}var K=e=>`${e}\nstarters`;function q(e,t){return U(K(e),t)}function J(e){return W(K(e))}function Y(e,t={}){let n={completed:!0,...t,id:e,updatedAt:Date.now()};return H(z,`readwrite`,e=>e.put(n)).then(()=>n)}function X(e){return H(z,`readonly`,t=>t.get(e)).then(e=>e??null)}function Z(){return H(z,`readonly`,e=>e.getAll())}var ne=`code-playpad`,re=`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 4v14a2 2 0 0 0 2 2h3M5 10h5"/><rect x="11" y="7" width="9" height="5" rx="1"/><rect x="11" y="17" width="9" height="5" rx="1"/><path d="M4 3h3"/></svg>`,ie=`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 20V6a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v3h9a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zM11 9H3M14 5h6"/></svg>`,ae=`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14 3H6a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8zM14 3v5h5M12 11v6M9 14h6"/></svg>`,oe=`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 6a1 1 0 0 1 1-1h5l2 3h9a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zM12 11v5M9.5 13.5h5"/></svg>`,se=(e,t)=>e?`${e}/${t}`:t;function ce(e){if(typeof e!=`string`||!e.trim())return`A file needs a name.`;if(e.includes(`\\`))return`"${e}" has a backslash. Use / between folders.`;let t=e.split(`/`);return t.some(e=>!e.trim())?`"${e}" has an empty folder name.`:t.some(e=>e===`.`||e===`..`)?`"${e}" can't use . or .. as a folder.`:e===`__proto__`?`"${e}" can't be used as a file name.`:null}function le(e,t,n){let r={...e};for(let e of Object.keys(n))Object.hasOwn(t,e)?r[e]===t[e]&&(r[e]=n[e]):Object.hasOwn(r,e)||(r[e]=n[e]);for(let e of Object.keys(t))!Object.hasOwn(n,e)&&r[e]===t[e]&&delete r[e];return r}function ue(e){let t=e.replace(/\t/g,` `).split(`
570
713
  `);for(;t.length&&t[0].trim()===``;)t.shift();for(;t.length&&t[t.length-1].trim()===``;)t.pop();let n=t.filter(e=>e.trim()!==``).reduce((e,t)=>Math.min(e,t.match(/^ */)[0].length),1/0);return(n===1/0?t:t.map(e=>e.slice(n))).join(`
571
- `)}var Q=2e5,$=`playpad-file`,te={python:`main.py`,javascript:`main.js`,typescript:`main.ts`,java:`Main.java`,c:`main.c`,cpp:`main.cpp`,csharp:`Program.cs`,cs:`Program.cs`,react:`src/main.jsx`,next:`app/page.jsx`};function ne(e){return te[e]??`main.txt`}var re=e=>e.tagName===`SCRIPT`&&e.getAttribute(`type`)===`text/plain`;function ie(e){return[...e.children].filter(e=>e.tagName.toLowerCase()===$&&[...e.children].some(e=>!re(e))).map(e=>e.getAttribute(`name`)??``)}function ae(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==$)continue;let e=t.getAttribute(`name`),r=[...t.children].find(re);e&&(n[e]=Z((r??t).textContent??``))}if(Object.keys(n).length)return n;let r=[...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==$),i=r.some(e=>e.nodeType===Node.ELEMENT_NODE),a=Z(r.filter(e=>!(i&&e.nodeType===Node.TEXT_NODE&&!(e.textContent??``).trim())).map(e=>e.textContent??``).join(``));return{[t]:a}}function oe(e,t){try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t;return Object.keys(e).length?e:null}}catch{}return e?{[t]:e}:null}var se=typeof HTMLElement>`u`?class{}:HTMLElement,ce=class extends se{static get observedAttributes(){return[`language`,`height`,`min-height`,`max-height`,`preview-height`,`tree-width`,`file-view`,`open-file`,`theme`,`theme-controls`,`readonly`,`autorun`,`stdin`,`persist`,`entry`,`practice`]}#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u=null;#d=null;#f=null;#p=null;#m={};#h={};#g=!1;#_=`main.py`;#v=null;#y;#b=!1;#x=null;#S=!1;#C=!1;#w=null;#T=null;#E=null;#D=()=>this.#ge();#O=null;#k=null;#A=!0;#j=[];#M=null;#N=null;#P=null;#F=0;#I=!1;#L=null;#R;#z;#B=null;#V=[];#H=/* @__PURE__ */ new Set;#U=null;#W=null;#G=null;constructor(){super(),this.#e=this.attachShadow({mode:`open`})}get code(){return this.#u?this.#u.getCode():this.#m[this.#_]??``}set code(e){this.#m[this.#_]=e,this.#te()}get practice(){if(this.#L)return this.#L;let e=this.getAttribute(`practice`);if(!e)return null;try{return JSON.parse(e)}catch{return null}}set practice(e){this.#L=e}get files(){return this.#se()}set files(e){let t=Object.keys(e);if(!t.length)return;let n=Object.keys(this.#h);n.length===1&&!this.#h[n[0]]&&(this.#h={...e}),this.#m={...e},this.#V=[],t.includes(this.#_)||(this.#_=this.#ae()),this.#$(),this.#ee(),this.#ce(),this.#Z()}get entry(){return this.#ae()}set entry(e){this.setAttribute(`entry`,e)}openFile(e){if(e in this.#m){this.#u&&(e!==this.#_&&this.#Q(),this.#m[this.#_]=this.#u.getCode(),this.#u.openFile(e,this.#m[e]??``)),this.#_=e;for(let t=e.indexOf(`/`);t!==-1;t=e.indexOf(`/`,t+1))this.#H.delete(e.slice(0,t));this.#ce(),this.#Z()}}get stdin(){return this.#l?this.#l.value:``}set stdin(e){this.#l&&(this.#l.value=e,this.#c.hidden=!1)}get language(){return this.getAttribute(`language`)||`python`}set language(e){this.setAttribute(`language`,e)}getCode(){return this.code}getFiles(){return this.#se()}reset(){this.#Q(),this.#m={...this.#h},this.#_=this.#ae(),this.#ee(),this.#ce(),this.#Z(),this.#ye(),this.#s.hidden=!0,this.#de(),this.#B=null,this.#fe(),this.#ve(this.#f?.ready?`${this.#f.label} ready`:``,`idle`)}async run(){if(this.#U)return this.#U.widget.run();if(this.#b)return;await this.#d;let e=this.#se(),r=this.getAttribute(`entry`);if(r&&!(r in e))return this.#re(r,e);this.#ne=!1;let i=this.#ae(),a=e[i]??``;this.#b=!0,this.#S=!1,this.#n.disabled=!0,this.#r.hidden=!1,this.#ye(),this.#s.hidden=!1;let o=this.practice;this.hasAttribute(`practice`)&&!o&&this.#be(`The practice attribute is not valid JSON.
572
- `,`cp-err`),this.#ue()&&(this.#B=e,this.#fe(),this.#V.length&&this.#be(`${this.#V.join(`, `)}: HTML tags in this file's markup were read as elements, so its code is incomplete. Write < as &lt;, or put the code in <script type="text/plain">. A <script> left unescaped runs on the host page.\n`,`cp-err`)),this.#Ee(`py-run`,{code:a,entry:i,files:e,language:this.language,...o?{practice:o}:{}});try{let r=await this.#X();if(this.#S)throw new t;if(o&&!r.supportsPractice)throw Error(`Practice mode is not available for ${r.label}.`);this.#ve(`Queued…`,`busy`),this.#o.hidden=!1;let s=r.run(a,{stdin:this.#l.value,files:e,entry:i,onStart:()=>this.#ve(`Running…`,`busy`),onProgress:e=>this.#ve(e.message,`busy`),onStdout:e=>this.#be(e),onStderr:e=>this.#be(e,`cp-err`),onEcho:e=>this.#be(e,`cp-in`),onStdinRequest:()=>this.#Se(),...o?{practice:o}:{},...this.#ue()?{preview:{host:this.#R,onStart:()=>this.#ve(`Running…`,`busy`),onConsole:(e,t)=>{this.#be(`${t}\n`,e===`error`?`cp-err`:e===`warn`?`cp-warn`:void 0),this.#De(`playpad-console`,{level:e,text:t,language:this.language})},onRender:e=>this.#De(`playpad-render`,{rootText:e,language:this.language}),onError:e=>{this.#ve(`Error`,`error`),this.#Ee(`py-error`,{...e,language:this.language})}}}:{}});this.#x={runtime:r,run:s};let c=await s;if(c.table&&this.#Te(c.table),c.value!==void 0&&this.#be(`${c.value}\n`,`cp-value`),c.hint&&this.#we(c.hint,n.has(c)),c.failed=r.statusDecidesFailure?c.failed===!0:!!c.stderr,c.failed)this.#ve(`Error · ${c.durationMs} ms`,`error`),this.#Ee(`py-error`,{message:c.problem?.message??c.stderr??``,hint:c.hint,language:this.language,...c.problem??{}});else if(c.cases){let e=c.cases.filter(e=>e.expected!==void 0).length,t=c.passed===e;this.#ve(e?`${c.passed} of ${e} passed · ${c.durationMs} ms`:`Done in ${c.durationMs} ms`,t?`ok`:`error`)}else this.#ve(`Done in ${c.durationMs} ms`,`ok`);return this.#Ee(`py-output`,{...c,language:this.language}),c}catch(e){if(e instanceof t)this.#be(`
714
+ `)}var Q=2e5,$=`playpad-file`,de={python:`main.py`,javascript:`main.js`,typescript:`main.ts`,java:`Main.java`,c:`main.c`,cpp:`main.cpp`,csharp:`Program.cs`,cs:`Program.cs`,react:`src/main.jsx`,next:`app/page.jsx`};function fe(e){return de[e]??`main.txt`}var pe=e=>e.tagName===`SCRIPT`&&e.getAttribute(`type`)===`text/plain`;function me(e){return[...e.children].filter(e=>e.tagName.toLowerCase()===$&&[...e.children].some(e=>!pe(e))).map(e=>e.getAttribute(`name`)??``)}function he(e,t){let n={};for(let t of e.children){if(t.tagName.toLowerCase()!==$)continue;let e=t.getAttribute(`name`),r=[...t.children].find(pe);e&&(n[e]=ue((r??t).textContent??``))}if(Object.keys(n).length)return n;let r=[...e.childNodes].filter(e=>e.nodeType!==Node.ELEMENT_NODE||e.tagName.toLowerCase()!==$),i=r.some(e=>e.nodeType===Node.ELEMENT_NODE),a=ue(r.filter(e=>!(i&&e.nodeType===Node.TEXT_NODE&&!(e.textContent??``).trim())).map(e=>e.textContent??``).join(``));return{[t]:a}}function ge(e,t){try{let t=JSON.parse(e);if(t&&typeof t==`object`&&!Array.isArray(t)){let e=t;return Object.keys(e).length?e:null}}catch{}return e?{[t]:e}:null}var _e=typeof HTMLElement>`u`?class{}:HTMLElement,ve=class extends _e{static get observedAttributes(){return[`language`,`height`,`min-height`,`max-height`,`preview-height`,`tree-width`,`file-view`,`file-actions`,`file-view-switch`,`change-marks`,`open-file`,`theme`,`theme-controls`,`readonly`,`autorun`,`stdin`,`persist`,`entry`,`practice`]}#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u=null;#d=null;#f=null;#p=null;#m={};#h={};#g=!1;#_=`main.py`;#v=null;#y;#b=!1;#x=null;#S=!1;#C=!1;#w=null;#T=null;#E=null;#D=()=>this.#it();#O=null;#k=null;#A=!0;#j=[];#M=null;#N=null;#P=null;#F=0;#I=!1;#L=null;#R;#z;#B=null;#V=``;#H=[];#U=/* @__PURE__ */ new Set;#W=null;#G=null;#K;#q;#J=null;#Y=null;#X=null;#Z=null;#Q=null;constructor(){super(),this.#e=this.attachShadow({mode:`open`})}get code(){return this.#u?this.#u.getCode():this.#m[this.#_]??``}set code(e){this.#m[this.#_]=e,this.#ce(),this.#$e()}get practice(){if(this.#L)return this.#L;let e=this.getAttribute(`practice`);if(!e)return null;try{return JSON.parse(e)}catch{return null}}set practice(e){this.#L=e}get files(){return this.#me()}set files(e){let t=Object.keys(e);if(!t.length)return;let n=Object.keys(this.#h);n.length===1&&!this.#h[n[0]]&&(this.#h={...e}),this.#m={...e},this.#Y=null,this.#Re(),this.#H=[],t.includes(this.#_)||(this.#_=this.#fe()),this.#oe(),this.#se(),this.#he(),this.#ie()}get entry(){return this.#fe()}set entry(e){this.setAttribute(`entry`,e)}openFile(e){if(e in this.#m){this.#u&&(e!==this.#_&&this.#ae(),this.#m[this.#_]=this.#u.getCode(),this.#u.openFile(e,this.#m[e]??``)),this.#_=e,this.#W=null;for(let t=e.indexOf(`/`);t!==-1;t=e.indexOf(`/`,t+1))this.#U.delete(e.slice(0,t));this.#he(),this.#ie()}}addFile(e,t=``){if(this.#X)return this.#X.widget.addFile(e,t);this.#ye();let n=this.#be(e);if(n)throw Error(n);this.#Ce(()=>{this.#m[e]=t}),this.openFile(e),this.#Ee(`add`,e)}renameFile(e,t){if(this.#X)return this.#X.widget.renameFile(e,t);if(this.#ye(),!Object.hasOwn(this.#m,e))throw Error(`There is no file named "${e}".`);let n=this.#xe(e);if(n)throw Error(`"${e}" can't be renamed: ${n}.`);if(t===e)return;let r=this.#be(t,e);if(r)throw Error(r);let i=this.#me()[e];this.#Ce(()=>{this.#m=Object.fromEntries(Object.entries(this.#m).map(([n,r])=>n===e?[t,i]:[n,r]))}),this.#u?.renameFile(e,t),this.#H=this.#H.filter(t=>t!==e),this.#_===e&&(this.#_=t,this.#we(t)),this.#he(),this.#ie(),this.#Ee(`rename`,t,e)}removeFile(e){if(this.#X)return this.#X.widget.removeFile(e);if(this.#ye(),!Object.hasOwn(this.#m,e))throw Error(`There is no file named "${e}".`);if(Object.keys(this.#m).length===1)throw Error(`"${e}" can't be removed: it's the only file.`);let t=this.#xe(e);if(t)throw Error(`"${e}" can't be removed: ${t}.`);this.#_===e&&this.openFile(this.#Te(e)),delete this.#m[e],this.#u?.forgetFiles(Object.keys(this.#m)),this.#H=this.#H.filter(t=>t!==e),this.#he(),this.#Ee(`remove`,e)}get stdin(){return this.#l?this.#l.value:``}set stdin(e){this.#l&&(this.#l.value=e,this.#c.hidden=!1,this.#$e())}get language(){return this.getAttribute(`language`)||`python`}set language(e){this.setAttribute(`language`,e)}getCode(){return this.code}getFiles(){return this.#me()}reset(){this.#ae(),this.#Re(),this.#Y=null,this.#m={...this.#h},this.#_=this.#fe(),this.#se(),this.#he(),this.#ie(),this.#st(),this.#s.hidden=!0,this.#Qe(),this.#B=null,this.#$e(),this.#ot(this.#f?.ready?`${this.#f.label} ready`:``,`idle`),this.#ve()&&this.#tt(0)}async run(){if(this.#X)return this.#X.widget.run();if(this.#b)return;await this.#d;let e=this.#me(),r=this.getAttribute(`entry`);if(r&&!(r in e))return this.#ue(r,e);this.#le=!1;let i=this.#fe(),a=e[i]??``;this.#b=!0,this.#S=!1,this.#n.disabled=!0,this.#r.hidden=!1,this.#st(),this.#s.hidden=!1;let o=this.practice;this.hasAttribute(`practice`)&&!o&&this.#ct(`The practice attribute is not valid JSON.
715
+ `,`cp-err`),this.#B=e,this.#V=this.#l.value,this.#$e(),this.#Ze()&&this.#H.length&&this.#ct(`${this.#H.join(`, `)}: HTML tags in this file's markup were read as elements, so its code is incomplete. Write < as &lt;, or put the code in <script type="text/plain">. A <script> left unescaped runs on the host page.\n`,`cp-err`),this.#mt(`py-run`,{code:a,entry:i,files:e,language:this.language,...o?{practice:o}:{}});try{let r=await this.#re();if(this.#S)throw new t;if(o&&!r.supportsPractice)throw Error(`Practice mode is not available for ${r.label}.`);this.#ot(`Queued…`,`busy`),this.#o.hidden=!1;let s=r.run(a,{stdin:this.#l.value,files:e,entry:i,onStart:()=>this.#ot(`Running…`,`busy`),onProgress:e=>this.#ot(e.message,`busy`),onStdout:e=>this.#ct(e),onStderr:e=>this.#ct(e,`cp-err`),onEcho:e=>this.#ct(e,`cp-in`),onStdinRequest:()=>this.#ut(),...o?{practice:o}:{},...this.#Ze()?{preview:{host:this.#R,onStart:()=>this.#ot(`Running…`,`busy`),onConsole:(e,t)=>{this.#ct(`${t}\n`,e===`error`?`cp-err`:e===`warn`?`cp-warn`:void 0),this.#ht(`playpad-console`,{level:e,text:t,language:this.language})},onRender:e=>this.#ht(`playpad-render`,{rootText:e,language:this.language}),onError:e=>{this.#ot(`Error`,`error`),this.#mt(`py-error`,{...e,language:this.language})}}}:{}});this.#x={runtime:r,run:s};let c=await s;if(c.table&&this.#pt(c.table),c.value!==void 0&&this.#ct(`${c.value}\n`,`cp-value`),c.hint&&this.#ft(c.hint,n.has(c)),c.failed=r.statusDecidesFailure?c.failed===!0:!!c.stderr,c.failed)this.#ot(`Error · ${c.durationMs} ms`,`error`),this.#mt(`py-error`,{message:c.problem?.message??c.stderr??``,hint:c.hint,language:this.language,...c.problem??{}});else if(c.cases){let e=c.cases.filter(e=>e.expected!==void 0).length,t=c.passed===e;this.#ot(e?`${c.passed} of ${e} passed · ${c.durationMs} ms`:`Done in ${c.durationMs} ms`,t?`ok`:`error`)}else this.#ot(`Done in ${c.durationMs} ms`,`ok`);return this.#mt(`py-output`,{...c,language:this.language}),c}catch(e){if(e instanceof t)this.#ct(`
573
716
  [stopped]
574
- `,`cp-err`),this.#ve(`Stopped`,`error`);else{let t=e instanceof Error?e.message:String(e);this.#be(t+`
575
- `,`cp-err`),this.#ve(`Failed to start`,`error`),this.#Ee(`py-error`,{message:t,language:this.language})}return}finally{this.#x=null,this.#Ce(null),this.#xe(),this.#b=!1,this.#n.disabled=!1,this.#r.hidden=!(this.#ue()&&this.#f?.hasLivePreview?.(this.#R)),this.#o.hidden=!0}}stop(){this.#U?this.#U.widget.stop():this.#x?this.#x.runtime.stop?.(this.#x.run):this.#b?this.#S=!0:this.#ue()&&this.#f?.hasLivePreview?.(this.#R)&&(this.#de(),this.#r.hidden=!0,this.#ve(`Stopped`,`idle`))}openWindow(){if(this.#U)return this.#U.window.focus(),!0;if(this.#W)return!1;let e=window.open(``,`_blank`,`popup,width=1280,height=800`);if(!e)return this.#ve(`The browser blocked the new window`,`error`),!1;let t=this.#se(),n=this.#_,r=document.createElement(this.localName);for(let e of[`language`,`entry`,`file-view`,`preview-height`,`tree-width`,`theme`,`theme-controls`,`readonly`,`stdin`]){let t=this.getAttribute(e);t!==null&&r.setAttribute(e,t)}r.setAttribute(`data-window`,``),r.#W=this,r.#G={...this.#h},r.#v=t,this.#de(),this.#r.hidden=!0,e.document.title=`Code playground`,e.document.documentElement.style.height=`100%`,e.document.body.style.cssText=`margin:0;height:100%`,e.document.body.append(r);let i=()=>this.closeWindow();return window.addEventListener(`pagehide`,i),this.#U={window:e,widget:r,onLeave:i,timer:setInterval(()=>{e.closed&&this.closeWindow()},300)},this.#e.querySelector(`.cp-root`)?.classList.add(`cp-popped`),r.#d?.then(()=>(r.openFile(n),r.run())),!0}closeWindow(){let e=this.#U;if(!e)return;this.#U=null,clearInterval(e.timer),window.removeEventListener(`pagehide`,e.onLeave);let{widget:t}=e,n=t.#se(),r=t.#_;t.#de(),t.remove(),e.window.closed||e.window.close(),this.#e.querySelector(`.cp-root`)?.classList.remove(`cp-popped`),this.files=n,this.openFile(r),this.#ve(``,`idle`)}prewarm(){return this.#X()}connectedCallback(){this.#I?(this.#ge(),this.#Y()):!this.textContent?.trim()&&document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#K(),{once:!0}):this.#K()}disconnectedCallback(){this.#w?.disconnect(),this.#w=null,this.#T?.removeEventListener(`change`,this.#D),this.#T=null,this.#E?.disconnect(),this.#E=null,this.#O?.(),this.#O=null,this.#k&&clearTimeout(this.#k),this.#Ce(null),setTimeout(()=>{this.isConnected||(this.closeWindow(),this.#de(),this.#u&&(this.#v=this.#se(),this.#u.destroy(),this.#u=null,this.#d=null,this.#I=!1))},0)}attributeChangedCallback(e,t,n){if(this.#I)switch(e){case`theme`:case`theme-controls`:this.#ge();break;case`height`:this.#$(),this.#_e();break;case`min-height`:case`max-height`:case`preview-height`:case`tree-width`:this.#_e();break;case`readonly`:this.#u?.setReadOnly(n!==null);break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`entry`:case`file-view`:this.#ce();break;case`language`:this.#de(),this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-has-preview`,this.#ue()),this.#f=null,this.#p=null,this.#C=!1,this.#X().catch(()=>{})}}#K(){this.#I=!0,this.#h=this.#G??ae(this,this.#ie()),this.#V=this.#ue()?ie(this):[],this.#m=this.#v??{...this.#h},this.#_=this.#oe(),this.#q(),this.#ge(),this.#_e();let e=this.getAttribute(`persist`);this.#d=(async()=>{if(e&&this.#v==null){let t=await G(e).catch(()=>null),n=t==null?null:oe(t,this.#ie());if(n){let e={},t=Object.keys(this.#h),r=Object.keys(n);for(let r of t)e[r]=n[r]??this.#h[r];t.length===1&&r.length===1&&!(t[0]in n)&&(e[t[0]]=n[r[0]]),this.#m=e,this.#_=this.#oe()}}this.#ce();let t=await N(this.language).catch(()=>null),n=t?await t.editorLanguage().catch(()=>null):null;this.#u=await S({parent:this.#t,doc:this.#m[this.#_]??``,name:this.#_,dark:this.#me(),themeId:this.#he(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#pe(e)}),this.#v=null,this.#ge(),this.#Z()})(),this.#Y()}#q(){let e=document.createElement(`style`);e.textContent=P;let t=document.createElement(`div`);t.className=this.#ue()?`cp-root cp-has-preview`:`cp-root`,t.innerHTML=`
717
+ `,`cp-err`),this.#ot(`Stopped`,`error`);else{let t=e instanceof Error?e.message:String(e);this.#ct(t+`
718
+ `,`cp-err`),this.#ot(`Failed to start`,`error`),this.#mt(`py-error`,{message:t,language:this.language})}return}finally{this.#x=null,this.#dt(null),this.#lt(),this.#b=!1,this.#n.disabled=!1,this.#r.hidden=!(this.#Ze()&&this.#f?.hasLivePreview?.(this.#R)),this.#o.hidden=!0}}stop(){this.#X?this.#X.widget.stop():this.#x?this.#x.runtime.stop?.(this.#x.run):this.#b?this.#S=!0:this.#Ze()&&this.#f?.hasLivePreview?.(this.#R)&&(this.#Qe(),this.#r.hidden=!0,this.#ot(`Stopped`,`idle`))}openWindow(){if(this.#X)return this.#X.window.focus(),!0;if(this.#Z)return!1;let e=window.open(``,`_blank`,`popup,width=1280,height=800`);if(!e)return this.#ot(`The browser blocked the new window`,`error`),!1;let t=this.#me(),n=this.#_,r=document.createElement(this.localName);for(let e of[`language`,`entry`,`file-view`,`file-view-switch`,`file-actions`,`change-marks`,`preview-height`,`tree-width`,`theme`,`theme-controls`,`readonly`,`stdin`]){let t=this.getAttribute(e);t!==null&&r.setAttribute(e,t)}r.setAttribute(`data-window`,``),r.#Z=this,r.#Q={...this.#h},r.#v=t,r.#Y=this.#Y,this.#Qe(),this.#r.hidden=!0,e.document.title=`Code playground`,e.document.documentElement.style.height=`100%`,e.document.body.style.cssText=`margin:0;height:100%`,e.document.body.append(r);let i=()=>this.closeWindow();return window.addEventListener(`pagehide`,i),this.#X={window:e,widget:r,onLeave:i,timer:setInterval(()=>{e.closed&&this.closeWindow()},300)},this.#e.querySelector(`.cp-root`)?.classList.add(`cp-popped`),r.#d?.then(()=>(r.openFile(n),r.run())),!0}closeWindow(){let e=this.#X;if(!e)return;this.#X=null,clearInterval(e.timer),window.removeEventListener(`pagehide`,e.onLeave);let{widget:t}=e,n=t.#me(),r=t.#_;t.#Qe(),t.remove(),e.window.closed||e.window.close(),this.#e.querySelector(`.cp-root`)?.classList.remove(`cp-popped`),this.files=n,this.#Y=t.#Y;let i=t.getAttribute(`file-view`);i!==this.getAttribute(`file-view`)&&(i===null?this.removeAttribute(`file-view`):this.setAttribute(`file-view`,i)),this.openFile(r),this.#ot(``,`idle`),this.#ve()&&this.#tt(0)}prewarm(){return this.#re()}connectedCallback(){this.#I?(this.#it(),this.#ne()):!this.textContent?.trim()&&document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,()=>this.isConnected&&this.#$(),{once:!0}):this.#$()}disconnectedCallback(){this.#w?.disconnect(),this.#w=null,this.#T?.removeEventListener(`change`,this.#D),this.#T=null,this.#E?.disconnect(),this.#E=null,this.#O?.(),this.#O=null,this.#k&&clearTimeout(this.#k),this.#dt(null),setTimeout(()=>{this.isConnected||(this.closeWindow(),this.#Qe(),this.#u&&(this.#v=this.#me(),this.#u.destroy(),this.#u=null,this.#d=null,this.#I=!1))},0)}attributeChangedCallback(e,t,n){if(this.#I)switch(e){case`theme`:case`theme-controls`:this.#it();break;case`height`:this.#oe(),this.#at();break;case`min-height`:case`max-height`:case`preview-height`:case`tree-width`:this.#at();break;case`readonly`:this.#u?.setReadOnly(n!==null),this.hasAttribute(`file-actions`)&&(this.#Re(),this.#he());break;case`stdin`:this.#c.hidden=n===null&&!this.#l.value;break;case`file-view`:case`file-actions`:this.#Re(),this.#he();break;case`entry`:case`file-view-switch`:this.#he();break;case`change-marks`:this.#$e();break;case`language`:this.#Qe(),this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-has-preview`,this.#Ze()),this.#f=null,this.#p=null,this.#C=!1,this.#re().catch(()=>{})}}#$(){this.#I=!0,this.#h=this.#Q??he(this,this.#de()),this.#H=this.#Ze()?me(this):[],this.#m=this.#v??{...this.#h},this.#_=this.#pe(),this.#ee(),this.#it(),this.#at();let e=this.getAttribute(`persist`);this.#d=(async()=>{if(e&&this.#v==null){let t=await W(e).catch(()=>null),n=t==null?null:ge(t,this.#de()),r=n&&this.#ve()?await this.#De(e):null;if(n&&r){let e=[this.#fe(),...this.#Se()],t=le(n,r,this.#h);for(let n of e)!Object.hasOwn(t,n)&&Object.hasOwn(this.#h,n)&&(t[n]=this.#h[n]);this.#Ce(()=>{this.#m=t}),this.#_=this.#pe()}else if(n){let e={},t=Object.keys(this.#h),r=Object.keys(n);for(let r of t)e[r]=n[r]??this.#h[r];t.length===1&&r.length===1&&!(t[0]in n)&&(e[t[0]]=n[r[0]]),this.#m=e,this.#_=this.#pe()}}this.#he();let t=await M(this.language).catch(()=>null),n=t?await t.editorLanguage().catch(()=>null):null;this.#u=await S({parent:this.#t,doc:this.#m[this.#_]??``,name:this.#_,dark:this.#nt(),themeId:this.#rt(),readOnly:this.hasAttribute(`readonly`),language:n,onRun:()=>void this.run(),onChange:e=>this.#et(e)}),this.#v=null,this.#it(),this.#ie()})(),this.#ne()}#ee(){let e=document.createElement(`style`);e.textContent=N;let t=document.createElement(`div`);if(t.className=this.#Ze()?`cp-root cp-has-preview`:`cp-root`,t.innerHTML=`
576
719
  <div class="cp-toolbar">
577
720
  <button class="cp-primary" part="run-button" data-action="run">Run</button>
578
721
  <button class="cp-danger" part="stop-button" data-action="stop" hidden>Stop</button>
579
722
  <button data-action="reset">Reset</button>
580
723
  <span class="cp-spacer"></span>
724
+ <button part="file-view-button" class="cp-icon-button" data-action="file-view" hidden></button>
581
725
  <button part="theme-button" class="cp-icon-button" data-action="theme">
582
726
  <svg class="cp-theme-moon" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
583
727
  <svg class="cp-theme-sun" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
@@ -591,7 +735,6 @@ table.cp-table th { background: var(--cp-bg); }
591
735
  <button part="window-button" class="cp-icon-button cp-window-button" data-action="window" aria-label="Open in window" title="Open in a separate window you can resize">
592
736
  <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14 4h6v6M20 4l-9 9M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/></svg>
593
737
  </button>
594
- <span class="cp-edited-note" hidden>Edited since the last run</span>
595
738
  <span class="cp-status" data-state="idle"></span>
596
739
  </div>
597
740
  <div class="cp-progress" hidden></div>
@@ -605,6 +748,8 @@ table.cp-table th { background: var(--cp-bg); }
605
748
  <div class="cp-tabs" part="tabs" hidden></div>
606
749
  <div class="cp-split cp-split-tree" role="separator" tabindex="0" aria-orientation="vertical" aria-label="Resize the file tree"></div>
607
750
  <div class="cp-editor"></div>
751
+ <div class="cp-file-overlay cp-file-pop" hidden></div>
752
+ <div class="cp-file-overlay cp-file-message" role="status" hidden></div>
608
753
  <div class="cp-stdin" hidden>
609
754
  <label>Standard input — one value per line</label>
610
755
  <textarea rows="2" spellcheck="false"></textarea>
@@ -615,11 +760,12 @@ table.cp-table th { background: var(--cp-bg); }
615
760
  <div class="cp-preview" part="preview"></div>
616
761
  <div class="cp-split cp-split-console" role="separator" tabindex="0" aria-orientation="horizontal" aria-label="Resize the preview and the console"></div>
617
762
  <pre class="cp-output" part="output" hidden></pre>
763
+ <div class="cp-stale-note" part="stale-note" role="status" hidden></div>
618
764
  </div>
619
- </div>`,this.#e.replaceChildren(e,t),this.#n=t.querySelector(`[data-action="run"]`),this.#r=t.querySelector(`[data-action="stop"]`),this.#i=t.querySelector(`[data-action="reset"]`),this.#a=t.querySelector(`.cp-status`),this.#o=t.querySelector(`.cp-progress`),this.#y=t.querySelector(`.cp-tabs`),this.#t=t.querySelector(`.cp-editor`),this.#c=t.querySelector(`.cp-stdin`),this.#l=t.querySelector(`.cp-stdin textarea`),this.#s=t.querySelector(`.cp-output`),this.#R=t.querySelector(`.cp-preview`),this.#z=t.querySelector(`.cp-edited-note`),this.#ue()||t.querySelector(`.cp-source`).after(this.#s),this.#c.hidden=!this.hasAttribute(`stdin`),this.#l.addEventListener(`input`,()=>this.#c.classList.remove(`cp-attention`)),this.#y.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`button[data-file]`);n&&this.openFile(n.getAttribute(`data-file`));let r=t.closest(`button[data-folder]`)?.dataset.folder;r!==void 0&&(this.#H.delete(r)||this.#H.add(r),this.#ce())}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.reset()),t.querySelector(`[data-action="theme"]`).addEventListener(`click`,()=>{y({mode:this.#me()?`light`:`dark`})}),t.querySelector(`.cp-theme-picker select`).addEventListener(`change`,e=>{let t=e.target.value,n=d.find(e=>e.id===t)?.mode;n&&y({mode:n,[n]:t})}),t.querySelector(`[data-action="window"]`).addEventListener(`click`,()=>this.openWindow()),t.querySelector(`[data-action="show-window"]`).addEventListener(`click`,()=>this.openWindow()),t.querySelector(`[data-action="close-window"]`).addEventListener(`click`,()=>this.closeWindow()),this.#J(t);let n=()=>void this.#X().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#J(e){let t=e.querySelector(`.cp-body`),n=e.querySelector(`.cp-source`),r=e.querySelector(`.cp-preview`),i=e.querySelector(`.cp-preview-pane`),a=this.#y,o=(e,t,n)=>Math.round(Math.max(t,Math.min(e,Math.max(t,n)))),s=(t,n)=>e.style.setProperty(t,`${n}px`),c=(t,n,r,i,a)=>{let o=()=>t.setAttribute(`aria-orientation`,n()===`x`?`vertical`:`horizontal`);t.addEventListener(`pointerdown`,a=>{a.preventDefault();let o=n()===`x`,s=o?a.clientX:a.clientY,c=r();t.setPointerCapture(a.pointerId),e.classList.add(`cp-dragging`,o?`cp-dragging-x`:`cp-dragging-y`);let l=e=>i(c+(o?e.clientX:e.clientY)-s),u=()=>{e.classList.remove(`cp-dragging`,`cp-dragging-x`,`cp-dragging-y`),t.removeEventListener(`pointermove`,l),t.removeEventListener(`pointerup`,u),t.removeEventListener(`pointercancel`,u)};t.addEventListener(`pointermove`,l),t.addEventListener(`pointerup`,u),t.addEventListener(`pointercancel`,u)}),t.addEventListener(`keydown`,e=>{let t={ArrowLeft:-24,ArrowUp:-24,ArrowRight:24,ArrowDown:24}[e.key];t&&(e.preventDefault(),i(r()+t))}),t.addEventListener(`dblclick`,a),t.addEventListener(`focus`,o),t.addEventListener(`pointerenter`,o)},l=()=>getComputedStyle(t).flexDirection===`row`&&getComputedStyle(t).display===`flex`;c(e.querySelector(`.cp-split-tree`),()=>`x`,()=>a.getBoundingClientRect().width,e=>s(`--cp-tree-width`,o(e,90,n.getBoundingClientRect().width-160)),()=>e.style.removeProperty(`--cp-tree-width`)),c(e.querySelector(`.cp-split-main`),()=>l()?`x`:`y`,()=>l()?n.getBoundingClientRect().width:this.#t.getBoundingClientRect().height,n=>{l()?s(`--cp-source-width`,o(n,200,t.getBoundingClientRect().width-200)):(s(`--cp-editor-height`,o(n,80,this.#W?t.getBoundingClientRect().height-100:2e3)),e.classList.add(`cp-editor-sized`))},()=>{e.style.removeProperty(`--cp-source-width`),e.style.removeProperty(`--cp-editor-height`),e.classList.remove(`cp-editor-sized`)}),c(e.querySelector(`.cp-split-console`),()=>`y`,()=>r.getBoundingClientRect().height,e=>s(`--cp-preview-height`,o(e,60,l()||this.#W?i.getBoundingClientRect().height-40:2e3)),()=>e.style.removeProperty(`--cp-preview-height`))}#Y(){this.#W||this.#w||typeof IntersectionObserver>`u`||(this.#w=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#w?.disconnect(),this.#w=null,this.#X().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#w.observe(this))}#X(){return this.#p||=(async()=>{let e=await N(this.language);this.#f=e,!e.ready&&!this.#ne&&(this.#o.hidden=!1,this.#ve(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{!this.#b&&!this.#ne&&this.#ve(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#ve(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#be(t+`
620
- `,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#Z(),this.#C||(this.#C=!0,this.#ne||this.#ve(`${e.label} ready`,`ok`),this.#Ee(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#Z(){if(!this.#u)return;let e=this.#_,t=await ee(e,this.language);if(t){this.#_===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await N(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#_===e&&this.#u?.setLanguage(n??[])}#Q(){if(this.getAttribute(`height`)!==`auto`||this.#W)return;let e=this.#e.querySelector(`.cp-root`),t=this.#t.getBoundingClientRect().height;e&&t&&!e.classList.contains(`cp-editor-sized`)&&(e.style.setProperty(`--cp-editor-height`,`${t}px`),e.classList.add(`cp-editor-sized`),this.#g=!0)}#$(){if(!this.#g)return;this.#g=!1;let e=this.#e.querySelector(`.cp-root`);e?.style.removeProperty(`--cp-editor-height`),e?.classList.remove(`cp-editor-sized`)}#ee(){this.#u?.openFile(this.#_,this.#m[this.#_]??``),this.#u?.forgetFiles([]),this.#te()}#te(){this.#u?this.#u.setCode(this.#m[this.#_]??``):this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#_]??``),this.#ce()})}#ne=!1;#re(e,t){let n=Object.keys(t),r=`This widget's entry is "${e}", but it has no file of that name${n.length?` (its files: ${n.join(`, `)})`:``}. Set entry to one of its files.\n`;this.#ye(),this.#s.hidden=!1,this.#be(r,`cp-err`),this.#ne=!0,this.#ve(`Error · entry not found`,`error`);let i={stdout:``,stderr:r,durationMs:0,failed:!0};return this.#Ee(`py-error`,{message:r,language:this.language}),this.#Ee(`py-output`,{...i,language:this.language}),i}#ie(){return this.getAttribute(`entry`)||ne(this.language)}#ae(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;let n=this.#ue()&&e.includes(`index.html`)?`index.html`:ne(this.language);if(e.includes(n))return n;if(this.language===`next`){let t=e.filter(e=>/^(src\/)?app\/(\([^/]+\)\/)*page\.(jsx?|tsx?)$/.test(e)).sort((e,t)=>e.split(`/`).length-t.split(`/`).length)[0];if(t)return t}return e[0]??n}#oe(){let e=this.getAttribute(`open-file`);return e&&e in this.#m?e:this.#ae()}#se(){if(this.#U)return this.#U.widget.#se();let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#ce(){let e=Object.keys(this.#m);this.#y.hidden=e.length<2;let t=!this.#y.hidden&&this.getAttribute(`file-view`)===`tree`;if(this.#y.classList.toggle(`cp-tree`,t),this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-has-tree`,t),this.#y.hidden){this.#y.replaceChildren();return}if(t){this.#le(e),this.#fe();return}let n=this.#ae();this.#y.replaceChildren(...e.map(e=>{let t=document.createElement(`button`);t.dataset.file=e;let r=e.lastIndexOf(`/`)+1;if(r){let n=document.createElement(`span`);n.className=`cp-tab-folder`,n.textContent=e.slice(0,r),t.setAttribute(`aria-label`,e),t.append(n)}return t.append(e.slice(r)),t.setAttribute(`aria-pressed`,String(e===this.#_)),e===n&&(t.classList.add(`cp-entry`),t.title=`entry point — this is the file Run executes`),t})),this.#fe()}#le(e){let t=this.#ae(),n=[],r=(i,a)=>{let o=e.filter(e=>e.startsWith(i)).map(e=>e.slice(i.length)),s=[...new Set(o.filter(e=>e.includes(`/`)).map(e=>e.slice(0,e.indexOf(`/`))))].sort();for(let e of s){let t=i+e,o=!this.#H.has(t),s=document.createElement(`button`);s.className=`cp-tree-folder`,s.dataset.folder=t,s.textContent=e,s.setAttribute(`aria-expanded`,String(o)),s.style.setProperty(`--cp-depth`,String(a)),n.push(s),o&&r(`${t}/`,a+1)}for(let e of o.filter(e=>!e.includes(`/`)).sort()){let r=i+e,o=document.createElement(`button`);o.dataset.file=r,o.textContent=e,o.setAttribute(`aria-label`,r),o.setAttribute(`aria-pressed`,String(r===this.#_)),o.style.setProperty(`--cp-depth`,String(a)),r===t&&(o.classList.add(`cp-entry`),o.title=`entry point — this is the file Run executes`),n.push(o)}};r(``,0),this.#y.replaceChildren(...n)}#ue(){return this.language===`react`||this.language===`next`}#de(){this.#R&&(this.#f?.dispose?.(this.#R),this.#R.replaceChildren())}#fe(){if(!this.#ue())return;let e=this.#se();for(let t of this.#y.querySelectorAll(`button[data-file]`)){let n=t.dataset.file;t.classList.toggle(`cp-edited`,e[n]!==this.#h[n])}let t=this.#B;this.#z.hidden=!t||Object.keys(e).every(n=>e[n]===t[n])}#pe(e){this.#m[this.#_]=e,this.#fe();let t=this.getAttribute(`persist`);if(!t)return;this.#k&&clearTimeout(this.#k);let n=JSON.stringify(this.#se());this.#k=setTimeout(()=>void W(t,n).catch(()=>{}),400)}#me(){let e=this.getAttribute(`theme`)??`auto`;if(e===`dark`)return!0;if(e===`light`)return!1;let t=v().mode;if(t)return t===`dark`;let n=typeof document>`u`?``:getComputedStyle(document.documentElement).colorScheme,r=n.includes(`dark`);return r===n.includes(`light`)?!!this.#T?.matches:r}#he(){return v()[this.#me()?`dark`:`light`]}#ge(){this.#O??=b(this.#D),!this.#T&&typeof matchMedia==`function`&&(this.#T=matchMedia(`(prefers-color-scheme: dark)`),this.#T.addEventListener(`change`,this.#D)),!this.#E&&typeof MutationObserver==`function`&&typeof document<`u`&&(this.#E=new MutationObserver(this.#D),this.#E.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`,`style`,`data-theme`,`data-color-scheme`,`color-scheme`]}));let e=this.#me(),t=this.#he();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.setAttribute(`data-editor-theme`,t),this.#u?.setTheme(e,t);let n=this.getAttribute(`theme`),r=n===`light`||n===`dark`||this.getAttribute(`theme-controls`)===`off`,i=this.#e.querySelector(`[data-action="theme"]`),a=this.#e.querySelector(`.cp-theme-picker`);if(i&&a){let n=e?`Switch to the light theme`:`Switch to the dark theme`;i.hidden=a.hidden=r,i.title=n,i.setAttribute(`aria-label`,n),a.querySelector(`select`).value=t}}#_e(){for(let[e,t]of[[`height`,`--cp-height`],[`min-height`,`--cp-min-height`],[`max-height`,`--cp-max-height`],[`preview-height`,`--cp-preview-height`]]){let n=this.getAttribute(e);n===null||n===``?this.style.removeProperty(t):this.style.setProperty(t,/^\d+$/.test(n)?`${n}px`:n)}let e=this.getAttribute(`tree-width`)?.trim();e?/^(\d+(px)?|\d+(\.\d+)?%)$/.test(e)?this.style.setProperty(`--cp-tree-width`,/\d$/.test(e)?`${e}px`:e):(this.style.removeProperty(`--cp-tree-width`),console.warn(`code-playpad: tree-width="${e}" is not a size. Use a percentage like "20%" or pixels like "240".`)):this.style.removeProperty(`--cp-tree-width`)}#ve(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#ye(){this.#P&&clearTimeout(this.#P),this.#P=null,this.#j=[],this.#F=0,this.#s.replaceChildren(),this.#A=!0}#be(e,t){if(!e)return;let n=t===`cp-err`&&!this.#A?`\n${e}`:e;this.#A=n.endsWith(`
621
- `),this.#j.push({text:n,className:t}),this.#P??=setTimeout(()=>this.#xe(),16)}#xe(){if(this.#P&&clearTimeout(this.#P),this.#P=null,!this.#j.length)return;let e=this.#j;this.#j=[];let t=document.createDocumentFragment(),n=``,r,i=()=>{if(!n)return;let e=document.createElement(`span`);r&&(e.className=r),e.textContent=n,t.appendChild(e),n=``};for(let t of e){if(this.#F>=Q)break;let e=t.text;this.#F+e.length>Q&&(e=e.slice(0,Q-this.#F)+`
765
+ </div>`,this.#e.replaceChildren(e,t),this.#n=t.querySelector(`[data-action="run"]`),this.#r=t.querySelector(`[data-action="stop"]`),this.#i=t.querySelector(`[data-action="reset"]`),this.#a=t.querySelector(`.cp-status`),this.#o=t.querySelector(`.cp-progress`),this.#y=t.querySelector(`.cp-tabs`),this.#t=t.querySelector(`.cp-editor`),this.#c=t.querySelector(`.cp-stdin`),this.#l=t.querySelector(`.cp-stdin textarea`),this.#s=t.querySelector(`.cp-output`),this.#R=t.querySelector(`.cp-preview`),this.#z=t.querySelector(`.cp-stale-note`),this.#K=t.querySelector(`.cp-file-pop`),this.#q=t.querySelector(`.cp-file-message`),!this.#Ze()){let e=document.createElement(`div`);e.className=`cp-output-box`,t.querySelector(`.cp-source`).after(e),e.append(this.#s,this.#z)}this.#c.hidden=!this.hasAttribute(`stdin`),this.#l.addEventListener(`input`,()=>{this.#c.classList.remove(`cp-attention`),this.#$e()}),this.#y.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-file-action]`);if(n){this.#Pe(n);return}let r=t.closest(`[data-more]`);if(r){this.#qe(r,r.dataset.more);return}if(t.closest(`[data-target-root]`)){this.#W=``,this.#he(),this.#y.querySelector(`[data-target-root]`)?.focus();return}let i=t.closest(`button[data-file]`);i&&this.openFile(i.getAttribute(`data-file`));let a=t.closest(`button[data-folder]`)?.dataset.folder;a!==void 0&&(this.#ve()&&(this.#W=a),this.#U.delete(a)||this.#U.add(a),this.#he())}),this.#n.addEventListener(`click`,()=>void this.run()),this.#r.addEventListener(`click`,()=>this.stop()),this.#i.addEventListener(`click`,()=>this.#Xe()),this.#K.addEventListener(`keydown`,e=>{let t={ArrowDown:1,ArrowRight:1,ArrowUp:-1,ArrowLeft:-1}[e.key];if(e.key!==`Escape`&&!t)return;if(e.preventDefault(),!t)return this.#Ge(!0);let n=[...this.#K.querySelectorAll(`button`)];n[(n.indexOf(this.#e.activeElement)+t+n.length)%n.length]?.focus()}),this.#K.addEventListener(`focusout`,e=>{let t=e.relatedTarget;t&&!this.#K.contains(t)&&this.#Ge(!1)}),t.addEventListener(`pointerdown`,e=>{!this.#K.hidden&&!e.composedPath().includes(this.#K)&&this.#Ge(!1)}),t.querySelector(`[data-action="theme"]`).addEventListener(`click`,()=>{y({mode:this.#nt()?`light`:`dark`})}),t.querySelector(`.cp-theme-picker select`).addEventListener(`change`,e=>{let t=e.target.value,n=d.find(e=>e.id===t)?.mode;n&&y({mode:n,[n]:t})}),t.querySelector(`[data-action="file-view"]`).addEventListener(`click`,()=>{this.setAttribute(`file-view`,this.getAttribute(`file-view`)===`tree`?`tabs`:`tree`)}),t.querySelector(`[data-action="window"]`).addEventListener(`click`,()=>this.openWindow()),t.querySelector(`[data-action="show-window"]`).addEventListener(`click`,()=>this.openWindow()),t.querySelector(`[data-action="close-window"]`).addEventListener(`click`,()=>this.closeWindow()),this.#te(t);let n=()=>void this.#re().catch(()=>{});this.#t.addEventListener(`pointerdown`,n,{once:!0}),this.#t.addEventListener(`focusin`,n,{once:!0})}#te(e){let t=e.querySelector(`.cp-body`),n=e.querySelector(`.cp-source`),r=e.querySelector(`.cp-preview`),i=e.querySelector(`.cp-preview-pane`),a=this.#y,o=(e,t,n)=>Math.round(Math.max(t,Math.min(e,Math.max(t,n)))),s=(t,n)=>e.style.setProperty(t,`${n}px`),c=(t,n,r,i,a)=>{let o=()=>t.setAttribute(`aria-orientation`,n()===`x`?`vertical`:`horizontal`);t.addEventListener(`pointerdown`,a=>{a.preventDefault();let o=n()===`x`,s=o?a.clientX:a.clientY,c=r();t.setPointerCapture(a.pointerId),e.classList.add(`cp-dragging`,o?`cp-dragging-x`:`cp-dragging-y`);let l=e=>i(c+(o?e.clientX:e.clientY)-s),u=()=>{e.classList.remove(`cp-dragging`,`cp-dragging-x`,`cp-dragging-y`),t.removeEventListener(`pointermove`,l),t.removeEventListener(`pointerup`,u),t.removeEventListener(`pointercancel`,u)};t.addEventListener(`pointermove`,l),t.addEventListener(`pointerup`,u),t.addEventListener(`pointercancel`,u)}),t.addEventListener(`keydown`,e=>{let t={ArrowLeft:-24,ArrowUp:-24,ArrowRight:24,ArrowDown:24}[e.key];t&&(e.preventDefault(),i(r()+t))}),t.addEventListener(`dblclick`,a),t.addEventListener(`focus`,o),t.addEventListener(`pointerenter`,o)},l=()=>getComputedStyle(t).flexDirection===`row`&&getComputedStyle(t).display===`flex`;c(e.querySelector(`.cp-split-tree`),()=>`x`,()=>a.getBoundingClientRect().width,e=>s(`--cp-tree-width`,o(e,90,n.getBoundingClientRect().width-160)),()=>e.style.removeProperty(`--cp-tree-width`)),c(e.querySelector(`.cp-split-main`),()=>l()?`x`:`y`,()=>l()?n.getBoundingClientRect().width:this.#t.getBoundingClientRect().height,n=>{l()?s(`--cp-source-width`,o(n,200,t.getBoundingClientRect().width-200)):(s(`--cp-editor-height`,o(n,80,this.#Z?t.getBoundingClientRect().height-100:2e3)),e.classList.add(`cp-editor-sized`))},()=>{e.style.removeProperty(`--cp-source-width`),e.style.removeProperty(`--cp-editor-height`),e.classList.remove(`cp-editor-sized`)}),c(e.querySelector(`.cp-split-console`),()=>`y`,()=>r.getBoundingClientRect().height,e=>s(`--cp-preview-height`,o(e,60,l()||this.#Z?i.getBoundingClientRect().height-40:2e3)),()=>e.style.removeProperty(`--cp-preview-height`))}#ne(){this.#Z||this.#w||typeof IntersectionObserver>`u`||(this.#w=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(this.#w?.disconnect(),this.#w=null,this.#re().then(()=>{this.hasAttribute(`autorun`)&&this.run()}).catch(()=>{}))},{rootMargin:`300px`}),this.#w.observe(this))}#re(){return this.#p||=(async()=>{let e=await M(this.language);this.#f=e,!e.ready&&!this.#le&&(this.#o.hidden=!1,this.#ot(`Loading ${e.label}…`,`busy`));try{await e.load(e=>{!this.#b&&!this.#le&&this.#ot(e.message,e.phase===`ready`?`ok`:`busy`)})}catch(e){this.#p=null,this.#ot(`Runtime unavailable`,`error`);let t=e instanceof Error?e.message:String(e);throw this.#ct(t+`
766
+ `,`cp-err`),this.#s.hidden=!1,e}finally{this.#o.hidden=!0}return this.#ie(),this.#C||(this.#C=!0,this.#le||this.#ot(`${e.label} ready`,`ok`),this.#mt(`py-ready`,{language:e.id,label:e.label})),e})(),this.#p}async#ie(){if(!this.#u)return;let e=this.#_,t=await te(e,this.language);if(t){this.#_===e&&this.#u?.setLanguage(t);return}let n=e.includes(`.`)?null:await(this.#f??await M(this.language).catch(()=>null))?.editorLanguage().catch(()=>null);this.#_===e&&this.#u?.setLanguage(n??[])}#ae(){if(this.getAttribute(`height`)!==`auto`||this.#Z)return;let e=this.#e.querySelector(`.cp-root`),t=this.#t.getBoundingClientRect().height;e&&t&&!e.classList.contains(`cp-editor-sized`)&&(e.style.setProperty(`--cp-editor-height`,`${t}px`),e.classList.add(`cp-editor-sized`),this.#g=!0)}#oe(){if(!this.#g)return;this.#g=!1;let e=this.#e.querySelector(`.cp-root`);e?.style.removeProperty(`--cp-editor-height`),e?.classList.remove(`cp-editor-sized`)}#se(){this.#u?.openFile(this.#_,this.#m[this.#_]??``),this.#u?.forgetFiles([]),this.#ce()}#ce(){this.#u?this.#u.setCode(this.#m[this.#_]??``):this.#d?.then(()=>{this.#u?.setCode(this.#m[this.#_]??``),this.#he()})}#le=!1;#ue(e,t){let n=Object.keys(t),r=`This widget's entry is "${e}", but it has no file of that name${n.length?` (its files: ${n.join(`, `)})`:``}. Set entry to one of its files.\n`;this.#st(),this.#s.hidden=!1,this.#ct(r,`cp-err`),this.#le=!0,this.#ot(`Error · entry not found`,`error`);let i={stdout:``,stderr:r,durationMs:0,failed:!0};return this.#mt(`py-error`,{message:r,language:this.language}),this.#mt(`py-output`,{...i,language:this.language}),i}#de(){return this.getAttribute(`entry`)||fe(this.language)}#fe(){let e=Object.keys(this.#m),t=this.getAttribute(`entry`);if(t&&e.includes(t))return t;if(this.#Y&&e.includes(this.#Y))return this.#Y;let n=this.#Ze()&&e.includes(`index.html`)?`index.html`:fe(this.language);if(e.includes(n))return n;if(this.language===`next`){let t=e.filter(e=>/^(src\/)?app\/(\([^/]+\)\/)*page\.(jsx?|tsx?)$/.test(e)).sort((e,t)=>e.split(`/`).length-t.split(`/`).length)[0];if(t)return t}return e[0]??n}#pe(){let e=this.getAttribute(`open-file`);return e&&e in this.#m?e:this.#fe()}#me(){if(this.#X)return this.#X.widget.#me();let e={...this.#m};if(this.#u)for(let t of Object.keys(e))e[t]=this.#u.fileCode(t,e[t]);return e}#he(){let e=Object.keys(this.#m),t=this.#ve();this.#y.hidden=e.length<2&&!t,this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-file-actions`,t),this.#ge();let n=t?this.#je():null,r=!this.#y.hidden&&this.getAttribute(`file-view`)===`tree`;if(this.#y.classList.toggle(`cp-tree`,r),this.#e.querySelector(`.cp-root`)?.classList.toggle(`cp-has-tree`,r),this.#y.hidden){this.#y.replaceChildren();return}if(r){this.#_e(e),this.#$e(),t&&this.#Me(n);return}let i=this.#fe();if(this.#y.replaceChildren(...e.map(e=>{if(this.#G?.from===e)return this.#Ae();let n=document.createElement(`button`);n.dataset.file=e;let r=e.lastIndexOf(`/`)+1;if(r){let t=document.createElement(`span`);t.className=`cp-tab-folder`,t.textContent=e.slice(0,r),n.setAttribute(`aria-label`,e),n.append(t)}return n.append(e.slice(r)),n.setAttribute(`aria-pressed`,String(e===this.#_)),e===i&&(n.classList.add(`cp-entry`),n.title=`entry point — this is the file Run executes`),t?this.#ke(n,e):n})),t){if(this.#G&&this.#G.kind!==`rename`)this.#y.append(this.#Ae());else{let e=this.#Oe(`new-file`,`New file`,`+`);e.classList.add(`cp-file-new`),this.#y.append(e)}}this.#$e(),t&&this.#Me(n)}#ge(){let e=this.#e.querySelector(`[data-action="file-view"]`);if(!e)return;e.hidden=!this.hasAttribute(`file-view-switch`)||this.#y.hidden;let t=this.getAttribute(`file-view`)===`tree`,n=t?`Show files as tabs`:`Show files as a tree`;e.setAttribute(`aria-label`,n),e.title=n,e.innerHTML=t?ie:re}#_e(e){let t=this.#fe(),n=this.#ve(),r=[],i=this.#G,a=i?.folder?[...e,`${i.folder}/`]:e;if(n){let e=document.createElement(`div`);e.className=`cp-tree-head`;let t=document.createElement(`button`);t.type=`button`,t.className=`cp-tree-root`,t.dataset.targetRoot=``,t.textContent=`Files`,t.title=`Add new files and folders at the top level`,this.#W===``&&t.setAttribute(`aria-current`,`true`);let n=this.#Fe(),i=n?`in ${n}`:`at the top level`,a=this.#Oe(`new-file`,`New file`,ae);a.title=`New file ${i}`;let o=this.#Oe(`new-folder`,`New folder`,oe);o.title=`New folder ${i}`,e.append(t,a,o),r.push(e)}let o=(e,s)=>{let c=a.filter(t=>t.startsWith(e)).map(t=>t.slice(e.length));i&&i.kind!==`rename`&&`${i.folder}/`===(e||`/`)&&r.push(this.#Ae(s));let l=[...new Set(c.filter(e=>e.includes(`/`)).map(e=>e.slice(0,e.indexOf(`/`))))].sort();for(let t of l){let i=e+t,a=!this.#U.has(i),c=document.createElement(`button`);if(c.className=`cp-tree-folder`,c.dataset.folder=i,c.textContent=t,c.setAttribute(`aria-expanded`,String(a)),n&&this.#W===i&&c.setAttribute(`aria-current`,`true`),c.style.setProperty(`--cp-depth`,String(s)),n){let e=this.#Oe(`new-file`,`New file in ${i}`,`+`);e.dataset.in=i;let t=document.createElement(`div`);t.className=`cp-file-row`,t.append(c,e),r.push(t)}else r.push(c);a&&o(`${i}/`,s+1)}for(let a of c.filter(e=>e&&!e.includes(`/`)).sort()){let o=e+a;if(i?.from===o){r.push(this.#Ae(s));continue}let c=document.createElement(`button`);c.dataset.file=o,c.textContent=a,c.setAttribute(`aria-label`,o),c.setAttribute(`aria-pressed`,String(o===this.#_)),c.style.setProperty(`--cp-depth`,String(s)),o===t&&(c.classList.add(`cp-entry`),c.title=`entry point — this is the file Run executes`),r.push(n?this.#ke(c,o):c)}};o(``,0),this.#y.replaceChildren(...r)}#ve(){return this.hasAttribute(`file-actions`)&&!this.hasAttribute(`readonly`)}#ye(){if(!this.#I)throw Error(`Add the widget to the page before changing its files.`)}#be(e,t){let n=ce(e);if(n)return n;let r=Object.keys(this.#m).filter(e=>e!==t);if(r.includes(e))return`A file named "${e}" already exists.`;if(r.some(t=>t.startsWith(`${e}/`)))return`"${e}" is a folder.`;let i=r.find(t=>e.startsWith(`${t}/`));return i?`"${i}" is a file, so it can't hold other files.`:null}#xe(e){return e===this.#fe()?`it's the entry file`:this.#Se().has(e)?`this ${this.language} project needs it`:null}#Se(){let e=/* @__PURE__ */ new Set,t=Object.keys(this.#m);if(this.language===`next`)for(let n of t)/^(src\/)?app\/layout\.(jsx?|tsx?)$/.test(n)&&e.add(n);if(this.language!==`react`)return e;for(let n of[`src/main.jsx`,`src/main.js`])t.includes(n)&&e.add(n);let n=this.#me()[`index.html`];if(n===void 0)return e;e.add(`index.html`);let r=new DOMParser().parseFromString(n,`text/html`);for(let n of r.querySelectorAll(`script[src], link[rel="stylesheet"][href]`)){let r=(n.getAttribute(`src`)??n.getAttribute(`href`)).replace(/^\.?\//,``);t.includes(r)&&e.add(r)}return e}#Ce(e){let t=this.#fe();e(),this.#fe()!==t&&Object.hasOwn(this.#m,t)&&(this.#Y=t)}#we(e){for(let t=e.indexOf(`/`);t!==-1;t=e.indexOf(`/`,t+1))this.#U.delete(e.slice(0,t))}#Te(e){let t=[...this.#y.querySelectorAll(`button[data-file]`)].map(e=>e.dataset.file),n=t.indexOf(e);return(n===-1?void 0:t[n+1]??t[n-1])??Object.keys(this.#m).find(t=>t!==e)}#Ee(e,t,n){this.#tt(0),this.#ht(`playpad-files-change`,{action:e,name:t,...n?{previousName:n}:{},files:this.#me()})}async#De(e){let t=await J(e).catch(()=>null);if(!t)return null;try{return JSON.parse(t)}catch{return null}}#Oe(e,t,n){let r=document.createElement(`button`);return r.type=`button`,r.className=`cp-file-tool`,r.dataset.fileAction=e,r.setAttribute(`aria-label`,t),r.title=t,r.innerHTML=n,r}#ke(e,t){let n=document.createElement(`div`);if(n.className=`cp-file-row`,n.append(e),this.#xe(t))return n;let r=document.createElement(`button`);return r.type=`button`,r.className=`cp-file-tool cp-file-more`,r.dataset.more=t,r.textContent=`⋯`,r.setAttribute(`aria-label`,`Actions for ${t}`),r.setAttribute(`aria-expanded`,`false`),r.title=`Rename or remove`,n.append(r),n}#Ae(e=0){let t=this.#G,n=document.createElement(`form`);n.className=`cp-file-field`,n.style.setProperty(`--cp-depth`,String(e));let r=document.createElement(`input`);r.type=`text`,r.value=t.value,r.autocapitalize=`off`,r.autocomplete=`off`,r.spellcheck=!1,r.placeholder=t.kind===`folder`?`components`:`TaskLine.jsx`;let i=t.folder?` in ${t.folder}`:``;r.setAttribute(`aria-label`,t.kind===`rename`?`New name for ${t.from}`:t.kind===`folder`?`Name of the new folder${i}`:`Name of the new file${i}`),r.addEventListener(`input`,()=>{t.value=r.value,this.#Ve(``)}),r.addEventListener(`keydown`,e=>{e.key===`Escape`&&(e.preventDefault(),this.#ze())});let a=document.createElement(`button`);return a.type=`button`,a.className=`cp-file-tool`,a.dataset.fileAction=`cancel`,a.textContent=`×`,a.setAttribute(`aria-label`,`Cancel`),n.addEventListener(`submit`,e=>{e.preventDefault(),this.#Be()}),n.append(r,a),n}#je(){let e=this.#e.activeElement;if(!e||!this.#y.contains(e))return null;if(e.closest(`.cp-file-field`))return{field:!0};let{file:t,folder:n,more:r}=e.dataset;return{file:t,folder:n,more:r}}#Me(e){let t=this.#y.querySelector(`.cp-file-field input`);if(t&&this.#G?.fresh){this.#G.fresh=!1,t.focus();let e=this.#G.kind===`rename`?t.value.lastIndexOf(`.`):-1;e>0?t.setSelectionRange(t.value.lastIndexOf(`/`)+1,e):t.setSelectionRange(t.value.length,t.value.length)}else e?.field?t?.focus():e&&this.#Ne(e)?.focus();let n=this.#y.querySelector(`button[aria-pressed="true"]`);if(n&&!t){let e=this.#y.getBoundingClientRect(),t=n.getBoundingClientRect();t.left<e.left?this.#y.scrollLeft-=e.left-t.left:t.right>e.right-32&&(this.#y.scrollLeft+=t.right-e.right+32),t.top<e.top?this.#y.scrollTop-=e.top-t.top:t.bottom>e.bottom&&(this.#y.scrollTop+=t.bottom-e.bottom)}}#Ne(e){return[...this.#y.querySelectorAll(`button`)].find(({dataset:t})=>e.file!==void 0&&t.file===e.file||e.folder!==void 0&&t.folder===e.folder||e.more!==void 0&&t.more===e.more)}#Pe(e){let t=e.dataset.fileAction;if(t===`cancel`)return this.#ze();let n=this.getAttribute(`file-view`)===`tree`,r=e.dataset.in??this.#Fe();this.#we(`${r}/`),this.#Ie(t===`new-folder`?{kind:`folder`,folder:r,value:``,fresh:!0}:n?{kind:`file`,folder:r,value:``,fresh:!0}:{kind:`file`,folder:``,value:r&&`${r}/`,fresh:!0})}#Fe(){let e=this.#W;return e===``||e&&Object.keys(this.#m).some(t=>t.startsWith(`${e}/`))?e:this.#_.includes(`/`)?this.#_.slice(0,this.#_.lastIndexOf(`/`)):``}#Ie(e){this.#Ge(!1),this.#Ve(``),this.#G=e,this.#he()}#Le(e){let t=this.getAttribute(`file-view`)===`tree`?e.lastIndexOf(`/`):-1;this.#Ie({kind:`rename`,from:e,folder:t===-1?``:e.slice(0,t),value:e.slice(t+1),fresh:!0})}#Re(){this.#G=null,this.#W=null,this.#K&&(this.#K.hidden=!0,this.#Ve(``))}#ze(){let e=this.#G?.from;this.#G=null,this.#Ve(``),this.#he(),(e&&this.#Ne({more:e})||this.#Ne({file:this.#_}))?.focus()}#Be(){let e=this.#G;if(!e)return;let t=e.value.trim(),n=this.getAttribute(`file-view`)===`tree`;if(e.kind===`folder`||e.kind===`file`&&t.endsWith(`/`)){if(!n)return this.#Ve(`Add a file name after the folder.`,!0);if(!t)return this.#Ve(`A folder needs a name.`,!0);let r=se(e.folder,t.replace(/\/$/,``)),i=Object.keys(this.#m).some(e=>e.startsWith(`${r}/`))?null:this.#be(r);return i?this.#Ve(i,!0):(this.#we(`${r}/`),this.#Ie({kind:`file`,folder:r,value:``,fresh:!0}))}if(!t)return this.#Ve(`A file needs a name.`,!0);let r=se(e.folder,t);if(e.kind===`rename`&&r===e.from)return this.#ze();if(Object.hasOwn(this.#m,r))return this.#G=null,this.openFile(r),this.#u?.focus(),this.#Ve(`"${r}" already exists, so it's open now.`,!1,4e3);let i=this.#be(r,e.from);if(i)return this.#Ve(i,!0);if(this.#G=null,this.#Ve(``),e.kind===`rename`){let t=this.#_===e.from;this.renameFile(e.from,r),t?this.#u?.focus():this.#Ne({file:r})?.focus()}else this.addFile(r),this.#u?.focus()}#Ve(e,t=!1,n=0){this.#J&&clearTimeout(this.#J),this.#J=n?setTimeout(()=>this.#Ve(``),n):null,this.#q.textContent=e,this.#q.hidden=!e,this.#q.classList.toggle(`cp-file-refused`,t),this.#y.querySelector(`.cp-file-field input`)?.setAttribute(`aria-invalid`,String(!!e&&t)),e&&this.#He(this.#q,t&&this.#y.querySelector(`.cp-file-field`)||this.#y)}#He(e,t){e.hidden=!1;let n=e.parentElement.getBoundingClientRect(),r=t.getBoundingClientRect();e.style.top=`${Math.max(0,Math.min(r.bottom-n.top+2,n.height-e.offsetHeight))}px`,e.style.left=`${Math.max(0,Math.min(r.left-n.left,n.width-e.offsetWidth))}px`}#Ue=null;#We(e,t){this.#Ge(!1),this.#Ue=e,this.#K.replaceChildren(...t),this.#He(this.#K,e),this.#K.querySelector(`button`)?.focus()}#Ge(e){this.#K&&!this.#K.hidden&&(this.#K.hidden=!0,this.#K.replaceChildren(),this.#K.removeAttribute(`role`),this.#K.removeAttribute(`aria-label`),this.#Ue?.setAttribute(`aria-expanded`,`false`),e&&this.#Ue?.focus(),this.#Ue=null)}#Ke(e,t,n=``){let r=document.createElement(`button`);return r.type=`button`,r.textContent=e,r.className=n,r.addEventListener(`click`,t),r}#qe(e,t){let n=()=>{this.#me()[t]?.trim()?this.#Je(e,`Remove ${t}? Its code will be lost.`,`Remove`,()=>this.#Ye(t)):this.#Ye(t)},r=this.#Ke(`Rename`,()=>{this.#Ge(!1),this.#Le(t)});this.#We(e,[r,this.#Ke(`Remove`,n)]),e.setAttribute(`aria-expanded`,`true`)}#Je(e,t,n,r){let i=document.createElement(`p`);i.textContent=t;let a=document.createElement(`div`);a.className=`cp-file-pop-buttons`,a.append(this.#Ke(`Cancel`,()=>this.#Ge(!0)),this.#Ke(n,()=>{this.#Ge(!1),r()},`cp-danger`)),this.#We(e,[i,a]),this.#K.setAttribute(`role`,`alertdialog`),this.#K.setAttribute(`aria-label`,t)}#Ye(e){this.#Ge(!1);let t=this.#Te(e);this.removeFile(e),this.#Ne({file:t})?.focus()}#Xe(){let e=Object.keys(this.#m),t=Object.keys(this.#h),n=e.length===t.length&&e.every(e=>Object.hasOwn(this.#h,e));if(!this.#ve()||n)return this.reset();this.#Je(this.#i,`Reset the project? Files you added go away, and files you removed come back.`,`Reset`,()=>{this.reset(),this.#i.focus()})}#Ze(){return this.language===`react`||this.language===`next`}#Qe(){this.#R&&(this.#f?.dispose?.(this.#R),this.#R.replaceChildren())}#$e(){if(!this.#z)return;let e=this.getAttribute(`change-marks`)!==`off`,t=this.#me(),n=this.#B,r=n??this.#h;for(let n of this.#y.querySelectorAll(`button[data-file]`)){let i=n.dataset.file;n.classList.toggle(`cp-unrun`,e&&t[i]!==r[i]),n.classList.toggle(`cp-edited`,e&&t[i]!==this.#h[i])}let i=Object.keys(t),a=i.length!==Object.keys(r).length||i.some(e=>t[e]!==r[e])||n!==null&&this.#l.value!==this.#V,o=e&&a;this.#n.classList.toggle(`cp-unrun`,o),o?this.#n.title=`Run to see your changes (${/Mac|iPhone|iPad/.test(navigator.platform)?`⌘`:`Ctrl`}+Enter)`:this.#n.removeAttribute(`title`);let s=o&&n!==null?`Code changed since this run`:``;this.#z.textContent!==s&&(this.#z.hidden=!s,this.#z.textContent=s)}#et(e){this.#m[this.#_]=e,this.#$e(),this.#tt()}#tt(e=400){let t=this.getAttribute(`persist`);if(!t)return;this.#k&&clearTimeout(this.#k);let n=JSON.stringify(this.#me()),r=this.#ve()?JSON.stringify(this.#h):null,i=()=>{r&&q(t,r).catch(()=>{}),U(t,n).catch(()=>{})};e?this.#k=setTimeout(i,e):i()}#nt(){let e=this.getAttribute(`theme`)??`auto`;if(e===`dark`)return!0;if(e===`light`)return!1;let t=v().mode;if(t)return t===`dark`;let n=typeof document>`u`?``:getComputedStyle(document.documentElement).colorScheme,r=n.includes(`dark`);return r===n.includes(`light`)?!!this.#T?.matches:r}#rt(){return v()[this.#nt()?`dark`:`light`]}#it(){this.#O??=b(this.#D),!this.#T&&typeof matchMedia==`function`&&(this.#T=matchMedia(`(prefers-color-scheme: dark)`),this.#T.addEventListener(`change`,this.#D)),!this.#E&&typeof MutationObserver==`function`&&typeof document<`u`&&(this.#E=new MutationObserver(this.#D),this.#E.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`,`style`,`data-theme`,`data-color-scheme`,`color-scheme`]}));let e=this.#nt(),t=this.#rt();this.setAttribute(`data-resolved-theme`,e?`dark`:`light`),this.setAttribute(`data-editor-theme`,t),this.#u?.setTheme(e,t);let n=this.getAttribute(`theme`),r=n===`light`||n===`dark`||this.getAttribute(`theme-controls`)===`off`,i=this.#e.querySelector(`[data-action="theme"]`),a=this.#e.querySelector(`.cp-theme-picker`);if(i&&a){let n=e?`Switch to the light theme`:`Switch to the dark theme`;i.hidden=a.hidden=r,i.title=n,i.setAttribute(`aria-label`,n),a.querySelector(`select`).value=t}}#at(){for(let[e,t]of[[`height`,`--cp-height`],[`min-height`,`--cp-min-height`],[`max-height`,`--cp-max-height`],[`preview-height`,`--cp-preview-height`]]){let n=this.getAttribute(e);n===null||n===``?this.style.removeProperty(t):this.style.setProperty(t,/^\d+$/.test(n)?`${n}px`:n)}let e=this.getAttribute(`tree-width`)?.trim();e?/^(\d+(px)?|\d+(\.\d+)?%)$/.test(e)?this.style.setProperty(`--cp-tree-width`,/\d$/.test(e)?`${e}px`:e):(this.style.removeProperty(`--cp-tree-width`),console.warn(`code-playpad: tree-width="${e}" is not a size. Use a percentage like "20%" or pixels like "240".`)):this.style.removeProperty(`--cp-tree-width`)}#ot(e,t){this.#a.textContent=e,this.#a.dataset.state=t}#st(){this.#P&&clearTimeout(this.#P),this.#P=null,this.#j=[],this.#F=0,this.#s.replaceChildren(),this.#A=!0}#ct(e,t){if(!e)return;let n=t===`cp-err`&&!this.#A?`\n${e}`:e;this.#A=n.endsWith(`
767
+ `),this.#j.push({text:n,className:t}),this.#P??=setTimeout(()=>this.#lt(),16)}#lt(){if(this.#P&&clearTimeout(this.#P),this.#P=null,!this.#j.length)return;let e=this.#j;this.#j=[];let t=document.createDocumentFragment(),n=``,r,i=()=>{if(!n)return;let e=document.createElement(`span`);r&&(e.className=r),e.textContent=n,t.appendChild(e),n=``};for(let t of e){if(this.#F>=Q)break;let e=t.text;this.#F+e.length>Q&&(e=e.slice(0,Q-this.#F)+`
622
768
  … output truncated for display — the full text is in the playpad-output event
623
- `),this.#F+=t.text.length,r!==t.className&&(i(),r=t.className),n+=e}i(),this.#s.hidden=!1;let a=this.#s.querySelector(`.cp-prompt`);a?this.#s.insertBefore(t,a):this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight}#Se(){return this.#xe(),this.#Ce(null),new Promise(e=>{let t=document.createElement(`form`);t.className=`cp-prompt`;let n=document.createElement(`input`);n.type=`text`,n.setAttribute(`aria-label`,`Program input — press Enter to send`),n.autocapitalize=`off`,n.autocomplete=`off`,n.spellcheck=!1;let r=document.createElement(`button`);r.type=`submit`,r.className=`cp-send`,r.textContent=`⏎`,r.title=`Send this line (Enter)`;let i=document.createElement(`button`);i.type=`button`,i.className=`cp-eof`,i.textContent=`EOF`,i.title=`End of input (Ctrl-D) — makes input() raise EOFError`;let a=n=>{this.#M===e&&(this.#M=null,this.#N=null,t.remove(),n===null?this.#be(`
624
- `,`cp-in`):this.#be(n+`
625
- `,`cp-in`),this.#xe(),e(n))};t.addEventListener(`submit`,e=>{e.preventDefault(),a(n.value)}),i.addEventListener(`click`,()=>a(null)),n.addEventListener(`keydown`,e=>{(e.key===`Escape`||e.key===`d`&&e.ctrlKey)&&(e.preventDefault(),a(null))}),t.append(n,r,i),this.#s.hidden=!1,this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight,this.#M=e,this.#N=a,n.focus({preventScroll:!0})})}#Ce(e){this.#N?.(e),this.#N=null,this.#M=null}#we(e,t){this.#xe();let n=document.createElement(`div`);n.className=`cp-hint`,n.textContent=e,this.#s.hidden=!1,this.#s.appendChild(n),this.#s.scrollTop=this.#s.scrollHeight,t&&(this.#c.hidden=!1,this.#c.classList.add(`cp-attention`))}#Te(e){this.#xe();let t=document.createElement(`table`);t.className=`cp-table`;let n=t.createTHead().insertRow();for(let t of e.columns){let e=document.createElement(`th`);e.textContent=t,n.appendChild(e)}let r=t.createTBody();for(let t of e.rows){let e=r.insertRow();for(let n of t)e.insertCell().textContent=n==null?``:String(n)}this.#s.hidden=!1,this.#s.appendChild(t)}#Ee(e,t){this.#De(e,t),this.#De(`playpad-${e.slice(3)}`,t)}#De(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0})),this.#W?.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};function le(e=X){typeof window<`u`&&typeof customElements<`u`&&(customElements.get(e)||customElements.define(e,ce))}le();export{ce as CodePlayPadElement,d as EDITOR_THEMES,u as PYODIDE_VERSION,r as REACT_VERSION,t as RunStopped,e as WorkerUnavailable,Y as allProgress,K as clearSnippet,s as configureCSharp,l as configureCpp,o as configurePython,i as configureReact,c as configureTypeScript,S as createEditor,le as defineCodePlayPad,J as getProgress,N as getRuntime,v as getThemePreference,M as listRuntimes,G as loadSnippet,b as onThemePreferenceChange,a as pyodideAssetUrls,j as registerRuntime,W as saveSnippet,q as setProgress,y as setThemePreference};
769
+ `),this.#F+=t.text.length,r!==t.className&&(i(),r=t.className),n+=e}i(),this.#s.hidden=!1;let a=this.#s.querySelector(`.cp-prompt`);a?this.#s.insertBefore(t,a):this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight}#ut(){return this.#lt(),this.#dt(null),new Promise(e=>{let t=document.createElement(`form`);t.className=`cp-prompt`;let n=document.createElement(`input`);n.type=`text`,n.setAttribute(`aria-label`,`Program input — press Enter to send`),n.autocapitalize=`off`,n.autocomplete=`off`,n.spellcheck=!1;let r=document.createElement(`button`);r.type=`submit`,r.className=`cp-send`,r.textContent=`⏎`,r.title=`Send this line (Enter)`;let i=document.createElement(`button`);i.type=`button`,i.className=`cp-eof`,i.textContent=`EOF`,i.title=`End of input (Ctrl-D) — makes input() raise EOFError`;let a=n=>{this.#M===e&&(this.#M=null,this.#N=null,t.remove(),n===null?this.#ct(`
770
+ `,`cp-in`):this.#ct(n+`
771
+ `,`cp-in`),this.#lt(),e(n))};t.addEventListener(`submit`,e=>{e.preventDefault(),a(n.value)}),i.addEventListener(`click`,()=>a(null)),n.addEventListener(`keydown`,e=>{(e.key===`Escape`||e.key===`d`&&e.ctrlKey)&&(e.preventDefault(),a(null))}),t.append(n,r,i),this.#s.hidden=!1,this.#s.appendChild(t),this.#s.scrollTop=this.#s.scrollHeight,this.#M=e,this.#N=a,n.focus({preventScroll:!0})})}#dt(e){this.#N?.(e),this.#N=null,this.#M=null}#ft(e,t){this.#lt();let n=document.createElement(`div`);n.className=`cp-hint`,n.textContent=e,this.#s.hidden=!1,this.#s.appendChild(n),this.#s.scrollTop=this.#s.scrollHeight,t&&(this.#c.hidden=!1,this.#c.classList.add(`cp-attention`))}#pt(e){this.#lt();let t=document.createElement(`table`);t.className=`cp-table`;let n=t.createTHead().insertRow();for(let t of e.columns){let e=document.createElement(`th`);e.textContent=t,n.appendChild(e)}let r=t.createTBody();for(let t of e.rows){let e=r.insertRow();for(let n of t)e.insertCell().textContent=n==null?``:String(n)}this.#s.hidden=!1,this.#s.appendChild(t)}#mt(e,t){this.#ht(e,t),this.#ht(`playpad-${e.slice(3)}`,t)}#ht(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0})),this.#Z?.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};function ye(e=ne){typeof window<`u`&&typeof customElements<`u`&&(customElements.get(e)||customElements.define(e,ve))}ye();export{ve as CodePlayPadElement,d as EDITOR_THEMES,u as PYODIDE_VERSION,r as REACT_VERSION,t as RunStopped,e as WorkerUnavailable,Z as allProgress,G as clearSnippet,s as configureCSharp,l as configureCpp,o as configurePython,i as configureReact,c as configureTypeScript,S as createEditor,ye as defineCodePlayPad,X as getProgress,M as getRuntime,v as getThemePreference,j as listRuntimes,W as loadSnippet,b as onThemePreferenceChange,a as pyodideAssetUrls,A as registerRuntime,U as saveSnippet,Y as setProgress,y as setThemePreference};
@@ -1,4 +1,4 @@
1
- import{d as e,l as t,u as n}from"./element-DnazizZC.js";var r=1,i=class{#e=null;#t=null;#n=`module`;#r=null;#i=null;#a=!1;#o=!1;#s=``;#c=/* @__PURE__ */ new Set;#l=[];#u=null;#d=!1;get recycleAfterRun(){return!1}get startTimeoutMs(){}initPayload(){return{}}loadModule(e){return Promise.reject(/* @__PURE__ */ Error(`no module named ${e}`))}get ready(){return this.#a}get interactiveStdin(){return this.#o}get version(){return this.#s}load(t){t&&this.#c.add(t);let n=()=>{t&&this.#c.delete(t)};if(!this.#r){let t=new Promise((t,n)=>{this.#i={resolve:t,reject:n};let r;try{if(typeof Worker>`u`)throw Error(`Worker constructor missing`);let e=new Blob([this.source],{type:`text/javascript`});this.#t=URL.createObjectURL(e),r=new Worker(this.#t,{type:this.#n})}catch(t){this.#i=null,n(new e(`Could not start a Web Worker: ${t.message}`));return}this.#e=r;let i=this.startTimeoutMs,a=i===void 0?void 0:setTimeout(()=>{this.#e!==r||this.#a||(this.#m(),n(/* @__PURE__ */ Error(`The ${this.label} worker did not start within ${i} ms.`)))},i);r.onmessage=e=>{if(this.#e!==r)return;let i=e.data;i.type===`ready`?(this.#s=i.version,this.#o=i.interactiveStdin===!0,this.#a=!0,this.#i=null,clearTimeout(a),this.#h({phase:`ready`,message:`${this.label} ready`}),t()):i.type===`fatal`&&!this.#a?(clearTimeout(a),this.#p(i.message,t,n)):this.#g(i)},r.onerror=e=>{if(this.#e!==r)return;let i=e.message||`Worker failed to start`;clearTimeout(a),this.#a?this.#u&&this.#y(this.#u,Error(i)):this.#p(i,t,n)},r.postMessage({type:`init`,...this.initPayload()})});this.#r=t,t.catch(()=>{this.#r===t&&(this.#r=null)})}return this.#r.then(n,e=>{throw n(),e})}run(e,t={}){let n,i,a=new Promise((e,t)=>{n=e,i=t}),o,s=new Promise(e=>{o=e}),c={id:r++,code:e,options:t,stdout:``,stderr:``,resolve:n,reject:i,promise:a,started:!1,settled:!1,done:s,markDone:()=>{clearTimeout(c.timer),c.settled=!0,o()}};return this.#l.push(c),this.#b(),a}stop(e){if(e){let t=this.#l.findIndex(t=>t.promise===e);if(t!==-1){this.#y(this.#l.splice(t,1)[0],new n);return}let r=this.#u;if(!r||r.promise!==e||r.settled)return;if(!r.started){this.#y(r,new n),this.recycleAfterRun&&this.#f();return}}this.#f()}#f(){let e=this.#e!==null,t=this.#i;if(this.#m(),this.#u&&this.#y(this.#u,new n),e&&(t||!this.recycleAfterRun)){let e=this.load();t&&e.then(t.resolve,t.reject),e.catch(()=>{})}}#p(e,t,n){this.#m(),this.#n===`module`?(this.#n=`classic`,this.load().then(t,n)):n(Error(e))}#m(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=null,this.#a=!1}#h(e){for(let t of this.#c)t(e)}#g(e){if(e.type===`progress`){this.#h({phase:e.phase,message:e.message}),this.#u&&e.id===this.#u.id&&!this.#u.settled&&this.#u.options.onProgress?.({phase:e.phase,message:e.message});return}let n=this.#u;if(n&&`id`in e&&e.id===n.id)switch(e.type){case`stdout`:n.stdout+=e.text,n.options.onStdout?.(e.text);break;case`echo`:n.options.onEcho?.(e.text);break;case`stdin-request`:this.#v(n,e.request);break;case`module-request`:this.#_(n,e.name);break;case`stderr`:n.stderr+=e.text,n.options.onStderr?.(e.text);break;case`result`:n.resolve({stdout:n.stdout,stderr:n.stderr||void 0,value:e.value,durationMs:Math.round(e.durationMs),failed:!1,...e.memory?{memory:e.memory}:{},...e.cases?{cases:e.cases,passed:e.passed,total:e.total}:{}}),n.markDone();break;case`error`:case`fatal`:{let r=(n.stderr&&!n.stderr.endsWith(`
1
+ import{d as e,l as t,u as n}from"./element-Ce06T38j.js";var r=1,i=class{#e=null;#t=null;#n=`module`;#r=null;#i=null;#a=!1;#o=!1;#s=``;#c=/* @__PURE__ */ new Set;#l=[];#u=null;#d=!1;get recycleAfterRun(){return!1}get startTimeoutMs(){}initPayload(){return{}}loadModule(e){return Promise.reject(/* @__PURE__ */ Error(`no module named ${e}`))}get ready(){return this.#a}get interactiveStdin(){return this.#o}get version(){return this.#s}load(t){t&&this.#c.add(t);let n=()=>{t&&this.#c.delete(t)};if(!this.#r){let t=new Promise((t,n)=>{this.#i={resolve:t,reject:n};let r;try{if(typeof Worker>`u`)throw Error(`Worker constructor missing`);let e=new Blob([this.source],{type:`text/javascript`});this.#t=URL.createObjectURL(e),r=new Worker(this.#t,{type:this.#n})}catch(t){this.#i=null,n(new e(`Could not start a Web Worker: ${t.message}`));return}this.#e=r;let i=this.startTimeoutMs,a=i===void 0?void 0:setTimeout(()=>{this.#e!==r||this.#a||(this.#m(),n(/* @__PURE__ */ Error(`The ${this.label} worker did not start within ${i} ms.`)))},i);r.onmessage=e=>{if(this.#e!==r)return;let i=e.data;i.type===`ready`?(this.#s=i.version,this.#o=i.interactiveStdin===!0,this.#a=!0,this.#i=null,clearTimeout(a),this.#h({phase:`ready`,message:`${this.label} ready`}),t()):i.type===`fatal`&&!this.#a?(clearTimeout(a),this.#p(i.message,t,n)):this.#g(i)},r.onerror=e=>{if(this.#e!==r)return;let i=e.message||`Worker failed to start`;clearTimeout(a),this.#a?this.#u&&this.#y(this.#u,Error(i)):this.#p(i,t,n)},r.postMessage({type:`init`,...this.initPayload()})});this.#r=t,t.catch(()=>{this.#r===t&&(this.#r=null)})}return this.#r.then(n,e=>{throw n(),e})}run(e,t={}){let n,i,a=new Promise((e,t)=>{n=e,i=t}),o,s=new Promise(e=>{o=e}),c={id:r++,code:e,options:t,stdout:``,stderr:``,resolve:n,reject:i,promise:a,started:!1,settled:!1,done:s,markDone:()=>{clearTimeout(c.timer),c.settled=!0,o()}};return this.#l.push(c),this.#b(),a}stop(e){if(e){let t=this.#l.findIndex(t=>t.promise===e);if(t!==-1){this.#y(this.#l.splice(t,1)[0],new n);return}let r=this.#u;if(!r||r.promise!==e||r.settled)return;if(!r.started){this.#y(r,new n),this.recycleAfterRun&&this.#f();return}}this.#f()}#f(){let e=this.#e!==null,t=this.#i;if(this.#m(),this.#u&&this.#y(this.#u,new n),e&&(t||!this.recycleAfterRun)){let e=this.load();t&&e.then(t.resolve,t.reject),e.catch(()=>{})}}#p(e,t,n){this.#m(),this.#n===`module`?(this.#n=`classic`,this.load().then(t,n)):n(Error(e))}#m(){this.#e?.terminate(),this.#e=null,this.#t&&=(URL.revokeObjectURL(this.#t),null),this.#r=null,this.#i=null,this.#a=!1}#h(e){for(let t of this.#c)t(e)}#g(e){if(e.type===`progress`){this.#h({phase:e.phase,message:e.message}),this.#u&&e.id===this.#u.id&&!this.#u.settled&&this.#u.options.onProgress?.({phase:e.phase,message:e.message});return}let n=this.#u;if(n&&`id`in e&&e.id===n.id)switch(e.type){case`stdout`:n.stdout+=e.text,n.options.onStdout?.(e.text);break;case`echo`:n.options.onEcho?.(e.text);break;case`stdin-request`:this.#v(n,e.request);break;case`module-request`:this.#_(n,e.name);break;case`stderr`:n.stderr+=e.text,n.options.onStderr?.(e.text);break;case`result`:n.resolve({stdout:n.stdout,stderr:n.stderr||void 0,value:e.value,durationMs:Math.round(e.durationMs),failed:!1,...e.memory?{memory:e.memory}:{},...e.cases?{cases:e.cases,passed:e.passed,total:e.total}:{}}),n.markDone();break;case`error`:case`fatal`:{let r=(n.stderr&&!n.stderr.endsWith(`
2
2
  `)?`
3
3
  `:``)+e.message+`
4
4
  `;n.stderr+=r,n.options.onStderr?.(r);let i={stdout:n.stdout,stderr:n.stderr,hint:`hint`in e?e.hint:void 0,durationMs:Math.round(`durationMs`in e?e.durationMs:0),failed:!0,...`cases`in e&&e.cases?{cases:e.cases,passed:0,total:e.cases.length}:{}};`hintAbout`in e&&e.hintAbout===`stdin`&&t.add(i),n.resolve(i),n.markDone();break}}}#_(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#u===e&&n?.postMessage({type:`module`,name:t,...r})};this.loadModule(t).then(e=>r({code:e}),e=>r({error:e instanceof Error?e.message:String(e)}))}#v(e,t){let n=this.#e,r=r=>{this.#e===n&&this.#u===e&&n?.postMessage({type:`stdin-response`,request:t,text:r})},i=e.options.onStdinRequest;i?i().then(r,()=>r(null)):r(null)}#y(e,t){e.reject(t),e.markDone()}async#b(){if(!this.#d){this.#d=!0;try{for(;this.#l.length;){let e=this.#l.shift();this.#u=e;let t=null;try{if(this.recycleAfterRun?await Promise.race([this.load(),e.done]):await this.load(),e.settled)continue;e.started=!0,e.options.onStart?.(),e.options.timeoutMs&&Number.isFinite(e.options.timeoutMs)&&e.options.timeoutMs>0&&(e.timer=setTimeout(()=>{this.#u!==e||e.settled||(this.#g({type:`error`,id:e.id,message:`Run exceeded its wall-clock time limit.`,durationMs:e.options.timeoutMs}),this.#m())},e.options.timeoutMs)),t=this.#e,this.#e.postMessage({type:`run`,id:e.id,code:e.code,stdin:e.options.stdin,files:e.options.files,entry:e.options.entry,...e.options.compilerLanguage?{compilerLanguage:e.options.compilerLanguage}:{},...e.options.practice?{practice:e.options.practice}:{}}),await e.done}catch(t){this.#y(e,t)}finally{this.#u=null,this.recycleAfterRun&&t&&this.#e===t&&this.#m()}}}finally{this.#d=!1}}}};export{i as t};